C51系列指令集单片机通用软件模拟串口数据收发程序,无需调用硬件寄存器。
/*
C51系列指令集单片机通用软件模拟串口数据收发程序,无需调用硬件寄存器,通过CPU程序控制及检测IO口高低电平实现。
若单片机内部无串口收发相关特殊功能寄存器,只能使用此方法实现串口收发数据而实现与上位机通讯。
如需修改接收口位置需修改中断寄存器参数,该口必须支持下降沿中断。
延迟时间误差过大或过短或晶振频率过高可能会导致误码率增加。
若不支持下降沿中断请在死循环内循环检测接收口电平,若检测到低电平则处理数据接收程序。
上电先发送字符串:"Hello World!" (不含引号)。
若上位机发送字符串0 0的16进制ascii码是0x30,则返回0x30,空格的ascii码是0x20,则返回0x20,以此类推。
*/
#include"reg51.h" //定义头文件reg51.h
#include"intrins.h" //定义头文件intrins.h
unsigned char code hex={ //十六进制字符串数据
0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46
};
sbit rxd=P3^0; //数据接收口
sbit txd=P3^1; //数据发送口
sfr AUXR = 0x8E; //定义AUXR寄存器
sfr INT_CLKO = 0x8F; //定义下降沿中断寄存器
void delay_uart(){ //延时时间1除以波特率秒
unsigned char a,b;
for(b=3;b>0;b--)
for(a=94;a>0;a--);
}
void init_uart(){ //初始化串口
AUXR |= 0x80; //设置AUXR寄存器
INT_CLKO |= 0x40; //开串口中断 (允许串口接收数据)
EA = 1; //启用I/O口外部中断功能
}
void txd_data(unsigned char i){//发送数据
unsigned char j=1;//控制移位
unsigned char k=8;//控制循环次数
delay_uart();//延时时间
txd=0; //发送起始位,低电平
while(k--){ //下面循环8次
delay_uart();//延时时间
txd=(i&j)/j; //发送数据
j<<=1; //左移1位,发送下1位数据
}
delay_uart();//延时时间
txd=1;//发送停止位
}
unsigned char rxd_data(){ //接收数据
unsigned char j=1;//控制移位
unsigned char k=8;//控制循环次数
unsigned char d=0;//存放数据
while(rxd == 1); //等待起始位低电平
while(k--){//下面循环8次
delay_uart(); //延时时间
d|=(rxd*j); //存入数据
j<<=1;//左移1位,接收下1位数据
}
delay_uart();//延时时间
if(rxd == 1){ //停止位为高电平
return d; //返回数据
} else {
return 0; //无效数据 返回0
}
}
void send_text(unsigned char *text){ //发送字符串
for(;*text!=0;text++){//遇到停止符0结束发送
txd_data(*text); //发送数据
}
}
void exint4() interrupt 16{ //P3.0下降沿中断 (串口接收到数据)
unsigned char dat=0;//数据存放变量
INT_CLKO &= 0xBF;//关闭中断,避免重复触发中断程序。
dat=rxd_data(); //串口接收数据。
txd_data(0x30); //发送字符串 0
txd_data(0x78); //发送字符串 x
txd_data(hex[(dat&0xF0)/0x10]); //发送十六进制高4位
txd_data(hex); //发送十六进制低4位
txd_data(0x20); //发送空格
INT_CLKO |= 0x40; //开启中断,允许下次接收数据。
}
void main(){ //主函数
init_uart(); //初始化串口
send_text("Hello World!\r\n"); //发送字符串
while(1); //进入死循环
}
{:5_118:}没接触单片机,先暖(水)贴,顺便占个沙发。 我也没接触过,顶1个
页:
[1]