历史上的今天
返回首页

历史上的今天

今天是:2024年12月20日(星期五)

正在发生

2019年12月20日 | 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芯片等等。

推荐阅读

史海拾趣

Engineered Components Co公司的发展小趣事

在追求经济效益的同时,ECC也注重可持续发展和环保责任。他们积极采用环保材料和绿色生产工艺,降低生产过程中的能耗和排放。ECC还投入资金建设了废水处理设施和废气处理设备,确保生产过程中的废弃物得到有效处理。此外,ECC还积极参与环保公益活动,推动电子行业的绿色发展。这些举措不仅体现了ECC的社会责任感,也为公司的长期发展奠定了坚实的基础。

Elec & Eltek公司的发展小趣事

在国内市场取得一定成绩后,Elec公司开始将目光投向国际市场。为了更好地适应国际市场的需求,Elec公司积极引进国际先进技术和管理经验,并加强与国际知名企业的合作。同时,Elec公司还加大了在海外市场的营销力度,通过参加国际展会、举办技术研讨会等方式提高品牌知名度。经过多年的努力,Elec公司的产品已远销欧美、东南亚等多个国家和地区,成为国际市场上具有竞争力的电子品牌。

AEC Design公司的发展小趣事
某电子行业的AEC Design公司凭借其独特的技术创新能力,成功开发出一款具有颠覆性的新产品。这款产品不仅满足了市场的迫切需求,还凭借其卓越的性能和用户体验赢得了消费者的广泛好评。随着产品的热销,公司的知名度和市场份额迅速提升,为公司的持续发展奠定了坚实基础。
Cypress(赛普拉斯)公司的发展小趣事

Cypress公司成立于1982年,总部设在美国加州的San Jose。创业之初,公司专注于高速CMOS SRAM、EEPROM、PAL器件和TTL逻辑器件的设计和开发。这一时期,Cypress通过引入创新的技术和产品设计,在竞争激烈的电子芯片市场中逐渐崭露头角。公司凭借对技术的持续投入和积累,为未来的发展奠定了坚实的基础。

BOPLA公司的发展小趣事

在国内市场取得一定成绩后,BOPLA开始将目光投向海外市场。通过参加国际电子展会、与海外客户建立合作关系等方式,公司成功将产品打入国际市场。同时,BOPLA还积极调整产品策略,根据不同国家和地区的市场需求,推出定制化的电子元件产品,进一步扩大了市场份额。

Alpha Wire公司的发展小趣事

为了进一步提升公司的竞争力,BOPLA积极寻求与其他企业的合作机会。通过与上下游企业建立紧密的合作关系,公司实现了产业链的协同发展。同时,BOPLA还与其他创新型企业进行技术交流和合作研发,共同推动电子行业的发展。这种合作模式不仅提升了公司的技术水平,还为公司带来了更多的商业机会和发展空间。

以上便是关于BOPLA公司在电子行业中发展的几个可能的故事情节。这些故事展示了BOPLA在创业初期、技术突破、市场拓展、绿色转型以及合作与共赢等方面的努力和成就。当然,实际的发展过程可能更加复杂和多变,但无论如何,BOPLA都以其坚韧不拔的精神和不断创新的态度,在电子行业中留下了深刻的印记。

问答坊 | AI 解惑

IR小型高性能高压IC可简化HID镇流器设计

 国际整流器公司推出IRS2453D系列600V自激式全桥驱动器集成电路IC。该系列适用于一般照明、室外照明及投影机等HID镇流器应用。        新器件采用IR专有的高压集成电路(HVIC)技术,集成了两个高端和两个低端的栅极驱动器。此 ...…

查看全部问答>

Win Ce开发教程

时髦的WinCE 开发教程,及资料…

查看全部问答>

sop元件PCB封装资料图

sop元件PCB封装资料图 --EDN电子设计技术…

查看全部问答>

【藏书阁】纳米粒子与纳米结构薄膜

目录: 第1章 电沉积量子点――通过半导体与衬底之间的晶格失配控制其尺寸  1.1 引言  1.2 CdSe/Au体系  1.3 半导体点阵间隔的调整――Cd(Se,Te)/Au  1.4 衬底点阵间隔的调整――CdSe/Pd  1.5 在Au和Pd衬底上沉积较厚的层CdS ...…

查看全部问答>

变频器前加滤波器的作用?

什么情况下变频器前面加滤波器,后面加电抗器?…

查看全部问答>

请教驱动高手,怎么编写PCM驱动?

我现在刚接触嵌入式下驱动的开发,现在项目组长要我写个UART驱动和PCM驱动,望各位驱动高手给我指点一下,怎么去编写一个PCM接口的驱动,PCM模块连接在板子上一般是遵从什么协议呢?PCI?USB?有协议遵从的话那我写的驱动应该是 ...…

查看全部问答>

GPIO管脚无输出

我写的WINCE的GPIO驱动,GPJ(IN/OUT)管脚GPJ0~GPJ7为输入,这部分工作正常,GPJ8为输出,GPJ9为输入,这两个就不正常了,一直是低电平,寄存器设置也对.默认的GPJ是给Camera用的,GPJ0~GPJ7为CAMDATA,GPJ8为CAMPCLK,GPJ9为CAMVSYNC.我试着把Camera的驱动删 ...…

查看全部问答>

编译驱动模块后,导入出现问题,请解决!

我写了一个虚拟的字符驱动,编译没有问题,可是作为模块导入时,却出现如下的错误提示: unresolved symbol DECLARE_WAIT_QUEUE 下面是源码,请帮忙找一下原因,谢谢! #include #include #include #include #include #include #include ...…

查看全部问答>

FILEIOSHELL 和HEX2BIN两个文件有什么区别

看文档SPRAAQ2中用了两个文件,其中对APPCODE的由HEX到BIN用了FILEOSHELL,而对在RAM中运行的程序用了HEX2BIN,这两个有区别吗?…

查看全部问答>

CCSv5编译优化选项问题

1.            1.我在用CCSv5 调试优化AVS编码器,CCSv5 编译优化选项编译都可以通过,但调试的时候只有-o1可以通过,其它选项调试不通过,提示熵编码代码中有错误。 2.无任何优化条件下,CCS编出来的码流和 ...…

查看全部问答>