立即注册 登录
返回首页

uid:90541的个人空间

日志

51模拟串口

热度 1已有 463 次阅读2015-9-19 17:21 |个人分类:51

#include <reg51.h>   
       
    #define uchar unsigned char   
    #define uint    unsigned int   
       
    sbit Tx_Pin = P1^1;   
    sbit Rx_Pin = P1^2;         //定义接收、发送引脚   
       
    /*******************************************  
    I/O口模拟232通讯程序  
    使用两种方式的C程序 占用定时器0  
      
    /******************************************/   
       
    #define MODE                                                    //定义工作模式,决定使用哪种算法   
    #define Flg F0                                              //标志位,使用PSW的F0位   
    #define Start_Timer0 TL0=TH0;TR0=1;     //定时计数器0的启动处理   
    #define Close_Timer0 TR0=0;                     //定时计数器0的关闭处理   
       
    sbit ACC0 = ACC^0;   
    sbit ACC1 = ACC^1;   
    sbit ACC2 = ACC^2;   
    sbit ACC3 = ACC^3;   
    sbit ACC4 = ACC^4;   
    sbit ACC5 = ACC^5;   
    sbit ACC6 = ACC^6;   
    sbit ACC7 = ACC^7;   
       
    void Timer0() interrupt 1                           //定时计数器中断处理   
    {   
        Flg = 1;                                                        //置位标志位   
    }   
       
    //发送一个字符   
    void SendByte(uchar adata)   
    {   
        #ifdef MODE                                                 //算法一   
            ACC = adata;                                                //待发送数据放入ACC   
            Flg = 0;   
            Tx_Pin = 0;                                             //启动位   
            Start_Timer0;                                           //启动定时器   
            while(!Flg)   
                ;   
            Tx_Pin = ACC0;                                      //先送出低位   
            Flg = 0;   
            while(!Flg)   
                ;   
            Tx_Pin = ACC1;   
            Flg = 0;   
            while(!Flg)   
                ;   
            Tx_Pin = ACC2;   
            Flg = 0;   
            while(!Flg)   
                ;   
            Tx_Pin = ACC3;   
            Flg = 0;   
            while(!Flg)   
                ;   
            Tx_Pin = ACC4;   
            Flg = 0;   
            while(!Flg)   
                ;   
            Tx_Pin = ACC5;   
            Flg = 0;   
            while(!Flg)   
                ;   
            Tx_Pin = ACC6;   
            Flg = 0;   
            while(!Flg)   
                ;   
            Tx_Pin = ACC7;   
            Flg = 0;   
            while(!Flg)                                             //停止位   
                ;   
            Tx_Pin = 1;   
            Flg = 0;   
            while(!Flg)   
                ;   
            Close_Timer0;                                           //停止定时计数器   
        #else                                                               //第二种算法   
        uchar j;   
        j = 0;                                                             
        Flg = 0;                                                        //初始化   
        Tx_Pin = 0;                                                 //起始位   
        Start_Timer0;                                               //启动定时计数器   
        while(!Flg)   
            ;   
        while(j<8)                                                   //如果没有发送完一个字节   
        {   
            if(adata&1)                                             //如果待发送位是1   
            {   
                Tx_Pin = 1;   
            }   
            else                                                            //如果待发送位是0   
            {   
                Tx_Pin = 0;   
            }   
            Flg = 0;   
            while(!Flg)   
                ;   
            j++;   
            adata>>=1;                                                    //移位   
        }   
        Tx_Pin = 1;   
        Flg = 0;   
        while(!Flg)                                                 //停止发送   
            ;      
        #endif   
        Close_Timer0;                                               //停止定时计数器   
    }   
       
    //接收一个字符       
           
    uchar RecByte()   
    {   
        #ifdef MODE                                                 //算法一   
        Start_Timer0;   
        Flg = 0;   
        while(!Flg)                                                 //等待起始位   
            ;   
        ACC0 = Rx_Pin;                                          //接收一位数据   
        TL0 = TH0;   
        Flg = 0;   
        while(!Flg)   
            ;   
        ACC1 = Rx_Pin;   
        Flg = 0;   
        while(!Flg)   
            ;   
        ACC2 = Rx_Pin;   
        Flg = 0;   
        while(!Flg)   
            ;   
        ACC3 = Rx_Pin;   
        Flg = 0;   
        while(!Flg)   
            ;   
        ACC4 = Rx_Pin;   
        Flg = 0;   
        while(!Flg)   
            ;   
        ACC5 = Rx_Pin;   
        Flg = 0;   
        while(!Flg)   
            ;   
        ACC6 = Rx_Pin;   
        Flg = 0;   
        while(!Flg)   
            ;   
        ACC7 = Rx_Pin;   
        Flg = 0;   
        while(!Flg)                                                 //等待停止位   
        {   
            if(Rx_Pin)   
            {   
                break;   
            }   
        }   
        Close_Timer0;                                               //停止timer    
        return ACC;                                                 //函数返回值通过ACC寄存器传递   
        #else                                                               //第二种算法   
        uchar Rx_Data, j;   
        Start_Timer0;   
        Flg = 0;   
        j = 0;   
        Rx_Data = 0;                                                //等待起始位   
        while(!Flg)                                                    
            ;   
        while(j<8)   
        {   
            Rx_Data>>=1;   
            if(Rx_Pin)   
            {   
                Rx_Data |= 0x80;                                //判断引脚电平   
            }   
            j++;   
            Flg = 0;   
            while(!Flg)   
                ;   
        }   
        Flg = 0;   
        while(!Flg)   
        {   
            if(Rx_Pin)   
            {   
                break;   
            }   
        }   
        Close_Timer0;                                               //停止定时计数器   
        return Rx_Data;   
        #endif   
    }   
           
    //检查是不是起始位   
    bit CheckStartBit()   
    {   
        return (Rx_Pin == 0);                               //返回引脚状态   
    }   
       
    void main()   
    {   
        uchar temp;   
        TMOD = 0x02;                                                //定时器0 模式2 8位重装   
        PCON = 0x00;   
        TR0 = 0;                                                            //在发送或接收才开始使用   
        TH0 = (256.96);                                            
        //9600bps 就是1000000/9600=104.167us 执行时间即是104.167*10.0592/12=96   
        TL0 = TH0;   
        ET0 = 1;   
        EA = 1;   
        SendByte(0x55);   
        SendByte(0xaa);   
        SendByte(0x00);   
        SendByte(0xff);                                         //发送数据   
        while(1)   
        {   
            if(CheckStartBit())                             //如果检测到起始位   
            {   
                temp = RecByte();                               //接收数据   
                SendByte(temp);                                 //发送数据   
            }   
        }   
    }   


1

路过

鸡蛋

鲜花

握手

雷人

刚表态过的朋友 (1 人)

评论 (0 个评论)

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

返回顶部