发一个51单片机的模拟串口代码

由于8位单片机一般只有一个串行接口,往往不够用,只能自己写一个模拟串口的程序,下面这个程序是自己早先写的,放上来,对别人也许有点用,注意接收端同时接到P3.2(INT0)

#include <at89X52.h>
#define DOUBLE_BAUDRATE

#define DATA_CORRUPT 0x80
#define BUFFER_OVERFLOW  0x81

#define F_OSC    11059200

#define BAUDRATE 9600 //115200//57600//19200//9600

#define BAUDRATE_CONST (256 - F_OSC/12/BAUDRATE)

#define HALF_BAUDRATE (256 - F_OSC/12/BAUDRATE/2)

#define DELAY_TIME 50;//ms
#define DELAY_CONST (DELAY_TIME/1000 * F_OSC)/12


#define DISABLE_RECEIVE() EX0 = 0;
#define ENABLE_RECEIVE() EX0 = 1;

#define RXD P1_2
#define TXD P1_3

char idata buffer[32] ;

unsigned char bdata DataBuf;
sbit DataBuf_0 = DataBuf ^ 0;
sbit DataBuf_1 = DataBuf ^ 1;
sbit DataBuf_2 = DataBuf ^ 2;
sbit DataBuf_3 = DataBuf ^ 3;
sbit DataBuf_4 = DataBuf ^ 4;
sbit DataBuf_5 = DataBuf ^ 5;
sbit DataBuf_6 = DataBuf ^ 6;
sbit DataBuf_7 = DataBuf ^ 7;

void send(char len,char * buf)
{
    char i,j;
    i=j=0;
    DISABLE_RECEIVE();

    TMOD |= 0x02;//MODE 3
    TL0 = BAUDRATE_CONST;//0x40;
    TH0 = BAUDRATE_CONST;//0x40;
    
    while(i<len)//for(i=0;i<len;i++)
    {
        DataBuf = buf[i];
        TL0 = BAUDRATE_CONST;
        TH0 = BAUDRATE_CONST;    
          TR0 = 1;

      TXD = 0;//send start bit
      //nop
      while(!TF0);
      TF0 = 0;

      TXD = DataBuf_0;//send bit 0
      while(!TF0);
      TF0 = 0;

      TXD = DataBuf_1;//send bit 1
      while(!TF0);
      TF0 = 0;

      TXD = DataBuf_2;//send bit 2
      while(!TF0);
      TF0 = 0;

      TXD = DataBuf_3;//send bit 3
      while(!TF0);
      TF0 = 0;

      TXD = DataBuf_4;//send bit 4
      while(!TF0);
      TF0 = 0;
      
      TXD = DataBuf_5;//send bit 5
      while(!TF0);
      TF0 = 0;
      
      TXD = DataBuf_6;//send bit 6
      while(!TF0);
      TF0 = 0;
      
      TXD = DataBuf_7;//send bit 7
      while(!TF0);
      TF0 = 0;
      
        TXD = 1;//send end bit 8
        while(!TF0);
        TF0 = 0;
        
        TR0 =0;//stop timer0
        i++;//next byte
    }

    ENABLE_RECEIVE();
}

unsigned char bdata DataBuf;
unsigned char LastError;
char recv_len;
void exint0_receive (void) interrupt 0 using 2  
{
    DISABLE_RECEIVE();
    TMOD |= 0x02;
    TL0 = HALF_BAUDRATE;
    TH0 = BAUDRATE_CONST;
        
    TR0 = 1; //start timer0
    
    while(!TF0); //delay 1/2 bit time to go to middle of start bit 
    TF0 = 0;
    if(RXD == 1)
    {
        ENABLE_RECEIVE();
        return;
    }
    while(!TF0);//receive data bit 0
    TF0 = 0;
    DataBuf_0 = RXD;

    while(!TF0);//receive data bit 1
    TF0 = 0;
    DataBuf_1 = RXD;
    
    while(!TF0);//receive data bit 2
    TF0 = 0;
    DataBuf_2 = RXD;

    while(!TF0);//receive data bit 3
    TF0 = 0;
    DataBuf_3 = RXD;

    while(!TF0);//receive data bit 4
    TF0 = 0;
    DataBuf_4 = RXD;

    while(!TF0);//receive data bit 5
    TF0 = 0;
    DataBuf_5 = RXD;

    while(!TF0);//receive data bit 6
    TF0 = 0;
    DataBuf_6 = RXD;

    while(!TF0);//receive data bit 7
    TF0 = 0;
    DataBuf_7 = RXD;

    while(!TF0);//receive end bit 
    TF0 = 0;
    
    if(RXD != 1)
    {
        LastError = 1;
        ENABLE_RECEIVE();
        return ;
    }
    TR0 = 0;//stop timer
     
    if(recv_len >=32)
    {
        LastError = BUFFER_OVERFLOW;
        ENABLE_RECEIVE();
        return;
                
    }
    buffer[recv_len++] = DataBuf;

    ENABLE_RECEIVE();
}

void InitSimuSerial()
{
    TMOD |= 0x02;
    TL0 = HALF_BAUDRATE; //wait at 
    TH0 = BAUDRATE_CONST;
    
    IT0 = 1;
    EX0 = 1;
}

void main()
{
    P0 = 0xff;
    P1 = 0xff;
    P2 = 0xff;
    P3 = 0xff;
    InitSimuSerial();
    EA = 1;
    while(1)
    {
        if(recv_len >0)
        {
            send(recv_len,buffer);
            recv_len = 0;
        }
    } 
}
--------------------- 
作者:i2cbus 
来源:CSDN 
原文:https://blog.csdn.net/I2Cbus/article/details/2901799 
版权声明:本文为博主原创文章,转载请附上博文链接!

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值