新手上路
- 积分
- 38
- 金钱
- 38
- 注册时间
- 2019-6-10
- 在线时间
- 9 小时
|
14金钱
最近由于手里面没有片子,使用MDK的仿真调试,调试DMA节合串口中断时发现一个有意思的问题:1.可以接收到数据,有时候完整有时候不完整(使用XCOM V2.0调试助手);
2.接受完一帧数据后,在空闲时间内不能产生中断(使用XCOM V2.0调试助手);
3.在数据帧结尾加0X00 或者0XFF,可以产生空闲中断(使用XCOM V2.0调试助手);
4.使用Modbus poll调试软件发送数据帧,数据没有接收完整就会进入空闲中断;
软件仿真调试环境:
MDK5.28 + VSPD + XCOM V2.0 + MODBUS POLL
期待各位前辈指点一二,感谢!!!第一次发帖不知道这个金钱代表什么,我将我所有的金钱悬赏了。
下面是代码:
- void My_UART_Init(void)
- {
- GPIO_InitTypeDef GPIO_InitStruct;
- USART_InitTypeDef USART_InitStruct;
- NVIC_InitTypeDef NVIC_InitStruct;
- DMA_InitTypeDef DMA_InitStruct;
-
-
-
- DMA_DeInit(DMA1_Channel5);
- DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)(&USART1->DR); //外设--->内存
- DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)RxBuffer;
- DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;
- DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
- DMA_InitStruct.DMA_BufferSize = BufferSize;
- DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralSRC;
- DMA_InitStruct.DMA_M2M = DMA_M2M_Disable;
- DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
- DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
- DMA_InitStruct.DMA_Priority = DMA_Priority_Medium;
- DMA_InitStruct.DMA_Mode = DMA_Mode_Circular;
- DMA_Init(DMA1_Channel5, &DMA_InitStruct);
-
- DMA_Cmd(DMA1_Channel5, ENABLE);
-
-
- RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); // 使能DMA
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 使能GPIOA
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); // 使能时钟 复用USART
-
- GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;
- GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOA,&GPIO_InitStruct); //初始化 USART_TX 即 GPIOA.9
-
- GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
- GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;
- GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOA,&GPIO_InitStruct); //初始化 USART_RX 即 GPIOA.10
-
- USART_InitStruct.USART_BaudRate = 9600;
- USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
- USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
- USART_InitStruct.USART_Parity = USART_Parity_No;
- USART_InitStruct.USART_StopBits = USART_StopBits_1;
- USART_InitStruct.USART_WordLength = USART_WordLength_8b;
- USART_Init(USART1,&USART_InitStruct); //初始化 USART
-
- USART_ITConfig(USART1, USART_IT_RXNE, DISABLE); // 开启 USART 接收缓冲区非空中断
- USART_ITConfig(USART1, USART_IT_TC, DISABLE); // 开启 USART 发送缓冲区空中断
-
- USART_ITConfig(USART1, USART_IT_IDLE, ENABLE); //开启 USART1 总线空闲中断
-
-
-
-
-
- NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;
- NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
- NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x01; //抢占优先级 2位 00 01 10 11
- NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x01; //响应优先级 2位 00 01 10 11
- NVIC_Init(&NVIC_InitStruct); //初始化中断
-
- USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE); // 使能 USART1接收DMA
- USART_Cmd(USART1, ENABLE);//使能USART中断
- }
-
- void USART1_IRQHandler(void) //串口1中断服务程序
- {
- uint8_t clear = clear; // 用来消除编译器的“没有用到”的提醒
- uint8_t data = 0;
-
- if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)
- {
- clear = USART1->SR;
- clear = USART1->DR;
-
- // RxCounter = BufferSize - DMA1_Channel5->CNDTR;//缓存中的字节数
- RxCounter = BufferSize - DMA_GetCurrDataCounter(DMA1_Channel5);//缓存中的字节数
-
- // USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);
-
- RxStatus = 1; //标记接收到一帧
- USART_ClearITPendingBit(USART1, USART_IT_IDLE); // 清除空闲中断
-
- DMA_Cmd(DMA1_Channel5, DISABLE); // 停止DMA,清除DMA缓存
- }
- }
- int main(void)
- {
- uint8_t i = 0;
- delay_init();
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); // 初始化中断优先级分组
- My_UART_Init();
- while(1)
- {
- if(RxStatus == 1)
- {
- RxStatus = 0;
- i = 0;
-
- while(RxCounter--)
- {
- USART_SendData(USART1, RxBuffer[i++]);
- while(USART_GetFlagStatus(USART1, USART_FLAG_TC) != SET);
- }
-
- memset(RxBuffer, 0, i); // 清除缓存
- RxCounter = 0;
-
- // DMA1_Channel5->CNDTR = BufferSize;
- DMA_SetCurrDataCounter(DMA1_Channel5, BufferSize);
- DMA_Cmd(DMA1_Channel5, ENABLE);
- }
-
- }
- }
|
|