微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 第43节:通过串口用计数延时方式发送一串数据

第43节:通过串口用计数延时方式发送一串数据

时间:11-22 来源:互联网 点击:
开场白:
上一节讲了通过串口用delay延时方式发送一串数据,这种方式要求发送一串数据的时候一气呵成,期间不能执行其它任务,由于delay(400)这个时间还不算很长,所以可以应用在很多简单任务的系统中。但是在某些任务量很多的系统中,实时运行的主任务不允许被长时间和经常性地中断,这个时候就需要用计数延时来替代delay延时。本节要教会大家两个知识点:
第一个:用计数延时方式发送一串数据的程序框架。
第二个:环形消息队列的程序框架。

具体内容,请看源代码讲解。

(1)硬件平台:
基于朱兆祺51单片机学习板

(2)实现功能:
波特率是:9600.
用朱兆祺51单片机学习板中的S1,S5,S9,S13作为独立按键。
按一次按键S1,发送EB 00 55 01 00 00 00 00 41
按一次按键S5,发送EB 00 55 02 00 00 00 00 42
按一次按键S9,发送EB 00 55 03 00 00 00 00 43
按一次按键S13,发送EB 00 55 04 00 00 00 00 44
(3)源代码讲解如下:

  1. #include "REG52.H"
  2. #define const_send_time100//累计主循环次数的计数延时 请根据项目实际情况来调整此数据大小
  3. #define const_send_size10//串口发送数据的缓冲区数组大小
  4. #define const_Message_size10//环形消息队列的缓冲区数组大小
  5. #define const_key_time120 //按键去抖动延时的时间
  6. #define const_key_time220 //按键去抖动延时的时间
  7. #define const_key_time320 //按键去抖动延时的时间
  8. #define const_key_time420 //按键去抖动延时的时间
  9. #define const_voice_short40 //蜂鸣器短叫的持续时间
  10. void initial_myself(void);
  11. void initial_peripheral(void);
  12. //void delay_short(unsigned int uiDelayshort);
  13. void delay_long(unsigned int uiDelaylong);
  14. void eusart_send(unsigned char ucSendData);//发送一个字节,内部没有每个字节之间的延时
  15. void send_service(void);//利用累计主循环次数的计数延时方式来发送一串数据
  16. void T0_time(void);//定时中断函数
  17. void usart_receive(void); //串口接收中断函数
  18. void key_service(void); //按键服务的应用程序
  19. void key_scan(void); //按键扫描函数 放在定时中断里
  20. void insert_message(unsigned char ucMessageTemp);//插入新的消息到环形消息队列里
  21. unsigned char get_message(void);//从环形消息队列里提取消息
  22. sbit led_dr=P3^5;//Led的驱动IO口
  23. sbit beep_dr=P2^7; //蜂鸣器的驱动IO口
  24. sbit key_sr1=P0^0; //对应朱兆祺学习板的S1键
  25. sbit key_sr2=P0^1; //对应朱兆祺学习板的S5键
  26. sbit key_sr3=P0^2; //对应朱兆祺学习板的S9键
  27. sbit key_sr4=P0^3; //对应朱兆祺学习板的S13键
  28. sbit key_gnd_dr=P0^4; //模拟独立按键的地GND,因此必须一直输出低电平
  29. unsigned char ucSendregBuf[const_send_size]; //串口发送数据的缓冲区数组
  30. unsigned char ucMessageBuf[const_Message_size]; //环形消息队列的缓冲区数据
  31. unsigned intuiMessageCurrent=0;//环形消息队列的取数据当前位置
  32. unsigned intuiMessageInsert=0;//环形消息队列的插入新消息时候的位置
  33. unsigned intuiMessageCnt=0;//统计环形消息队列的消息数量等于0时表示消息队列里没有消息
  34. unsigned char ucMessage=0; //当前获取到的消息
  35. unsigned intuiVoiceCnt=0;//蜂鸣器鸣叫的持续时间计数器
  36. unsigned charucVoiceLock=0;//蜂鸣器鸣叫的原子锁
  37. unsigned char ucKeySec=0; //被触发的按键编号
  38. unsigned intuiKeyTimeCnt1=0; //按键去抖动延时计数器
  39. unsigned char ucKeyLock1=0; //按键触发后自锁的变量标志
  40. unsigned intuiKeyTimeCnt2=0; //按键去抖动延时计数器
  41. unsigned char ucKeyLock2=0; //按键触发后自锁的变量标志
  42. unsigned intuiKeyTimeCnt3=0; //按键去抖动延时计数器
  43. unsigned char ucKeyLock3=0; //按键触发后自锁的变量标志
  44. unsigned intuiKeyTimeCnt4=0; //按键去抖动延时计数器
  45. unsigned char ucKeyLock4=0; //按键触发后自锁的变量标志
  46. unsigned char ucSendStep=0;//发送一串数据的运行步骤
  47. unsigned intuiSendTimeCnt=0; //累计主循环次数的计数延时器
  48. unsigned int uiSendCnt=0; //发送数据时的中间变量
  49. void main()
  50. {
  51. initial_myself();
  52. delay_long(100);
  53. initial_peripheral();
  54. while(1)
  55. {
  56. key_service(); //按键服务的应用程序
  57. send_service();//利用累计主循环次数的计数延时方式来发送一串数据
  58. }
  59. }
  60. /* 注释一:
  61. * 通过判断数组下标是否超范围的条件,把一个数组的首尾连接起来,就像一个环形,
  62. * 因此命名为环形消息队列。环形消息队列有插入消息,获取消

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

网站地图

Top