ST MCU Finder
安装免费手机应用,
寻找理想的ST MCU

[STM32F1] USART通讯接收并判断的问题,麻烦好心大哥解答一下!

[复制链接]
198|4
 楼主 | 2019-7-10 17:48 | 显示全部楼层 |阅读模式
我的程序是一个串口屏向单片机发送数据,然后单片机根据内容响应
开启了USART1、USART2
如果只是在接收中断里面写收到就马上转发出来,没问题
但是一旦判断就没反应。用IAR调试但是又只进一次中断,不知道什么原因!
下面为主要程序代码:
定义了一个结构体:
typedef struct
{
  u8 head;                       //接收自定义头  0xaa
  u8 data[15];                 //内容数组
  u8 data_pt;                 //用于数组  
  u8 end_byte;              //结束字符  0xdd
  u8 lock_flag;              //完成标志 1=完成,0=未完成
}ptr_stack;
extern ptr_stack rx_stack;
//------------------------------------------------------------------

//main.c文件的主要部分
main()
{
while(1)
    {
        if(rx_stack.lock_flag == 1)             //如果数据接受完成,进行下一步判断
        {
          if(rx_stack.data[1] == 0xbb)      //如果这个位的数组等于0xbb,那么进行下面的操作
            {
              u2_printf();                            //这个是一个通过USART2的内容输出  
              rx_stack.lock_flag = 0;          //将接收完成标志归0,意思就是解锁接收
              rx_stack.data_pt=0;             //归零
              rx_stack.end_byte=0;          //完成标志归零
               }
          if(rx_stack.data[1] == 0xcc)
            {
              normal_mode();                    //这个是另外一个通过USART1的内容输出
              rx_stack.lock_flag = 0;          //将接收完成标志归0,意思就是解锁接收
              rx_stack.data_pt=0;             //归零
              rx_stack.end_byte=0;          //完成标志归零
             }
        }
    }
}


//----------------------------------------------
//下面是Usart.c的重要部分
//配置肯定是没问题,中断等级USART1是0,0  : USART2是1,0
void USART1_IRQHandler(void)
{
  u8 rev_data;
    if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //判断读寄存器是否非空
      {
           if(rx_stack.lock_flag == 0) //如果串口没锁住,代表协议未满
                {
                       // rev_data = USART_ReceiveData(USART1);
                      rev_data =  USART1->DR;                                      //读数据,手持上说,读了数据自然就清除了标志,但是为了保险,还是再次手动清除
            
                       if(rev_data == 0xAA)                                                     //如果是头,则放入头里面
                        {
                             rx_stack.head = rev_data ;
                        }
                       else if(rev_data == 0xDD)                                                       //如果是结束,则放入结束里面
                        {
                             rx_stack.end_byte = rev_data ;
                         }
                      else
                       {
                          rx_stack.data[rx_stack.data_pt++] = rev_data;                  //如果既不是头,也不是尾就放入数据组里面
                        }
                      if((rx_stack.data_pt >= 5) && (rx_stack.end_byte == 0xDD))          //如果接受状态满,且结束位也被接收到,则锁住,直到数据被处理之后解锁
                        {
                            rx_stack.data_pt=0;
                            rx_stack.lock_flag = 1;
                         }
                 }
                USART_ClearFlag(USART1, USART_IT_RXNE);                                        //手工再清除接受中断标志   
         }
}





//--------------------------------------------------------
主要程序如上,用串口调试,
发送数据  AA CC CC 30 31 39 30 37 30 38 32 32 34 37 DD  
或者  AA DD DD 30 31 39 30 37 30 38 32 32 34 37 DD

都没有任何反应,
IAR也不熟,设置断点在  rev_data =  USART1->DR;  这个地方,发数据来的时候,中断会响应,单步执行完一次,就没有第二次了

麻烦大哥看看,指导一下!谢谢!

使用特权

评论回复
 楼主 | 2019-7-10 18:05 | 显示全部楼层
第二发送写错了,应该是发的   AA BB BB 30 31 39 30 37 30 38 32 32 34 37 DD

使用特权

评论回复
| 2019-7-10 21:10 | 显示全部楼层
要学会软件调试分析问题,查找原因,比如看串口寄存器,结合芯片手册分析串口不接收数据可能存在的原因

使用特权

评论回复
| 2019-7-11 10:31 | 显示全部楼层
简单来说,UART接收一帧数据,是多次进入接收中断的,每次接收一位;
设置断点在  rev_data =  USART1->DR;后面的数据丢失是正常的,你程序都停了,后面过来的数据自然就丢失了;
把断点设置到  rx_stack.lock_flag = 1;
上面的的置1应该就是你接收一帧数据结束,这个时候你看看你接收的数据全不全。

使用特权

评论回复
 楼主 | 2019-7-11 16:22 | 显示全部楼层
谢谢各位!只能换方式来了!

使用特权

评论回复
扫描二维码,随时随地手机跟帖
您需要登录后才可以回帖 登录 | 注册

本版积分规则

我要发帖 投诉建议 创建版块 申请版主

快速回复

您需要登录后才可以回帖
登录 | 注册
高级模式

论坛热帖

在线客服 快速回复 返回顶部 返回列表