1、前一阵一直在做单片机的程序,由于串口不够,需要用IO口来模拟出一个串口。经过若干曲折并参考了一些现有的资料,基本上完成了。现在将完整的测试程序,以及其中一些需要总结的部分贴出来。程序硬件平台:11.0592M晶振,STC单片机(兼容51)/* 在单片机上模拟了一个串口,使用P2.1作为发送端* 把单片机中存放的数据通过P2.1作为串口TXD发送出去*/#include #include #include typedef unsigned char uchar;int i;uchar code info = 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55
2、,0x55,0x55,0x55,0x55,0x55,0x55;sbit newTXD = P21;/模拟串口的发送端设为P2.1void UartInit() SCON = 0x50; / SCON: serail mode 1, 8-bit UART TMOD |= 0x21; / T0工作在方式1,十六位定时 PCON |= 0x80; / SMOD=1; TH0 = 0xFE; / 定时器0初始值,延时417us,目的是令模拟串口的波特率为2400bps fosc=11.0592MHz TL0 = 0x7F; / 定时器0初始值,延时417us,目的是令模拟串口的波特率为2400bps
3、fosc=11.0592MHz/ TH0 = 0xFD; / 定时器0初始值,延时417us,目的是令模拟串口的波特率为2400bps fosc=18.432MHz/ TL0 = 0x7F; / 定时器0初始值,延时417us,目的是令模拟串口的波特率为2400bps fosc=18.432MHzvoid WaitTF0(void) while(!TF0); TF0=0; TH0=0xFE; / 定时器重装初值 fosc=11.0592MHz TL0=0x7F; / 定时器重装初值 fosc=11.0592MHz / TH0 = 0xFD; / 定时器重装初值 fosc=18.432MHz /
4、 TL0 = 0x7F; / 定时器重装初值 fosc=18.432MHzvoid WByte(uchar input) /发送启始位 uchar j=8; TR0=1; newTXD=(bit)0; WaitTF0(); /发送8位数据位 while(j-) newTXD=(bit)(input&0x01); /先传低位 WaitTF0(); input=input1; /发送校验位(无) /发送结束位 newTXD=(bit)1; WaitTF0(); TR0=0; void Sendata() for(i=0;isizeof(info);i+)/外层循环,遍历数组 WByte(infoi
5、); void main() UartInit(); while(1) Sendata(); #/* 模拟接收程序,这个程序的作用从模拟串口接收数据,然后将这些数据发送到实际串口* 在单片机上模拟了一个串口,使用P3.2作为发送和接收端* 以P3.2模拟串口接收端,从模拟串口接收数据发至串口*/#include#include#includetypedef unsigned char uchar ;/这里用来切换晶振频率,支持11.0592MHz和18.432MHz/#define F18_432#define F11_0592 uchar tmpbuf264=0;/用来作为模拟串口接收数据的
6、缓存struct uchar recv :6 ;/tmpbuf2数组下标,用来将模拟串口接收到的数据存放到tmpbuf2中 uchar send :6 ;/tmpbuf2数组下标,用来将tmpbuf2中的数据发送到串口tmpbuf2_point=0,0;sbit newRXD=P32 ;/模拟串口的接收端设为P3.2void UartInit() SCON=0x50 ;/ SCON: serail mode 1, 8-bit UART TMOD|=0x21 ;/ TMOD: timer 1, mode 2, 8-bit reload,自动装载预置数(自动将TH1送到TL1);T0工作在方式1,
7、十六位定时 PCON|=0x80 ;/ SMOD=1; #ifdef F11_0592 TH1=0xE8 ;/ Baud:2400 fosc=11.0592MHz 2400bps为从串口接收数据的速率 TL1=0xE8 ;/ 计数器初始值,fosc=11.0592MHz 因为TH1一直往TL1送,所以这个初值的意义不大 TH0=0xFF ;/ 定时器0初始值,延时208us,目的是令模拟串口的波特率为9600bps fosc=11.0592MHz TL0=0xA0 ;/ 定时器0初始值,延时208us,目的是令模拟串口的波特率为9600bps fosc=11.0592MHz #endif #i
8、fdef F18_432 TH1=0xD8 ; / Baud:2400 fosc=18.432MHz 2400bps为从串口接收数据的速率 TL1=0xD8 ; / 计数器初始值,fosc=18.432MHz 因为TH1一直往TL1送,所以这个初值的意义不大 TH0=0xFF ;/ 定时器0初始值,延时104us,目的是令模拟串口的波特率为9600bps fosc=18.432MHz TL0=0x60 ;/ 定时器0初始值,延时104us,目的是令模拟串口的波特率为9600bps fosc=18.432MHz #endif IE|=0x81 ;/ 中断允许总控制位EA=1;使能外部中断0 TF
9、0=0 ; IT0=1 ;/ 设置外部中断0为边沿触发方式 TR1=1 ;/ 启动TIMER1,用于产生波特率void WaitTF0(void) while(!TF0); TF0=0 ; #ifdef F11_0592 TH0=0xFF ;/ 定时器重装初值 模拟串口的波特率为9600bps fosc=11.0592MHz TL0=0xA0 ;/ 定时器重装初值 模拟串口的波特率为9600bps fosc=11.0592MHz #endif #ifdef F18_432 TH0=0xFF ; / 定时器重装初值 fosc=18.432MHz TL0=0x60 ; / 定时器重装初值 fosc
10、=18.432MHz #endif /接收一个字符uchar RByte() uchar Output=0 ; uchar i=8 ; TR0=1 ; /启动Timer0 #ifdef F11_0592 TH0=0xFF ;/ 定时器重装初值 模拟串口的波特率为9600bps fosc=11.0592MHz TL0=0xA0 ;/ 定时器重装初值 模拟串口的波特率为9600bps fosc=11.0592MHz #endif #ifdef F18_432 TH0=0xFF ;/ 定时器重装初值 fosc=18.432MHz TL0=0x60 ;/ 定时器重装初值 fosc=18.432MHz
11、#endif TF0=0 ; WaitTF0();/等过起始位 /接收8位数据位 while(i-) Output=1 ; if(newRXD)Output|=0x80 ;/先收低位 WaitTF0();/位间延时 TR0=0 ;/停止Timer0 return Output ;/向COM1发送一个字符void SendChar(uchar byteToSend) SBUF=byteToSend ; while(!TI); TI=0 ;void main() UartInit(); while(1) if(tmpbuf2_point.recv!=tmpbuf2_point.send)/差值表示模拟串口接收数据缓存中还有多少个字节的数据未被处理(发送至串口) SendChar(tmpbuf2tmpbuf2_point.send+); /外部中断0,说明模拟串口的起始位到来了void Simulated_Serial_Start()interrupt 0 EX0=0 ; /屏蔽外部中断0 tmpbuf2tmpbuf2_point.recv+=RByte(); /从模拟串口读取数据,存放到tmpbuf2数组中 IE0=0 ; /防止外部中断
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1