在單片機實際開發的過程中,可能會出現串口不夠用的情形。如果你需要更多的串口,又無奈於手頭沒有資源更豐富的單片機,那麼,軟件模擬串口通信也許可以幫到你。
軟件模擬串口通信的主要思想是通過定時器來定時產生相應的波特率。
#include<reg52.h>
sbit PIN_RXD = P3^0;
sbit PIN_TXD = P3^1;
bit RxdEnd = 0; //接收完成標誌
bit RxdOrTxd = 0; //RXD = 0,TXD = 1
bit TxdEnd = 0; //發送完成標誌
unsigned char RxdBuf = 0; //數據接收緩衝區
unsigned char TxdBuf = 0; //數據發送緩衝區
void ConfigUART(unsigned int baud); //配置串口
void StartRXD(); //開始接收
void StartTXD(unsigned char dat); //開始發送
void main()
{
EA = 1; //開總中斷
ConfigUART(9600); //波特率9600
while(1)
{
while(PIN_RXD); //檢測到起始位0進入下一步
StartRXD(); //開始接收
while(!RxdEnd);
StartTXD(RxdBuf+1);
while(!TxdEnd);
}
}
void ConfigUART(unsigned int baud)
{
TMOD &= 0xF0; //清除定時器低四位
TMOD |= 0x02; //定時器0, 模式2, 8位自動重裝載模式
TH0 = 256 - (11059200/12)/baud; //高位預裝載值
}
void StartRXD()
{
TL0 = 256 - ((256 - TH0)>>1);
ET0 = 1;
TR0 = 1;
RxdEnd = 0;
RxdOrTxd = 0;
}
void StartTXD(unsigned char dat)
{
TxdBuf = dat;
TL0 = TH0;
ET0 = 1;
TR0 = 1;
PIN_TXD = 0;
TxdEnd = 0;
RxdOrTxd = 1;
}
void InterruptTimer0() interrupt 1
{
static unsigned char cnt = 0; // 接收/發送 到第幾位計數
if(RxdOrTxd) //發送部分
{
cnt++;
if(cnt <= 8)
{
PIN_TXD = TxdBuf & 0x01; //每次發一位,從低位發起
TxdBuf >>= 1; //右移一位,次低位爲低位
}
else if(cnt == 9)
{
PIN_TXD = 1; //發送停止位
}
else
{
cnt = 0; //清除計數
TR0 = 0; //關閉定時器
TxdEnd = 1; //置發送完成標
}
}
else //接收部分
{
if(cnt == 0)
{
if(!PIN_RXD) //檢測到接收起始位0
{
RxdBuf = 0;
cnt++;
}
else
{
TR0 = 0;
}
}
else if(cnt <= 8)
{
RxdBuf >>= 1; //數據右移一位
if(PIN_RXD) //如果接收到的數據爲1,就或上0x80讓高位爲1
{
RxdBuf |= 0x80; //或0x80只會改變最高位,其他位都不變
}
cnt++;
}
else
{
cnt = 0;
TR0 = 0;
if(PIN_RXD) //檢測到接收停止位
{
RxdEnd = 1; //置接收完成標誌位
}
}
}
}