单片机/MCU论坛
直播中

wy88451705

9年用户 3经验值
擅长:可编程逻辑 嵌入式技术 光电显示
私信 关注

51单片机接收到指令后的控制问题

       我最近在做套用AT89S52开发的控制柜的板子, 是利用RS485的方式从上位机通过单片机控制40个接口。
      协议、通信、控制功能都已经实现了,现在为了加强协议的抗干扰性,在协议里面加了一位“01”和“04”命令标识,例如我发送 68 01 01 06 01 00 00 00 8C,单片机接收到这串指令后,只是通过译码器识别40个接口的高低电平的状态,而不通过译码器发送这串指令去控制任何一个接口的高低电平,然后再给上位机发送一串指令,让上位机知道40个接口的状态;我要是发送68 01 04 06 01 00 00 00 8C,单片机接收到这串指令后,通过译码器将1号接口置为高电平,然后再给上位机发送一串指令,让上位机知道40个接口的状态;
      目前程序流程就是上位机发一组指令,单片机返回一组指令,我现在在协议里加上命令标示后(“04”好说,保存原状就行)当单片机收到带“01”的指令后,怎么样不向译码器发送这串指令去控制接口,并且读一遍所有接口的状态返回给上位机?怎么样通过程序控制单片机如何处理接收到的指令?
      下面是我写得这部分功能代码,那位专家帮忙指导下,如做过类此的东西,能直接附上代码让我学习下最好了!!!!谢谢

  1. void main(void)
  2. {
  3. unsigned char i;
  4. UART_init();        //初始化串口

  5. LED=0;                  //red lamp   
  6. RS485E=0;                  //green lamp   
  7.      
  8. //  addr_re();
  9. (*((void (*)())(addr_re)))();  // 执行上一行代码,将rst数组当函数调用
  10. (*((void (*)())(rq)))();

  11. //UART_init();        //初始化串口
  12. for(i = 0;i < 10 ;i++)
  13. {
  14.          //首先发送一次数据作为测试用
  15.    (*((void (*)())(COM_send)))();
  16. }
  17. while(1)   
  18. {
  19.   WDI=0;
  20.    if(read_flag==1)  //如果取数标志已置位,就将读到的数从串口发出
  21.   {
  22.      RS485E=1;
  23.     (*((void (*)())(COM_send)))();
  24.    _nop_();
  25.    read_flag=0; //取数标志清0
  26.   }
  27. else
  28.   {
  29.    RS485E=0;  
  30.   }
  31.   WDI=1;
  32. //;_nop();
  33.   }  
  34. }

这里是协议定义的内容,协议我写在中断里面了。


  1. case 2: //命令标示

  2.          if(temp==0x01)  
  3.    {
  4.     cmd_order=temp;


  5.     //单片机只识别不发送的功能

  6.     state=3;
  7.    }
  8.        else if(temp==0x04)  
  9.    {
  10.     cmd_order=temp;
  11.     state=3;
  12.    }
  13.    else
  14.    {
  15.     rc_index=0;
  16.     state=0;
  17.     MSG_LEN=0;
  18.     sum=0;
  19.       }
  20.   break;
  21.   case 3: //接收数据长度
  22.    if(temp<=7)
  23.    {
  24.     MSG_LEN=temp;
  25.     prar_len=MSG_LEN-1;
  26.     state=4;
  27.    }
  28.    else
  29.    {
  30.     rc_index=0;
  31.     state=0;
  32.     MSG_LEN=0;
  33.     sum=0;
  34.    }
  35.   break;
  36.   case 4: //获取命令参数
  37.    rbut[rc_index]=temp;
  38.    sum=sum+temp;
  39.    rc_index=rc_index+1;
  40.    if(rc_index>=prar_len)  state=5;
  41.   break;


已退回1积分

回帖(4)

yygy3748

2015-1-12 21:56:01
(*((void (*)())(COM_send)))();
这个怎样看啊,好像好高深
举报

南天音乐

2015-1-13 14:35:41
个人觉得你的思路有点局限,没有理清整个程序框架。
首先应当确定一套通信协议,但这个通信协议并不是直接用于控制,而是使需要传送的数据能准确无误的发送和接收,打个比方,要发送的数据是货物,而这个协议是汽车,汽车只负责完整的确保货物被送达,而不参与控制。
接下来就是将要发送的数据通过该协议打包,接收的数据从该协议拆包。这个应数据底层程序,其实是非常简单的。
再说控制,通过通信协议拆解出的数据已经是正确数据了,那么只需要设定另一套控制的协议即可。这点不用多说应该也明白了。
总的来说,做通信控制应包含两层协议,第一是数据通信协议,即保正传输的数据能正确完整的接收。
第二是应用层面的数据协议,就是指通过第一层协议承载的有用数据的数据格式。这样有条理的设计程序才是最佳。
补充一点,在串口中断中一般不允许过长的程序,但可以将第一层数据同信协议做在里面。
举报

nzm800

2015-2-21 00:15:49
都是大师,我想凑个热闹都不好意思
举报

霺ミ笑敷衍心痛

2015-3-2 09:59:48
大师们你们速度解答我来像你们学习的来了
举报

更多回帖

发帖
×
20
完善资料,
赚取积分