串口通信程序
要求:让两台单片机能相互通信,这台单片机按下在键盘能在另一台单片机上在数码管显示。
链接线:将一台单片机在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链接起来看看按本机在键盘能否在本机在数码管上显示值。
版权声明:本文为dingxiaowei原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。