📄 swuart.c
字号:
// 数据定义: 定义模拟串口程序所必须的一些资源,如I/O引脚、波特率、数据缓冲区等。
#define Fosc 22118400 //晶振频率
#define Baud 38400 //波特率
#define BaudT (Fosc/Baud/3/12)
#define BufLong 16 //FIFO长度
sbit RxD1=P1^7; //模拟接收RxD
sbit TxD1=P1^6; //模拟发送TxD
bit Brxd1,Srxd1;//RxD检测电平
BYTE Rbuf1[BufLong];//FIFO接收区
BYTE Rptr1,Rnum1;
BYTE Tbuf1[BufLong];//FIFO发送区
BYTE Tptr1,Tnum1;
BYTE TimCnt1A,TimCnt1B;
BYTE Mtbuf1,Mrbuf1,TxdCnt1,RxdCnt1;
/*
数据接收子程序:
数据接收过程中,依次存储RxD的逻辑位形成字节数据,
当数据接收完毕且停止位为1时,表示接收到了有效数据,就将结果存储到接收FIFO队列中去。
*/
void Recv(){
if(RxdCnt1>0){ //存数据位8个
Mrbuf1>>=1;
if(RxD1==1) Mrbuf1=Mrbuf1|0x80;
}
RxdCnt1--;
if(RxdCnt1==0&& RxD1==1){ //数据接收完毕
Rbuf1[Rptr1]=Mrbuf1; //存储到FIFO队列
if(++Rptr1>BufLong-1) Rptr1=0;
if(++Rnum1>BufLong) Rnum1=BufLong;
}
}
/*
数据发送子程序:
该程序过程中,当数据发送状态结束时,检测发送FIFO队列是否为空,
若非空则取出发送数据,然后启动发送状态;
当处于发送状态时,则按照状态机的状态进行起始位、数据位和停止位的发送。
*/
void Send(){
if(TxdCnt1!=0){ //字节发送状态机
if(TxdCnt1==11) TxD1=0; //发起始位0
else if(TxdCnt1>2){ //发数据位
Mtbuf1>>=1; TxD1=CY;
}
else TxD1=1; //发终止位1
TxdCnt1--;
}
else if(Tnum1>0){ //检测FIFO队列
Tnum1--;
Mtbuf1=Tbuf1[Tptr1]; //读取FIFO数据
if(++Tptr1>=BufLong) Tptr1=0;
TxdCnt1=11; //启动发送状态机
}
}
/*
中断程序
中断定时时间为波特率定时的1/3,即以3倍的波特率对RxD进行采样,实现起始位的判别,当起始位到达时启动接收过程状态机。
将该定时进行3分频再调用数据的发送和接收过程,进行准确波特率下的串口通信。
*/
void Uart() interrupt 1 using 1{
if(RxdCnt1==0 ){ //接收起始识别
if(RxD1==0 && Brxd1==0 && Srxd1==1) { RxdCnt1=8; TimCnt1B=0;}
}
Srxd1=Brxd1; Brxd1=RxD1;
if(++TimCnt1B>=3 && RxdCnt1!=0) { TimCnt1B=0; Recv();}//数据接收
if(++TimCnt1A>=3) { TimCnt1A=0; Send();} //数据发送
}
/*
串口初始化:
打开定时器的中断,将定时器的设置为自装载模式,依照波特率设置定时中断的定时间隔,启动定时器,并进行UART各变量的初始化。
*/
void IniUart(){
IE="0x82"; TMOD="0x22";
TH0=-BaudT; TL0=-BaudT; TR0=1;
Rptr1=0;Rnum1=0;Tptr1=0;Tnum1=0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -