中级会员
 
- 积分
- 281
- 金钱
- 281
- 注册时间
- 2018-5-28
- 在线时间
- 32 小时
|
1金钱
使用STM32F103RCT6的USART2和DMA处理串口数据。我是这么想的,发送和接收均使用MDA。
代码如下:
USART2 初始化代码
[mw_shl_code=applescript,true]void Uart2_Init(u32 BaudRate)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
DMA_InitTypeDef DMA_InitStruct;
//串口配置
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE); // 使能PB端口时钟
RCC_APB1PeriphClockCmd( RCC_APB1Periph_USART2, ENABLE); // 使能PB端口时钟
//PA.2,Tx Pin
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//PA.3,Rx Pin
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//串口参数配置
USART_InitStructure.USART_BaudRate = BaudRate;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_ITConfig(USART2, USART_IT_IDLE, ENABLE);
/* Configure USART1 */
USART_Init(USART2, &USART_InitStructure);
/* Enable the USART1 */
USART_Cmd(USART2, ENABLE);
//DMA 配置
USART_DMACmd(USART2, USART_DMAReq_Tx, ENABLE);
/* Enable USART2 DMA TX request */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
DMA_DeInit(DMA1_Channel7);
DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)(&USART2->DR);
DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)USART2_DMA_TX_Buf;
DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStruct.DMA_BufferSize = 0;
DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStruct.DMA_Mode = DMA_Mode_Normal;
DMA_InitStruct.DMA_Priority = DMA_Priority_VeryHigh;
DMA_InitStruct.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel7, &DMA_InitStruct);
DMA_ITConfig(DMA1_Channel7, DMA_IT_TC, ENABLE);
//DMA接收
DMA_ITConfig(DMA1_Channel6,DMA_IT_TC,ENABLE);
DMA_Cmd(DMA1_Channel6,DISABLE);
DMA_InitStruct.DMA_PeripheralBaseAddr = (Uint32)(&USART2->DR);
DMA_InitStruct.DMA_MemoryBaseAddr = (Uint32)&USART2_DMA_RX_Buf[0];
DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStruct.DMA_BufferSize = USART2_DMARx_LEN;
DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStruct.DMA_MemoryDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStruct.DMA_Mode = DMA_Mode_Normal;
DMA_InitStruct.DMA_Priority = DMA_Priority_VeryHigh;
DMA_InitStruct.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel6,&DMA_InitStruct);
//启动DMA接收通道
DMA_Cmd(DMA1_Channel6,ENABLE);
USART_DMACmd(USART2, USART_DMAReq_Rx,ENABLE);
// //串口中断配置
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =8;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
// Enable USART2 DMA TX Finish Interrupt
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel7_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 7;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}[/mw_shl_code]
发送数据部分代码
[mw_shl_code=applescript,true]void USART2_Data_Send(uint16_t len)
{
DMA1_Channel7->CMAR = (uint32_t)&USART2_DMA_TX_Buf[0];
DMA1_Channel7->CNDTR = len;
DMA_Cmd(DMA1_Channel7, ENABLE);
}[/mw_shl_code]
DMA发送完成中断
[mw_shl_code=applescript,true]void DMA1_Channel7_IRQHandler(void)
{
if(DMA_GetITStatus(DMA1_IT_TC7))
{
// USART2 DMA 传输完成
DMA_ClearITPendingBit(DMA1_IT_TC7);
DMA_Cmd(DMA1_Channel7, DISABLE);
// Enable USART2 Transmit complete interrupt
USART_ITConfig(USART2, USART_IT_TC, ENABLE);
}
}[/mw_shl_code]
USART2 接收完成中断
[mw_shl_code=applescript,true]void USART2_IRQHandler(void)
{
Uint8 Temp;
/****************DMA串口空闲中断后读取数据*************************/
if(USART_GetITStatus(USART2, USART_IT_IDLE) != RESET)
{
USART_ClearFlag(USART2, USART_IT_IDLE);
Temp = USART2->SR;
Temp = USART2->DR;
DMA_Cmd(DMA1_Channel6,DISABLE); //关闭DMA
Temp = 64 - DMA_GetCurrDataCounter(DMA1_Channel6); //获取数据长度
//读取数据
DMA1_Channel6->CNDTR = 64;//重装填,并让接收地址偏址从0开始
DMA_Cmd(DMA1_Channel6,ENABLE); //重新打开DMA
// WriteBufferFIFO((struct UART_Struct *)&UART3Buffer.RxInterval,UART3DMABuffer,Temp);
// UART3Buffer.RevFlag = 1;
}
}
[/mw_shl_code]
我的思路是发送和接收都是用DMA。其中接收部分使用USART的接收中断,当接收完一帧数据后触发中断,把数据读出来。
现在的问题是接收部分和发送部分的中断只使能一个的时候可以正常,可以正常发送或者正常接收。但是两个中断同时使能时就无法发送了,测试的时候用的是延时发送,每0.5s发送一次
经过仿真发现使能串口接收中断后重新一直在中断里面执行,根本执行不到发送部分的函数,因为不能正常发送。关于串口的中断我也用过很多次了,感觉中断配置上没有啥问题,可是问题应该就是在中断配置上,希望大神给看一下哪儿出了问题。
|
最佳答案
查看完整内容[请看2#楼]
1,dma发送,参考我们标准例程。
2, DMA接收,参考:http://www.openedv.com/forum.php?mod=viewthread&tid=63849&highlight=DMA%2B%B4%AE%BF%DA%2B%BD%D3%CA%D5
论坛好多帖子,学会自己搜索。
|