串口通信程序

要求:让两台单片机能相互通信,这台单片机按下在键盘能在另一台单片机上在数码管显示。

链接线:将一台单片机在P3.0(RXD)接到另一台单片机在P3.1(TXD),还有这台在P3.1接到另一台在P3.0,还有将两台单片机在GND相连。

  1 #include <reg51.h>
  2 #define LEDLen 6
  3 
  4 xdata unsigned char OUTBIT _at_ 0x8002;   // 位控制口
  5 xdata unsigned char OUTSEG _at_ 0x8004;   // 段控制口
  6 xdata unsigned char IN     _at_ 0x8001;   // 键盘读入口
  7 
  8 unsigned char LEDBuf[LEDLen];  // 显示缓冲
  9 unsigned char RcvBuf;          // 接收缓冲
 10 bit HasRcv = 0;                // 接收标志
 11 
 12 code unsigned char LEDMAP[] = {  // 八段管显示码
 13   0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07,
 14   0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71
 15 };
 16 
 17 void SerialIO0() interrupt 4
 18 {
 19 
 20   if(RI)
 21   {
 22     RI = 0;
 23     RcvBuf = SBUF;
 24     HasRcv = 1;
 25   }else
 26   {
 27     TI = 0;
 28   }
 29 }
 30 
 31 void Delay(unsigned char CNT)
 32 {
 33   unsigned char i;
 34 
 35   while (CNT-- !=0)
 36     for (i=100; i !=0; i--);
 37 }
 38 
 39 void DisplayLED()
 40 {
 41   unsigned char i, j;
 42   unsigned char Pos;
 43   unsigned char LED;
 44 
 45   Pos = 0x20;  // 从左边开始显示
 46   for (i = 0; i < LEDLen; i++) {
 47     OUTBIT = 0;     // 关所有八段管
 48     LED = LEDBuf[i];
 49     OUTSEG = LED;
 50     OUTBIT = Pos;  // 显示一位八段管
 51     Delay(1);
 52     Pos >>= 1;     // 显示下一位
 53   }
 54 }
 55 
 56 code unsigned char KeyTable[] = {   // 键码定义
 57   0x16, 0x15, 0x14, 0xff,
 58   0x13, 0x12, 0x11, 0x10,
 59   0x0d, 0x0c, 0x0b, 0x0a,
 60   0x0e, 0x03, 0x06, 0x09,
 61   0x0f, 0x02, 0x05, 0x08,
 62   0x00, 0x01, 0x04, 0x07
 63 };
 64 
 65 unsigned char TestKey()
 66 {
 67    OUTBIT = 0;            // 输出线置为0
 68    return (~IN & 0x0f);   // 读入键状态 (高四位不用)
 69 }
 70 
 71 unsigned char GetKey()
 72 {
 73   unsigned char Pos;
 74   unsigned char i;
 75   //unsigned char j;
 76   unsigned char k;
 77 
 78   i = 6;
 79   Pos = 0x20;     // 找出键所在列
 80   do {
 81     OUTBIT = ~ Pos;
 82     Pos >>= 1;
 83     k = ~IN & 0x0f;
 84   } while ((--i != 0) && (k == 0));
 85 
 86   // 键值 = 列 X 4 + 行
 87   if (k != 0) {
 88     i *= 4;
 89     if (k & 2)
 90       i += 1;
 91     else if (k & 4)
 92       i += 2;
 93     else if (k & 8)
 94       i += 3;
 95 
 96     OUTBIT = 0;
 97     do Delay(10); while (TestKey());  // 等键释放
 98 
 99     return(KeyTable[i]);  // 取出键码
100   } else return(0xff);
101 }
102 
103 void main()
104 {
105     IE =   0x00;  // DISABLE ALL INTERRUPT
106     TMOD = 0x20;  // 定时器1工作于方式2 (8位重装)
107     TH1  = 0xF3;  // 2400BPS @ 12MHz
108     TL1  = 0xF3;
109     PCON&= 0x7F;  // SMOD 位清零
110     SCON = 0x50;  // 串行口工作方式设置
111 
112 
113    LEDBuf[0] = 0xff;
114    LEDBuf[1] = 0xff;
115    LEDBuf[2] = 0xff;
116    LEDBuf[3] = 0xff;
117    LEDBuf[4] = 0x00;
118    LEDBuf[5] = 0x00;
119 
120    TR1 = 1;
121    ES  = 1;
122    EA  = 1;
123    HasRcv = 0;
124 
125    while (1) {
126      if(HasRcv){
127        LEDBuf[5] = LEDMAP[RcvBuf & 0x0f];
128      }
129      DisplayLED();
130      if (TestKey()) SBUF = GetKey();
131    }
132 }

结果:会发现按下这台单片机在键盘码会在另一台单片机在数码管显示出来。

友情提醒:可以先在一台单片机上测试一下程序是否有效,将本机在P3.1和P3.0链接起来看看按本机在键盘能否在本机在数码管上显示值。

原文地址:https://www.cnblogs.com/dingxiaowei/p/3100928.html