STC8单片机IO口简单模拟串行通信

   我们都知道如何使用系统配置的串口初始化函数去使用我们的串口,就是只能使用固定的引脚去进行串行通信,就是下面这种方法,

STC8单片机IO口简单模拟串行通信_第1张图片

   如果想要使用其他的引脚来进行串行通信,就不可以了。下面教大学如何使用模拟串行通信,即可以使用任意引脚进行数据的收发。

   1.计算传输一位数据所需要的时间,这与通信的波特率有关,在这里以波特率为1200bps为例。

波特率为1200,意思就是每秒传输的位数是1200位,那么每一位传输的时间就是1/1200*10的6次方=833us

这就表示传输每一位的时间是833us。

   2.了解串行数据收发的过程,它的一帧数据一般包括1个起始位 + 8位有效数据(即一个字节)+ 1位停止位,还有校验位,在这里可要可不要,为了初学者学起来比较简单,在这里就不要校验位了,那么它发送一个字节数据共需要发送10位。还需要注意的是,有效数据是从最低位开始发送,也是从最低位开始接收的。

                                 

   3.知道了它发送数据,接收数据的原理和顺序,计算出它发送一位的时间,我们就可以开始写它的发送函数和接收函数了。

   4.还有一个难点是如何处理号数据接收和数据发送的关系,让他们之间互不影响。接收一个字节时,需要等待起始位的到来,假设接收数据的引脚是RX,那么就需要一直等待RX为0后才可以接收数据,但是在程序里一直等待RX为0,会影响程序其他功能的使用。解决方法有两个,一是采用中断的方法,二是采用查询的方法,在这里我使用了查询的方法,如果不明白的话可以看下面的代码。

   代码实现的功能是按下KEY1键,单片机发送0x01,按下KEY2键,单片机发送0x02;也可以通过串口助手向单片机发送数据,单片机接收到数据后,就再把接收到的数据发送给串口助手。这样的话,即可以实现基本的收发数据的功能。因为单片机的不同,有的地方可能有细微的区别,烧录后看不出效果的可以在下方留言,相互交流一下。

代码如下:

#include"STC15Fxxxx.h"
sbit TX =P3^1;
sbit RX =P3^0;
    
unsigned flag = 0;    
sbit KEY1 = P0^0;
sbit KEY2 = P0^1;

 void Delay833us()        //@11.0592MHz
{
    unsigned char i, j;

    _nop_();
    i = 12;
    j = 244;
    do
    {
        while (--j);
    } while (--i);
}

void Delay416us()        //@11.0592MHz
{
    unsigned char i, j;

    _nop_();
    i = 6;
    j = 247;
    do
    {
        while (--j);
    } while (--i);
}

void Delay10ms()        //@11.0592MHz
{
    unsigned char i, j;

    _nop_();
    _nop_();
    i = 144;
    j = 157;
    do
    {
        while (--j);
    } while (--i);
}


//发送一个字节
void sendbyte(unsigned char num)
{
    int i;
    
    TX=1;
    
    TX=0;    //START
    Delay833us();
    for(i=0;i<8;i++)
    {
        if(num&0x01) TX=1;
        else TX=0; 
        num=num>>1;
        Delay833us();
    }
    
    TX=1;     //STOP
    Delay833us();
}

//接收一个字节
unsigned char receive()
{
    int i = 0;
    unsigned char temp,dat;

    //   TX=1;
//   while(RX==1);    //等待起始位   可以等待到起始位

   Delay833us();
   Delay416us();

   for(i = 0;i < 8;i ++)   //开始接收数据
   {
           dat >>=  1;

           temp = RX;
        if(temp)
            dat |= 0x80;
        else
            dat &= 0x7f;

        Delay833us();
   }

    P64 = ~P64;
    flag = 3;

   return dat;
}

void keyscan()
{
    if(KEY1 == 0)
    {
       Delay10ms();
       if(KEY1 == 0)
       {
            flag = 1;
            while(KEY1 == 0);
       }
    }

    if(KEY2 == 0)
    {
       Delay10ms();
       if(KEY2 == 0)
       {
            flag = 2;
            while(KEY2 == 0);
       }
    }
}
////////////////////
void main(void)
{
    unsigned char value;
     P07 = 0;

    while(1)
    {
        
        if(RX == 0)   //有数据需要接收
        {
            value = receive();   //接收数据
        }
        else
        {
            //按键1被按下,flag = 1;按键2被按下,flag = 2
            keyscan();
            
            
            if(flag == 1)
            {
                flag = 0;
                sendbyte(0x01);
            }
            else if(flag == 2)
            {
                flag = 0;
                sendbyte(0x02);
            }
            if(flag == 3)   //接收到数据,并把它再次发送 出来
            {
                flag = 0;
                Delay10ms();
                Delay10ms();
                Delay10ms();
                Delay10ms();
                Delay10ms();
                Delay10ms();
                sendbyte(value);
            }
        }

    }
}

你可能感兴趣的:(单片机常见模块)