51单片机串口通信(UART)

Dear 丶 2022-01-23 05:59 474阅读 0赞

项目描述:
1.串口工作方式为1(8位UART,波特率可变),无校验位;
2.通信数据格式为:1位起始位 + 8位数据位 + 1位停止位;
3.上电后MCU给上位机发送问候语,之后等待上位机的信息;MCU和上位机的通信为收发交替进行。MCU接收到的信息会实时的显示在LCD上。上位机接收到的信息会在串口助手上显示。
C语言程序如下:

  1. /*-----------------------
  2. FileName: UART.h
  3. Function: 头文件
  4. Author: Zhang Kaizhou
  5. Date: 2019-6-10 11:33:35
  6. ------------------------*/
  7. #include "reg52.h"
  8. #include <string.h>
  9. #define uchar unsigned char
  10. #define uint unsigned int
  11. #define FOSC 11059200L // 系统晶振频率为11.0592MHz
  12. #define BAUD 9600 // 波特率位9600bps
  13. #define MAXSIZE 8
  14. /*LCD1602显示模块端口定义*/
  15. sbit lcdrs = P1^0;
  16. sbit lcdrw = P1^1;
  17. sbit lcden = P2^5;
  18. /*主模块函数声明*/
  19. void timer1Init();
  20. void sendChar(uchar dat);
  21. void sendString(char * str);
  22. /*LCD1602模块函数声明*/
  23. void writeCommand(uchar command);
  24. void writeData(uchar dat);
  25. void delay(uchar xms);
  26. void LCDInit();
  27. void display(uchar * str);
  28. /*--------------------------------------------
  29. FileName: main.c
  30. Function: 实现单片机与上位机的串口异步通信
  31. Description: 上电后MCU给上位机发送问候语,
  32. 之后等待上位机的信息;MCU和上位机的通信为收发
  33. 交替进行。MCU接收到的信息会实时的显示在LCD上。
  34. 上位机接收到的信息会在串口助手上显示。
  35. ----------------------------------------------
  36. Author: Zhang Kaizhou
  37. Date: 2019-6-10 11:16:29
  38. --------------------------------------------*/
  39. #include "UART.h"
  40. uchar code table3[] = {"Hello, I am ZKZ!\r\n"};
  41. uchar code table4[] = {"I get it!\r\n"};
  42. uchar info[MAXSIZE] = { 0 }; // 通信信息
  43. uchar count = 0; // 接收到的字符个数
  44. uchar temp = 0;
  45. bit busy = 0; // 串口忙标志
  46. /*主函数*/
  47. void main(){
  48. LCDInit();
  49. timer1Init();
  50. sendString(table3);
  51. while(1){
  52. if(count == MAXSIZE){
  53. count = 0;
  54. sendString(table4);
  55. display(info);
  56. }
  57. }
  58. }
  59. /*定时器1用作波特率发生器*/
  60. void timer1Init(){
  61. SM0 = 0; SM1 = 1; // 设置串口为8位UART
  62. REN = 1; // 允许串口接收数据
  63. TMOD = 0x20; // 设置timer1为8位自动重装初值的定时器
  64. PCON = 0x00; // SMOD = 0
  65. TH1 = 0xfd; // 装初值,可通过查表求得
  66. TL1 = 0xfd;
  67. TR1 = 1; // 启动定时器1
  68. ES = 1; // 开串口中断
  69. EA = 1; // 开全局中断
  70. }
  71. /*串口中断服务程序*/
  72. void uartService() interrupt 4{
  73. if (RI){ // 串口接收结束
  74. info[count++] = SBUF; // 将接收到的数据从串口缓存中取出放到info中
  75. RI = 0; // 串口接收标志软件复位
  76. }
  77. if (TI){ // 串口发送结束
  78. TI = 0; // 软件复位串口发送中断标志
  79. busy = 0;
  80. }
  81. }
  82. /*向串口发送一个字符的函数*/
  83. void sendChar(uchar dat){
  84. while (busy); // 等待串口空闲
  85. temp = dat;
  86. busy = 1;
  87. SBUF = temp;
  88. }
  89. /*向串口发送一个字符串的函数*/
  90. void sendString(char * str){
  91. while (* str){
  92. sendChar(*str++);
  93. }
  94. }
  95. /*-----------------------------
  96. FileName:display.c
  97. Function: LCD1602显示函数
  98. Author: Zhang Kaizhou
  99. Date: 2019-6-7 13:52:11
  100. ------------------------------*/
  101. #include "UART.h"
  102. uchar code table0[] = {"Welcome here!"};
  103. uchar code table1[] = {"This is UART!"};
  104. uchar code table2[] = {"Too long!"};
  105. uchar num = 0;
  106. /*初始化LCD1602的设置*/
  107. void LCDInit(){
  108. uchar i;
  109. lcden = 0; // 拉低使能端,准备产生使能高脉冲信号
  110. writeCommand(0x38); // 显示模式设置(16x2, 5x7点阵,8位数据接口)
  111. writeCommand(0x0c); // 开显示,不显示光标
  112. writeCommand(0x06); // 写一个字符后地址指针自动加1
  113. writeCommand(0x01); // 显示清零,数据指针清零
  114. /*LCD上电界面*/
  115. writeCommand(0x80); // 将数据指针定位到第一行首
  116. for(i = 0; i < strlen(table0); i++){
  117. writeData(table0[i]);
  118. delay(5);
  119. }
  120. writeCommand(0x80 + 0x40); // 将数据指针定位到第二行首
  121. for(i = 0; i < strlen(table1); i++){
  122. writeData(table1[i]);
  123. delay(5);
  124. }
  125. }
  126. /*LCD显示函数*/
  127. void display(uchar * str){
  128. uchar i;
  129. writeCommand(0x01); // 清屏
  130. writeCommand(0x80);
  131. for(i = 0; i < MAXSIZE; i++){
  132. writeData(str[i]);
  133. delay(5);
  134. }
  135. }
  136. /*写指令函数*/
  137. void writeCommand(uchar command){
  138. lcdrs = 0; // 命令选择
  139. lcdrw = 0;
  140. P0 = command;
  141. delay(5);
  142. lcden = 1; // 产生一个正脉冲使能信号
  143. delay(5);
  144. lcden = 0;
  145. }
  146. /*写数据函数*/
  147. void writeData(uchar dat){
  148. lcdrs = 1; // 数据选择
  149. lcdrw = 0;
  150. P0 = dat;
  151. delay(5);
  152. lcden = 1;
  153. delay(5);
  154. lcden = 0;
  155. }
  156. /*延时函数*/
  157. void delay(uchar xms){
  158. uint i, j;
  159. for(i = xms; i > 0; i--)
  160. for(j = 110; j > 0; j--);
  161. }

实现效果:
单片机每接收到一个来自上位机的字符串(规定长度为8个字符),就会向上位机发送一个应答语”I get it!”。
上位机会通过串口助手向单片机循环发送”12345678”,“abcdefgh”,”ijklmnop”三个字符串,单片机接收到后会显示在LCD上。
在这里插入图片描述

发表评论

表情:
评论列表 (有 0 条评论,474人围观)

还没有评论,来说两句吧...

相关阅读

    相关 51单片机串口通信(UART)

    项目描述: 1.串口工作方式为1(8位UART,波特率可变),无校验位; 2.通信数据格式为:1位起始位 + 8位数据位 + 1位停止位; 3.上电后MCU给上位机