你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32F051使用串口中断接收只能接收到第一位数据,后面的...

[复制链接]
snyanglq 提问时间:2014-11-4 14:29 /
使用STM32F051的串口2调试模块, MCU只接收到第一位数据,后面的7位数据都接收不到,请问改如何解决?
描述:
1、我使用串口调试助手测试MCU的程序,用MCU发送指令0xF5, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xF5
然后用助手发送正确的返回指令0xF5,0x0D, 0x00, 0x01, 0x00, 0x00, 0x0C, 0xF5
程序完全没有问题,全部都能接收能发送,并且我发错误指令时程序也能判断出错误,但是我连接上模块时,
程序出错了,程序一进接收中断就跑死,后来看了网上的大神解析改正过来,现在进入接收中断不会死了,但是又出现了新的问题

2、程序只能接收第一个数据 0XF5 后面的7位都不能接收,直接就接收超时了(我程序设定了1Sec 接收超时报警),我仿真了下,看到只能接收到一个数据
但是我用串口线把MCU的数据发送和模块的数据反馈打印到串口调试助手,发现,命令是正确的,模块也识别命令了,返回了正确的答复数据,说明指令的发送是没有错误的,是我程序的问题,但是我非常奇怪用串口调试助手调试时程序没有问题,连上模块就只能接收到第一个数据了。

串口初始化和中断接收的程序如下:

串口2初始化


  1. <span style="background-color: white;">void USART2_Init(void)//串口2初始化函数
  2. {  
  3.         GPIO_InitTypeDef  GPIO_InitStructure;
  4.         USART_InitTypeDef USART_InitStructure;
  5.         NVIC_InitTypeDef NVIC_InitStructure;
  6.         
  7.         RCC_AHBPeriphClockCmd( RCC_AHBPeriph_GPIOA, ENABLE);
  8.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE );
  9.                
  10.         GPIO_PinAFConfig(GPIOA,GPIO_PinSource2,GPIO_AF_1);
  11.         GPIO_PinAFConfig(GPIOA,GPIO_PinSource3,GPIO_AF_1);
  12.         
  13.         /*
  14.         *  USART2_TX -> PA2 , USART2_RX -> PA3
  15.         */                                
  16.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3;
  17.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  18.         GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;        //推挽
  19.         GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;        //上拉
  20.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  21.         GPIO_Init(GPIOA, &GPIO_InitStructure);        
  22.         
  23.         USART_InitStructure.USART_BaudRate = 57600;//设置串口波特率
  24.         USART_InitStructure.USART_WordLength = USART_WordLength_8b;//设置数据位
  25.         USART_InitStructure.USART_StopBits = USART_StopBits_1;//设置停止位
  26.         USART_InitStructure.USART_Parity = USART_Parity_No;//设置效验位
  27.         USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//设置无硬件流控制
  28.         USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//设置工作模式
  29.         USART_Init(USART2, &USART_InitStructure); //配置入结构体
  30.         
  31.         
  32.         NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
  33.         NVIC_InitStructure.NVIC_IRQChannelPriority = 0;
  34.         NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  35.         NVIC_Init(&NVIC_InitStructure);
  36.         USART_Cmd(USART2, ENABLE);//使能串口2
  37.         USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
  38. }</span>
复制代码
串口中断

  1. <span style="background-color: white;">void USART2_IRQHandler(void)
  2. {
  3.         uint8_t ch ,Clear_ch = 0;
  4.         
  5.         if(USART_GetITStatus(USART2, USART_IT_TXE) == SET)
  6.     {                                                                                                        
  7.                         USART_SendData(USART2, send_num[a++]);        
  8.                         Delay_ms(10);                        
  9.                         if(a == 8)
  10.                   {
  11.                                 a = 0;
  12.                                 b = 0;
  13.                                 Flag = 0;
  14.                                 USART_ITConfig(USART2, USART_IT_TXE, DISABLE);
  15.                                 USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
  16.                                 Delay_ms(1);
  17.                         }
  18.     }        
  19. //         if(USART2->ISR&(1<<5))
  20. if(USART_GetITStatus(USART2, USART_IT_RXNE) == SET)
  21.     {
  22.                         
  23.                         USART_ClearITPendingBit(USART2, USART_IT_RXNE);
  24.                 //        USART2->RQR |= 0x00000008;
  25.                   ch =USART_ReceiveData(USART2);
  26.                 //        ch = USART2->RDR;
  27.                         rec_num[b] = ch;
  28.                         b = b + 1;
  29.                         Flag = 1;
  30.                         //溢出错误检测
  31.                         if(USART_GetFlagStatus(USART2,USART_FLAG_ORE)==SET)
  32.                         {
  33.                                         USART_ClearFlag(USART2,USART_FLAG_ORE);        //读SR
  34.                                         ch = USART_ReceiveData(USART2);        //读DR
  35.                         }
  36.                 }
  37.         //溢出错误检测        
  38.         if(USART_GetFlagStatus(USART2,USART_FLAG_ORE)==SET)
  39.     {
  40.         USART_ClearFlag(USART2,USART_FLAG_ORE);        //读SR
  41.         Clear_ch = USART_ReceiveData(USART2);        //读DR
  42.                                 Flag = 1;
  43.                 }
  44.                
  45.                 //噪声误差检测               
  46.                 if(USART_GetFlagStatus(USART2, USART_FLAG_NE) != RESET)
  47.                 {
  48.                         USART_ClearFlag(USART2, USART_FLAG_NE);
  49.                 //        Clear_ch = USART_ReceiveData(USART2);        
  50.                         Flag = 1;
  51.                 }
  52.                 //帧错误检测
  53.                 if(USART_GetFlagStatus(USART2, USART_FLAG_FE) != RESET)
  54.                 {
  55.                         USART_ClearFlag(USART2, USART_FLAG_FE);
  56.                 //        Clear_ch = USART_ReceiveData(USART2);      
  57.                         Flag = 1;
  58.                 }
  59.                 //校验错误检测
  60.                 if(USART_GetFlagStatus(USART2, USART_FLAG_PE) != RESET)
  61.                 {
  62.                         USART_ClearFlag(USART2, USART_FLAG_PE);
  63.                 //        Clear_ch = USART_ReceiveData(USART2);        
  64.                         Flag = 1;
  65.                 }
  66.         
  67.                 Clear_ch = Clear_ch+0;
  68. }</span>
