最近因工作需要,研究了一下单片机IO口模拟串口通讯的相关知识。相关内容主要参考了网上《51单片机模拟串口的三种方法》和《单片机IO口模拟串口程序(发送+接收)》两篇文档,并动手做了一下实验。感受颇多。
硬件环境:STC89C52
软件环境:IDE Keil uVision V4.10
编译器 C51 V9.0
代码如下:
/********************************************** 方法1:延时法 硬件:11.0592MHz晶振,STC89C52,RXD P1.0 TXD P1.1 波特率:9600 描述:所谓延时法是指根据模拟出的波特率,每1位持续的时间的长短是通过循环空指令来延时的。 测试1:上电发送1个0x01的字符 测试2:上电后等待接收,接收到PC发送的0x01字符后,将此字符+1后再发送 结果: 测试1:正确!接收到1个0x01的字符 测试2-1:正确!分别一个一个发送0x01,0x02,0x03,0x04,0x05,均正常接收 测试2-2: 错误!一起发送0x01,0x02,0x03,0x04,0x05,丢包,只能接收0x02,0x04,0x06 时间:2012.07.25 于单位 **********************************************/ #include "reg52.h" #define uchar unsigned char sbit P1_0 = 0x90; sbit P1_1 = 0x91; sbit P1_2 = 0x92; #define RXD P1_0 #define TXD P1_1 #define WRDYN 44 //写延时 #define RDDYN 43 //读延时 void Delay2cp(unsigned char i); //往串口写一个字节 void WByte(uchar input) { uchar i=8; TXD=(bit)0; //发送启始位 Delay2cp(39); //发送8位数据位 while(i--) { TXD=(bit)(input&0x01); //先传低位 Delay2cp(36); input=input>>1; } //发送校验位(无) TXD=(bit)1; //发送结束位 Delay2cp(46); } //从串口读一个字节 uchar RByte(void) { uchar Output=0; uchar i=8; uchar temp=RDDYN; //发送8位数据位 Delay2cp(RDDYN*1.5); //此处注意,等过起始位 while(i--) { Output >>=1; if(RXD) Output |=0x80; //先收低位 Delay2cp(35); //(96-26)/2,循环共占用26个指令周 } while(--temp) //在指定的时间内搜寻结束位。 { Delay2cp(1); if(RXD)break; //收到结束位便退 } return Output; } //延时程序* void Delay2cp(unsigned char i) { while(--i); //刚好两个指令周期。 } void main() { uchar ccc; //测试1 //WByte(0x01); //while(1){;} //测试2 while(1) { if(RXD==0) { ccc=RByte(); WByte(ccc+1); } } }
附几张抓到的波形:
测试1:十六进制字符0x01的波形
测试1:发送出来的字符
测试2:依次发送0x01,0x02,0x03,0x04,0x05接收到的字符
测试2:一起发送0x01,0x02,0x03,0x04,0x05字符
结论:发送和接收字符均正常,没加缓冲,大数据量未测试。