OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 15203|回复: 2

上位机通过串口控制STM32的问题

[复制链接]

3

主题

5

帖子

0

精华

新手上路

积分
37
金钱
37
注册时间
2012-3-29
在线时间
0 小时
发表于 2012-3-29 16:34:51 | 显示全部楼层 |阅读模式

基本功能描述:
上位机发送指令控制STM32
情况一:命令为3个字符
起始符  命令符    结束符     功能
0x2f       0x34     0xcc     温度数据返回
0x2f       0x32     0xcc     led亮
0x2f       0x33     0xcc     led灭                        
我是通过串口中断来实现串口数据的接收的。
中断程序如下:如果接收到的指令正确,改变全局变量USART_RX_STA 的值,让它等于0x80。
if(USART_RX_STA != 0x80)
{
  if(data == 0x2f)      //起始符
  {
   memset(RecvBuf, 0, sizeof(RecvBuf));
   RecvBuf[0] = data;
   USART_RX_STA = 0;
   USART_SendData(USART1, data);
   while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET); 
  }
   else if(data == 0x39)      //结束符
   {
    if(RecvBuf[0] != 0x2f)
    {
      memset(RecvBuf, 0, sizeof(RecvBuf));
     return; 
    }
    RecvBuf[2] = data;
    USART_RX_STA = 0x80;
    USART_SendData(USART1, data);
    while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET);
   } 
   else
   {
    RecvBuf[1] = data;
    USART_SendData(USART1, data);
    while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET);
   }
}

主函数程序:
while(1)
{
    if(USART_RX_STA == 0x80)
  {
      switch(RecvBuf[1])
     {
      case 0x30: 

       break;

      case 0x31: 

      break;

     case 0x32: 
      GPIO_SetBits(GPIOD, GPIO_Pin_2);
     break;

    case 0x33: 
    GPIO_ResetBits(GPIOD, GPIO_Pin_2);
   break;

   case 0x34: 
    temp=DS18B20_Get_Temp();
    memset(SendBuf, 0, sizeof(SendBuf));
    SendBuf[0] = 0x2f;
    SendBuf[1] = 0x34;
    if(temp<0)
    {
     temp=-temp;
     SendBuf[2] = Number[11]; 
    }
    else
    {
     SendBuf[2] = Number[10];
    }
    SendBuf[3] = Number[temp/100%10];
    SendBuf[4] = Number[temp/10%10];
    SendBuf[5] = '.';
    SendBuf[6] = Number[temp%10];
    SendBuf[7] = 0x04;
    SendBuf[8] = 0xcc;
    for(i = 0; i < 9; ++i)
    {
      USART_SendData(USART1, SendBuf);
     while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET);
    }
   break;

   default:
       break;
   }
   USART_RX_STA = 0;
   }
  else
  {
   delay_ms(200);
  }
 }
}
问题是:程序开始还可以正确执行,但是执行一段时间,再发送指令,它就没有响应了。

全局变量是在mian.c文件里定义,然后在中断程序里extern了一下。我也不知道这个程序可能出了什么问题,望大虾指点一二!


正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165371
金钱
165371
注册时间
2010-12-1
在线时间
2110 小时
发表于 2012-3-29 17:38:35 | 显示全部楼层
说明你的中断接收程序存在问题.
我不管你怎么实现的,我说说我的看法:这种类似modbus协议,你必须规定一次接收时间的上线,因为如果是一条指令发过来,肯定是连在一起的,你可以计算一下接收完最长的指令需要多长时间.然后设置i一个超时时间,超过这个时间了的,就认为不是这个指令了.每条指令接收完做好处理之后清空. 另外,最好对指令做CRC校验,以保证数据的正确性. 
详细情况,你可以百度一下modbus.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

20

主题

562

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
670
金钱
670
注册时间
2012-2-28
在线时间
0 小时
发表于 2012-3-30 15:29:27 | 显示全部楼层
我感觉你这个通讯协议都放在中断中,连收到一个字符发送都放在中断中,容易出问题啊,还不如设置一个标识符,然后在主程序中进行判断,而且协议这样写有很多漏洞,如果你中间有一个数据和你起始的数据一样你怎么办啊,如果中间有一个数据和你结束的字符一样你怎么办啊,有待改进啊
努力,前进。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-25 07:34

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表