微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 第45节:主机的串口收发综合程序框架

第45节:主机的串口收发综合程序框架

时间:11-22 来源:互联网 点击:

  1. ucReceiveStatus=0;//返回的数据状态清零
  2. ucSendStep=1;//切换到下一个步骤,等待返回的数据
  3. break;
  4. case 1: //通讯过程1判断返回的指令
  5. if(ucReceiveStatus==1)//校验正确
  6. {
  7. ucErrorCnt=0; //累计校验错误总数清零
  8. ucSendTotal++;//累加当前发送了多少串数据
  9. if(ucSendTotal>=4) //已经发送完全部4串数据,结束
  10. {
  11. ucStatus=0;//切换到结束时的待机状态
  12. }
  13. else//还没发送完4串数据,则继续发送下一串新数据
  14. {
  15. ucSendStep=0;//返回上一个步骤,继续发送新数据
  16. }
  17. }
  18. else if(ucReceiveStatus==2||uiSendTimeOutCnt>const_send_time_out)//校验出错或者超时出错
  19. {
  20. ucErrorCnt++; //累计错误总数
  21. if(ucErrorCnt>=3)//累加重发次数3次以上,则报错
  22. {
  23. ucStatus=2;//切换到出错报警状态
  24. }
  25. else//重发还没超过3次,继续返回重发
  26. {
  27. ucSendStep=0;//返回上一个步骤,重发一次数据
  28. }
  29. }
  30. break;
  31. }
  32. }
  33. }
  34. void status_service(void)//状态显示的应用程序
  35. {
  36. if(ucStatus!=0) //处于非待机的状态,Led闪烁
  37. {
  38. if(uiLedCnt
  39. {
  40. led_dr=1;//前半秒亮
  41. if(ucStatus==2)//处于发送数据出错的状态,则蜂鸣器间歇鸣叫报警
  42. {
  43. ucVoiceLock=1;//原子锁加锁,保护主函数与中断函数的共享变量uiVoiceCnt
  44. uiVoiceCnt=const_voice_short; //按键声音触发,滴一声就停。
  45. ucVoiceLock=0;//原子锁解锁,保护主函数与中断函数的共享变量uiVoiceCnt
  46. }
  47. }
  48. else if(uiLedCnt
  49. {
  50. led_dr=0; //前半秒灭
  51. }
  52. else
  53. {
  54. ucLedLock=1; //原子锁加锁
  55. uiLedCnt=0; //延时计时器清零,让Led灯处于闪烁的反复循环中
  56. ucLedLock=0; //原子锁解锁
  57. }
  58. }
  59. else//处于待机状态,Led一直亮
  60. {
  61. led_dr=1;
  62. }
  63. }
  64. void usart_service(void)//串口接收服务程序,在main函数里
  65. {
  66. unsigned int i;
  67. if(uiSendCnt>=const_receive_time&&ucSendLock==1) //说明超过了一定的时间内,再也没有新数据从串口来
  68. {
  69. ucSendLock=0; //处理一次就锁起来,不用每次都进来,除非有新接收的数据
  70. //下面的代码进入数据协议解析和数据处理的阶段
  71. uiRcMoveIndex=0; //由于是判断数据头,所以下标移动变量从数组的0开始向最尾端移动
  72. while(uiRcregTotal>=5&&uiRcMoveIndex<=(uiRcregTotal-5))
  73. {
  74. if(ucRcregBuf[uiRcMoveIndex+0]==0xeb&&ucRcregBuf[uiRcMoveIndex+1]==0x00&&ucRcregBuf[uiRcMoveIndex+2]==0x55)//数据头eb 00 55的判断
  75. {
  76. ucRcType=ucRcregBuf[uiRcMoveIndex+3]; //数据类型一个字节
  77. uiRcSize=ucRcregBuf[uiRcMoveIndex+4]; //数据长度两个字节
  78. uiRcSize=uiRcSize<8;
  79. uiRcSize=uiRcSize+ucRcregBuf[uiRcMoveIndex+5];
  80. ucRcCy=ucRcregBuf[uiRcMoveIndex+6+uiRcSize]; //记录最后一个字节的校验
  81. ucRcregBuf[uiRcMoveIndex+6+uiRcSize]=0;//清零最后一个字节的累加和变量
  82. for(i=0;i<(3+1+2+uiRcSize);i++) //计算校验累加和
  83. {
  84. ucRcregBuf[uiRcMoveIndex+6+uiRcSize]=ucRcregBuf[uiRcMoveIndex+6+uiRcSize]+ucRcregBuf[uiRcMoveIndex+i];
  85. }
  86. if(ucRcCy==ucRcregBuf[uiRcMoveIndex+6+uiRcSize])//如果一串数据校验正确,则进入以下数据指令的判断
  87. {
  88. switch(ucRcType) //根据不同的数据类型来做不同的数据处理
  89. {
  90. case 0xf5: //返回的是正确的校验指令
  91. ucReceiveStatus=1;//代表校验正确
  92. break;
  93. case 0xfa: //返回的是错误的校验指令
  94. ucReceiveStatus=2;//代表校验错误
  95. break;
  96. }
  97. }
  98. break; //退出循环
  99. }
  100. uiRcMoveIndex++; //因为是判断数据头,游标向着数组最尾端的方向移动
  101. }
  102. uiRcregTotal=0;//清空缓冲的下标,方便下次重新从0下标开始接受新数据
  103. }
  104. }
  105. void eusart_send(unsigned char ucSendData) //发送一个字节,内部自带每个字节之间的delay延时
  106. {
  107. ES = 0; //关串口中断
  108. TI = 0; //清零串口发送完成中断请求标志
  109. SBUF =ucSendData; //发送

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top