×
单片机 > 单片机程序设计 > 详情

STC89C52RC拓展串口(串口不够)的解决方法

发布时间:2021-03-18 发布时间:
|

现在很多人拿51单片机起步,其中用的最多的当属STC89C52RC,但随着学习的深入,越来越感觉到这款单片机功能的落后,再加上现在物联网技术的发展,通信成了重要的一环,而许多模块比如蓝牙模块,串口屏,无线模块,GSM模块,串口语言模块等等都用串口通信,而这款单片机的串口就只有一个,远远不能满足功能复杂的大型应用,所以有些人就转向12,15,AVR,STM32等等,但这些单片机的学习资源远不如STC89C52RC,编程复杂了很多,但实际作品并不一定需要这么高级的单片机怎么办,本文将介绍几种常见的方法帮你扩展51单片机的串口:

1:先发一个常用的传统串口程序,里面包含了各种收发程序。

#include

#define MAIN_Fosc     11059200UL                        /*使用11.0592M晶体,UL相当于无符号整型,也就是unsigned int*/

//函数声明

void ConfigUART(unsigned int baud);

void SendByte(unsigned char d);

void SendString(unsigned char * pd);

//定义一个全局变量a存储接受到的数据

unsigned int a;

void main()

{

    EA = 1;   //使能总中断

    ConfigUART(9600);  //配置波特率为9600

        SendByte(0x03);

        SendString("ok");

    while(1);

}

//串口初始化程序

void ConfigUART(unsigned int baud)

{

    SCON  = 0x50;  //配置串口为模式1

    TMOD &= 0x0F;  //清零T1的控制位

    TMOD |= 0x20;  //配置T1为模式2

    TH1 = 256 - (MAIN_Fosc/12/32)/baud;  //计算T1重载值

    TL1 = TH1;     //初值等于重载值

    ET1 = 0;       //禁止T1中断

    ES  = 1;       //使能串口中断

    TR1 = 1;       //启动T1

}

//发送一个字节的数据,形参d即为待发送数据。

void SendByte(unsigned char d)                  

{

        SBUF=d; //将数据写入到串口缓冲

        while(!TI); //等待发送完毕

        TI=0;

}

//发送一个字符串

void SendString(unsigned char * pd)

{

        while((*pd)!='') //发送字符串,直到遇到0才结束

        {

                SendByte(*pd); //发送一个字符

                pd++;  //移动到下一个字符

        }

}

//串口中断函数

void InterruptUART() interrupt 4

{

        if(RI)

        {

                RI = 0;

                a= SBUF;

        }

}

2:其实不用单片机自带的串口,用定时器可以让任意两个IO口模拟串口

#include

sbit PIN_RXD = P3^0;

sbit PIN_TXD = P3^1;

bit RxdEnd = 0;

bit RxdOrTxd = 0;

bit TxdEnd = 0;

unsigned char RxdBuf = 0;

unsigned char TxdBuf = 0;

void ConfigUART(unsigned int baud);

void StartRXD();

void StartTXD(unsigned char dat);

void main()

{

        EA = 1;

        ConfigUART(9600);

       

        while(1)

        {

                while(PIN_RXD);

                StartRXD();

                while(!RxdEnd);

                StartTXD(RxdBuf);

                while(!TxdEnd);

        }

       

}

void ConfigUART(unsigned int baud)

{

        TMOD &= 0xF0;

        TMOD |= 0x02;

        TH0 = 256 - (11059200/12)/baud;

}

void StartRXD()

{

        TL0 = 256 - ((256 - TH0)>>1)+4;//之所以加4是因为实地测试发送数据还行,但接收数据误差率太大,估计是51速度太慢,中断中语句太多,当波特率低于9600时可不加4,波特率等于9600则加3以上

        ET0 = 1;

        TR0 = 1;

        RxdEnd = 0;

        RxdOrTxd = 0;

}

void  StartTXD(unsigned char dat)

{

        TxdBuf = dat;

        TL0 = TH0;

        ET0 = 1;

        TR0 = 1;

        PIN_TXD = 0;

        TxdEnd = 0;

        RxdOrTxd = 1;

}

void InterruptTimer0() interrupt 1

{

        static unsigned char cnt = 0;

        if(RxdOrTxd)

        {

                cnt++;

                if(cnt <= 8)

                {

                        PIN_TXD = TxdBuf & 0x01;

                        TxdBuf >>= 1;

                }

                else if(cnt == 9)

                {

                         PIN_TXD = 1;

                }

                else

                {

                        cnt = 0;

                        TR0 = 0;

                        TxdEnd = 1;

                }

        }

        else

        {

                if(cnt == 0)

                {

                        if(!PIN_RXD)

                        {

                                RxdBuf = 0;

                                cnt++;

                        }

                        else

                        {

                                TR0 = 0;

                        }

                }

                else if(cnt <= 8)

                {

                        RxdBuf >>= 1;             

                        if(PIN_RXD)

                        {

                                RxdBuf |= 0x80;

                        }

                        cnt++;

                }

                else

                {

                        cnt = 0;

                        TR0 = 0;

                        if(PIN_RXD)

                        {

                                RxdEnd = 1;

                        }

                }

        }

}

3:有些模块只需要接收单片机发送的数据,那就只接单片机的Txd,同理有些模块只需要给单片机发送数据只接Rxd;

4:多用几块单片机,我们的原则是能用低级的单品机解决的绝不用高级单片机解决。单片机与单片机之间可以用IIC通信或者原始的检测IO口电平。

5:把所有需要用到串口通信的模块都接到单片机的串口上,然后用三极管控制什么时间段什么模块供电工作。

6:通过SPI串口拓展芯片,比如VK3224芯片,CH432T芯片,GM8142芯片,8251芯片等等。

关键字:STC89C52RC  拓展串口  串口 

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
STM32单片机的复用端口初始化的步骤及方法