LscmunaixMG 发表于 2017-6-4 21:48:10

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); //进入死循环



}


demon 发表于 2017-7-3 19:40:59

{:5_118:}没接触单片机,先暖(水)贴,顺便占个沙发。

66大顺 发表于 2017-9-17 14:00:40

我也没接触过,顶1个
页: [1]
查看完整版本: C51系列指令集单片机通用软件模拟串口数据收发程序,无需调用硬件寄存器。