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

第44节:从机的串口收发综合程序框架

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

  1. 就增强
  2. dig_hc595_st_dr=0;
  3. dig_hc595_ds_dr=0;
  4. }
  5. //LED灯的74HC595驱动函数
  6. void hc595_drive(unsigned char ucLedStatusTemp16_09,unsigned char ucLedStatusTemp08_01)
  7. {
  8. unsigned char i;
  9. unsigned char ucTempData;
  10. hc595_sh_dr=0;
  11. hc595_st_dr=0;
  12. ucTempData=ucLedStatusTemp16_09;//先送高8位
  13. for(i=0;i<8;i++)
  14. {
  15. if(ucTempData>=0x80)hc595_ds_dr=1;
  16. else hc595_ds_dr=0;
  17. hc595_sh_dr=0; //SH引脚的上升沿把数据送入寄存器
  18. delay_short(1);
  19. hc595_sh_dr=1;
  20. delay_short(1);
  21. ucTempData=ucTempData<1;
  22. }
  23. ucTempData=ucLedStatusTemp08_01;//再先送低8位
  24. for(i=0;i<8;i++)
  25. {
  26. if(ucTempData>=0x80)hc595_ds_dr=1;
  27. else hc595_ds_dr=0;
  28. hc595_sh_dr=0; //SH引脚的上升沿把数据送入寄存器
  29. delay_short(1);
  30. hc595_sh_dr=1;
  31. delay_short(1);
  32. ucTempData=ucTempData<1;
  33. }
  34. hc595_st_dr=0;//ST引脚把两个寄存器的数据更新输出到74HC595的输出引脚上并且锁存起来
  35. delay_short(1);
  36. hc595_st_dr=1;
  37. delay_short(1);
  38. hc595_sh_dr=0; //拉低,抗干扰就增强
  39. hc595_st_dr=0;
  40. hc595_ds_dr=0;
  41. }
  42. void usart_receive(void) interrupt 4 //串口接收数据中断
  43. {
  44. if(RI==1)
  45. {
  46. RI = 0;
  47. ++uiRcregTotal;
  48. if(uiRcregTotal>const_rc_size)//超过缓冲区
  49. {
  50. uiRcregTotal=const_rc_size;
  51. }
  52. ucRcregBuf[uiRcregTotal-1]=SBUF; //将串口接收到的数据缓存到接收缓冲区里
  53. if(ucSendCntLock==0)//原子锁判断
  54. {
  55. ucSendCntLock=1; //加锁
  56. uiSendCnt=0;//及时喂狗,虽然在定时中断那边此变量会不断累加,但是只要串口的数据还没发送完毕,那么它永远也长不大,因为每个串口接收中断它都被清零。
  57. ucSendCntLock=0; //解锁
  58. }
  59. }
  60. else//我在其它单片机上都不用else这段代码的,可能在51单片机上多增加" TI = 0;"稳定性会更好吧。
  61. {
  62. TI = 0;//如果不是串口接收中断,那么必然是串口发送中断,及时清除发送中断的标志,否则一直发送中断
  63. }
  64. }
  65. void T0_time(void) interrupt 1 //定时中断
  66. {
  67. TF0=0;//清除中断标志
  68. TR0=0; //关中断
  69. /* 注释一:
  70. * 此处多增加一个原子锁,作为中断与主函数共享数据的保护,实际上是借鉴了"红金龙吸味"关于原子锁的建议.
  71. */
  72. if(ucSendCntLock==0)//原子锁判断
  73. {
  74. ucSendCntLock=1; //加锁
  75. if(uiSendCnt
  76. {
  77. uiSendCnt++; //表面上这个数据不断累加,但是在串口中断里,每接收一个字节它都会被清零,除非这个中间没有串口数据过来
  78. ucSendLock=1; //开自锁标志
  79. }
  80. ucSendCntLock=0; //解锁
  81. }
  82. if(ucVoiceLock==0) //原子锁判断
  83. {
  84. if(uiVoiceCnt!=0)
  85. {
  86. uiVoiceCnt--; //每次进入定时中断都自减1,直到等于零为止。才停止鸣叫
  87. beep_dr=0;//蜂鸣器是PNP三极管控制,低电平就开始鸣叫。
  88. }
  89. else
  90. {
  91. ; //此处多加一个空指令,想维持跟if括号语句的数量对称,都是两条指令。不加也可以。
  92. beep_dr=1;//蜂鸣器是PNP三极管控制,高电平就停止鸣叫。
  93. }
  94. }
  95. if(ucStatus!=0) //处于非待机的状态,Led闪烁
  96. {
  97. uiLedCnt++; //Led闪烁计时器不断累加
  98. }
  99. if(ucStatus==1) //处于正在通讯的状态,
  100. {
  101. if(ucSendTimeOutLock==0)//原子锁判断
  102. {
  103. uiSendTimeOutCnt++; //超时计时器累加
  104. if(uiSendTimeOutCnt>const_send_time_out)//超时出错
  105. {
  106. uiSendTimeOutCnt=0;
  107. ucStatus=2;//切换到出错报警状态
  108. }
  109. }
  110. }
  111. key_scan(); //按键扫描函数
  112. display_drive();//数码管字模的驱动函数
  113. TH0=0xfe; //重装初始值(65535-500)=65035=0xfe0b
  114. TL0=0x0b;
  115. TR0=1;//开中断
  116. }
  117. void delay_short(unsigned int uiDelayShort)
  118. {
  119. unsigned int i;
  120. for(i=0;i
  121. {
  122. ; //一个分号相当于执行一条空语句
  123. }
  124. }
  125. void delay_long(unsigned int uiDelayLong)
  126. {
  127. unsigned int i;
  128. unsigned int j;
  129. for(i=0;i
  130. {
  131. for(j=0;j<500;j++)//内嵌循环的空指令数量
  132. {
  133. ; //一个分号相当于执行一条空语句
  134. }
  135. }
  136. }
  137. void initial_myself(void)//第一区 初始化单片机
  138. {
  139. /* 注释二:
  140. * 矩阵键盘也可以做独立按键,前提是把某一根公共输出线输出低电平,
  141. * 模拟独立按键的触发地,本程序中,把key_gnd_dr输出低电平。
  142. * 朱兆祺51学习板的S1就是本程序中用到的一个独立按键。
  143. */
  144. key_gnd_dr=0; //模拟独立按键的地GND,因此必须一直输出低电平
  145. led_dr=1;//点亮独立LED灯
  146. beep_dr=1; //用PNP三极管控制蜂鸣器,输出高电平时不叫。
  147. hc595_drive(0x00,0x00);//关闭所有经过另外两个74HC595驱动的LED灯
  148. TMOD=0x01;//设置定时器0为工作方式1
  149. TH0=0xfe; //重装初始值(6553

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

网站地图

Top