单片机
返回首页

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

2019-12-20 来源:51hei

现在很多人拿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芯片等等。

进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

精选电路图
  • 红外线探测报警器

  • 短波AM发射器电路设计图

  • RS-485基础知识:处理空闲总线条件的两种常见方法

  • 如何调制IC555振荡器

  • 基于ICL296的大电流开关稳压器电源电路

  • 基于TDA2003的简单低功耗汽车立体声放大器电路

    相关电子头条文章