串口接收消息并返回

2019-03-24 18:52发布

最近实验PC通过串口与单片机通信,要求如下代码开头所说,但是通信过程中在按键的同时lcd与PC的串口助手同时出现了多余信息,请高手指教。
  另外,我想在单片机接收到8个字符后自动发送8个字符,请问程序能如何设计呢?
  1. /********************************************************************
  2. * 文件名  : 串口接收试验.c
  3. * 描述    :  该程序从串口接收数据,通过1602LCD显示数据。在LCD的第一行显示出来,
  4.     当数据过多时(超过16个字符),LCD第一行将会被覆盖。显示完成之后通过按键
  5.     发送字符串到PC。程序使用两个中断,分别是串口中断与外部的按键中断   
  6. ***********************************************************************/
  7. #include
  8. #include#define uchar unsigned char
  9. #define uint  unsigned int
  10. uchar key_s, key_v;
  11. uint COUNT = 0;void Time0_Init(void);
  12. void writedata(void);
  13. /*LED_Buffer[16]用来存储串口发送的数据,com_dat用来记录串口发送的个数*/
  14. uchar LED_Buffer[16], *q, com_dat;      //从串口接收的数据//这三个引脚参考资料
  15. sbit E=P2^7;  //1602使能引脚
  16. sbit RW=P2^6;  //1602读写引脚
  17. sbit RS=P2^5;  //1602数据/命令选择引脚
  18. sbit K1 = P3^2;//字符串发送按钮/********************************************************************
  19. * 名称 : Delay(uint del)
  20. * 功能 : 延时10ms * del
  21. * 输入 : 无
  22. * 输出 : 无
  23. ***********************************************************************/
  24. void Delay(uint del)
  25. {
  26. uint i,j;
  27. for(i=0; i
  28. for(j=0; j<1827; j++)   
  29. ;
  30. }/********************************************************************
  31. * 名称 : delay()
  32. * 功能 : 延时,延时时间大概为140US。
  33. * 输入 : 无
  34. * 输出 : 无
  35. ***********************************************************************/
  36. void delay()
  37. {
  38. int i,j;
  39. for(i=0; i<=10; i++)
  40. for(j=0; j<=2; j++)
  41. ;
  42. }/********************************************************************
  43. * 名称 : enable(uchar del)
  44. * 功能 : 1602命令函数
  45. * 输入 : 输入的命令值
  46. * 输出 : 无
  47. ***********************************************************************/
  48. void enable(uchar del)
  49. {
  50. P0 = del;
  51. RS = 0;
  52. RW = 0;
  53. E = 0;
  54. delay();
  55. E = 1;
  56. delay();
  57. }/********************************************************************
  58. * 名称 : write(uchar del)
  59. * 功能 : 1602写数据函数
  60. * 输入 : 需要写入1602的数据
  61. * 输出 : 无
  62. ***********************************************************************/
  63. void write(uchar del)
  64. {
  65. P0 = del;
  66. RS = 1;
  67. RW = 0;
  68. E = 0;
  69. delay();
  70. E = 1;
  71. delay();
  72. }/********************************************************************
  73. * 名称 : L1602_init()
  74. * 功能 : 1602初始化,请参考1602的资料
  75. * 输入 : 无
  76. * 输出 : 无
  77. ***********************************************************************/
  78. void L1602_init(void)
  79. {
  80. enable(0x01);
  81. enable(0x38);
  82. enable(0x0c);
  83. enable(0x06);
  84. enable(0xd0);
  85. }/********************************************************************
  86. * 名称 : L1602_char(uchar hang,uchar lie,char sign)
  87. * 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符显示"b" ,调用该函数如下
  88.    L1602_char(1,5,'b')
  89. * 输入 : 行,列,需要输入1602的数据
  90. * 输出 : 无
  91. ***********************************************************************/
  92. void L1602_char(uchar hang,uchar lie,char sign)
  93. {
  94. uchar a;
  95. if(hang == 1) a = 0x80;
  96. if(hang == 2) a = 0xc0;
  97. a = a + lie - 1;
  98. enable(a);
  99. write(sign);
  100. }/********************************************************************
  101. * 名称 : L1602_string(uchar hang,uchar lie,uchar *p)
  102. * 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符开始显示"ab cd ef" ,调用该函数如下
  103.     L1602_string(1,5,"ab cd ef;")
  104. * 输入 : 行,列,需要输入1602的数据
  105. * 输出 : 无
  106. ***********************************************************************/
  107. void L1602_string(uchar hang,uchar lie,uchar *p)
  108. {
  109. uchar a;
  110. if(hang == 1) a = 0x80;
  111. if(hang == 2) a = 0xc0;
  112. a = a + lie - 1;
  113. enable(a);
  114. while(1)
  115. {
  116.   if(*p == '')
  117.    break;
  118.   write(*p);
  119.   p++;
  120. }
  121. }/********************************************************************
  122. * 名称 : Com_Int()
  123. * 功能 : 串口中断子函数
  124. * 输入 : 无
  125. * 输出 : 无
  126. ***********************************************************************/
  127. void Com_Int(void) interrupt 4
  128. {
  129. EA = 0;
  130. if(RI == 1)   //当硬件接收到一个数据时,RI会置位
  131. {
  132.   LED_Buffer[com_dat] = SBUF;   //把从串口读出的数存到数组
  133.   RI = 0;           //标志位清0
  134.   com_dat++;
  135.   if(com_dat == 16)
  136.    com_dat = 0;  //当com_dat = 16时,清0,防止数组溢出
  137. }
  138. EA = 1;
  139. }/********************************************************************
  140. * 名称 : Com_Init()
  141. * 功能 : 串口初始化,晶振11.0592,波特率9600,使能了串口中断
  142. * 输入 : 无
  143. * 输出 : 无
  144. ***********************************************************************/
  145. void Com_Init(void)
  146. {
  147.      TMOD = 0x20;   //定时器工作在定时器1的方式2
  148.      PCON = 0x00;   //不倍频
  149.      SCON = 0x50; //串口工作在方式1,并且启动串行接收
  150.      TH1 = 0xFd;    //设置波特率 9600
  151.      TL1 = 0xFd;
  152.      TR1 = 1;  //启动定时器1
  153.   ES = 1;  //开串口中断
  154.   EA = 1;  //开总中断  
  155. }void writedata()
  156. {
  157. uchar i = 0;
  158. uint j = 0;
  159. uchar code Buf1[] = "abcdefgh";  //所要发送的数据
  160. uchar *p; p = Buf1;
  161. while(1)
  162. {   
  163.   SBUF = *p;
  164.   while(!TI)                   //如果发送完毕,硬件会置位TI
  165.   {
  166.    _nop_();
  167.   }
  168.   p++;
  169.   if(*p == '')
  170.    break;  //在每个字符串的最后,会有一个''
  171.   TI = 0;                  //TI清零   
  172. }
  173. }void Outside_Init(void)
  174. {
  175. EX0 = 1;  //开外部中断0
  176. IT0 = 1;  //负边沿触发
  177. EA = 1;   //开总中断
  178. }void Outside_Int1(void) interrupt 0 using 1
  179. {
  180. if(K1 == 0)
  181. {
  182.   Delay(2);
  183.   if(K1 == 0)
  184.    writedata();
  185. }
  186. }void Main()
  187. {
  188. uchar i = 0, com_dat = 0;
  189. L1602_init();
  190. Delay(100);
  191. Com_Init();
  192. Outside_Init();
  193. P2 = 0x00;
  194. while(1)
  195. {
  196.   q = LED_Buffer;
  197.   L1602_string(1,1,q);
  198.   com_dat = 0;
  199.   Delay(10);
  200. }
  201. }

复制代码 此帖出自小平头技术问答
0条回答

一周热门 更多>