[求助] 串口接收消息并返回

cooljun007   2013-2-4 16:14 楼主
最近实验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 for(j=0; j<1827; j++)
  28. ;
  29. }

    /********************************************************************

  30. * 名称 : delay()
  31. * 功能 : 延时,延时时间大概为140US。
  32. * 输入 : 无
  33. * 输出 : 无
  34. ***********************************************************************/
  35. void delay()
  36. {
  37. int i,j;
  38. for(i=0; i<=10; i++)
  39. for(j=0; j<=2; j++)
  40. ;
  41. }

    /********************************************************************

  42. * 名称 : enable(uchar del)
  43. * 功能 : 1602命令函数
  44. * 输入 : 输入的命令值
  45. * 输出 : 无
  46. ***********************************************************************/
  47. void enable(uchar del)
  48. {
  49. P0 = del;
  50. RS = 0;
  51. RW = 0;
  52. E = 0;
  53. delay();
  54. E = 1;
  55. delay();
  56. }

    /********************************************************************

  57. * 名称 : write(uchar del)
  58. * 功能 : 1602写数据函数
  59. * 输入 : 需要写入1602的数据
  60. * 输出 : 无
  61. ***********************************************************************/
  62. void write(uchar del)
  63. {
  64. P0 = del;
  65. RS = 1;
  66. RW = 0;
  67. E = 0;
  68. delay();
  69. E = 1;
  70. delay();
  71. }

    /********************************************************************

  72. * 名称 : L1602_init()
  73. * 功能 : 1602初始化,请参考1602的资料
  74. * 输入 : 无
  75. * 输出 : 无
  76. ***********************************************************************/
  77. void L1602_init(void)
  78. {
  79. enable(0x01);
  80. enable(0x38);
  81. enable(0x0c);
  82. enable(0x06);
  83. enable(0xd0);
  84. }

    /********************************************************************

  85. * 名称 : L1602_char(uchar hang,uchar lie,char sign)
  86. * 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符显示"b" ,调用该函数如下
  87. L1602_char(1,5,'b')
  88. * 输入 : 行,列,需要输入1602的数据
  89. * 输出 : 无
  90. ***********************************************************************/
  91. void L1602_char(uchar hang,uchar lie,char sign)
  92. {
  93. uchar a;
  94. if(hang == 1) a = 0x80;
  95. if(hang == 2) a = 0xc0;
  96. a = a + lie - 1;
  97. enable(a);
  98. write(sign);
  99. }

    /********************************************************************

  100. * 名称 : L1602_string(uchar hang,uchar lie,uchar *p)
  101. * 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符开始显示"ab cd ef" ,调用该函数如下
  102. L1602_string(1,5,"ab cd ef;")
  103. * 输入 : 行,列,需要输入1602的数据
  104. * 输出 : 无
  105. ***********************************************************************/
  106. void L1602_string(uchar hang,uchar lie,uchar *p)
  107. {
  108. uchar a;
  109. if(hang == 1) a = 0x80;
  110. if(hang == 2) a = 0xc0;
  111. a = a + lie - 1;
  112. enable(a);
  113. while(1)
  114. {
  115. if(*p == '\0')
  116. break;
  117. write(*p);
  118. p++;
  119. }
  120. }

    /********************************************************************

  121. * 名称 : Com_Int()
  122. * 功能 : 串口中断子函数
  123. * 输入 : 无
  124. * 输出 : 无
  125. ***********************************************************************/
  126. void Com_Int(void) interrupt 4
  127. {
  128. EA = 0;
  129. if(RI == 1) //当硬件接收到一个数据时,RI会置位
  130. {
  131. LED_Buffer[com_dat] = SBUF; //把从串口读出的数存到数组
  132. RI = 0; //标志位清0
  133. com_dat++;
  134. if(com_dat == 16)
  135. com_dat = 0; //当com_dat = 16时,清0,防止数组溢出
  136. }
  137. EA = 1;
  138. }

    /********************************************************************

  139. * 名称 : Com_Init()
  140. * 功能 : 串口初始化,晶振11.0592,波特率9600,使能了串口中断
  141. * 输入 : 无
  142. * 输出 : 无
  143. ***********************************************************************/
  144. void Com_Init(void)
  145. {
  146. TMOD = 0x20; //定时器工作在定时器1的方式2
  147. PCON = 0x00; //不倍频
  148. SCON = 0x50; //串口工作在方式1,并且启动串行接收
  149. TH1 = 0xFd; //设置波特率 9600
  150. TL1 = 0xFd;
  151. TR1 = 1; //启动定时器1
  152. ES = 1; //开串口中断
  153. EA = 1; //开总中断
  154. }

    void writedata()

  155. {
  156. uchar i = 0;
  157. uint j = 0;
  158. uchar code Buf1[] = "abcdefgh"; //所要发送的数据
  159. uchar *p;

    p = Buf1;

  160. while(1)
  161. {
  162. SBUF = *p;
  163. while(!TI) //如果发送完毕,硬件会置位TI
  164. {
  165. _nop_();
  166. }
  167. p++;
  168. if(*p == '\0')
  169. break; //在每个字符串的最后,会有一个'\0'
  170. TI = 0; //TI清零
  171. }
  172. }

    void Outside_Init(void)

  173. {
  174. EX0 = 1; //开外部中断0
  175. IT0 = 1; //负边沿触发
  176. EA = 1; //开总中断
  177. }

    void Outside_Int1(void) interrupt 0 using 1

  178. {
  179. if(K1 == 0)
  180. {
  181. Delay(2);
  182. if(K1 == 0)
  183. writedata();
  184. }
  185. }

    void Main()

  186. {
  187. uchar i = 0, com_dat = 0;
  188. L1602_init();
  189. Delay(100);
  190. Com_Init();
  191. Outside_Init();
  192. P2 = 0x00;
  193. while(1)
  194. {
  195. q = LED_Buffer;
  196. L1602_string(1,1,q);
  197. com_dat = 0;
  198. Delay(10);
  199. }
  200. }

回复评论

暂无评论,赶紧抢沙发吧
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复