复制代码


现在这个程序只能接收到第一位数据
rec_num[]缓存中只有rec_num[0]接收到0XF5,后面的7位接收不到了。
运行平台如下:
STM32F051C8T6    内部8MHz晶振   系统时钟48MHz  通信波特率  57600
最后再说一下问题吧,MCU与串口调试助手对发与接收时,程序没有问题 。MCU与模块发送接收时MCU只能接收第一位数据,后面的7位接收不到,为什么?请大神帮帮忙。



收藏 评论21 发布时间:2014-11-4 14:29

举报

21个回答
snyanglq 回答时间:2014-12-3 16:49:07
小贾-370388 发表于 2014-11-29 12:00
你怎么知道一定是接收到了命令的 第一个字节的0xf5啊 ,你的命令最后一个字节也是0XF5啊,会不会是你的接收 ...

谢谢你的回答,这个值我仿真看到的,不关a的事,如果a的问题,我跟串口调试助手时调试也不行啊,不过问题找到了,只要将最后一次延时去掉就可以
snyanglq 回答时间:2014-11-20 10:42:20
netlhx 发表于 2014-11-6 18:47
第一段代码的37行,最好启用USART_IT_RX中断,不要去启用USART_IT_RXNE中断。
第二段代码里没有清除USART_I ...

谢谢,问一下,有USART_IT_RX这个参数吗?要怎么设置,第二段有清除的,应该是哪天贴的比较急乱了,你没有看到,现在整理好了
小贾-370388 回答时间:2014-11-29 12:00:53
你怎么知道一定是接收到了命令的 第一个字节的0xf5啊 ,你的命令最后一个字节也是0XF5啊,会不会是你的接收缓存被冲掉了,只剩下了最后一个受到的数啊 ,a变量时不是有问题?看看定义位置,还有事不是别处也调用了
snyanglq 回答时间:2014-11-4 14:30:45
请大家指点一下,谢谢
netlhx 回答时间:2014-11-6 18:47:16
第一段代码的37行,最好启用USART_IT_RX中断,不要去启用USART_IT_RXNE中断。
第二段代码里没有清除USART_IT_RXNE或USART_IT_RX中断标志的语句。
沐紫 回答时间:2014-11-10 09:47:41
谢谢楼上朋友,楼主问题如果解决了回复一下哦,如果没有,可以继续追问滴
feixiang20 回答时间:2014-11-10 23:35:04
可能是在中断的地方搞错了位置,或者是参数设置错误
snyanglq 回答时间:2014-11-20 10:42:38
沐紫 发表于 2014-11-10 09:47
谢谢楼上朋友,楼主问题如果解决了回复一下哦,如果没有,可以继续追问滴 ...

还没有呢
snyanglq 回答时间:2014-11-20 10:43:39
feixiang20 发表于 2014-11-10 23:35
可能是在中断的地方搞错了位置,或者是参数设置错误

但是我用串口调试助手与MCU互调没有问题,应该不太可能吧
snyanglq 回答时间:2014-11-20 10:44:36
谢谢各位的回答,不过问题还没有解决,还得继续努力啊
那片清茶 回答时间:2014-11-21 08:51:08
你用查询发送,中断接收试试。。。
废鱼 回答时间:2014-11-21 09:16:12
中断中为什么要加延时啊?中断中不要有太多的处理,简单发送或者接收,在外部对这些数据缓冲区进行处理。
snyanglq 回答时间:2014-11-21 13:38:34
那片清茶 发表于 2014-11-21 08:51
你用查询发送,中断接收试试。。。

也试过,还是不行
snyanglq 回答时间:2014-11-21 13:41:19
安 发表于 2014-11-21 09:16
中断中为什么要加延时啊?中断中不要有太多的处理,简单发送或者接收,在外部对这些数据缓冲区进行处理。 ...

这个不碍事,主要是不加延时会丢包
废鱼 回答时间:2014-11-21 14:04:07
怎么会丢包呢?正常收发是不会发生该问题的.
12下一页
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版