欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 20861|回復: 9
打印 上一主題 下一主題
收起左側

STC89C52RC拓展串口(串口不夠)的解決方法

  [復制鏈接]
跳轉到指定樓層
樓主
現在很多人拿51單片機起步,其中用的最多的當屬STC89C52RC,但隨著學習的深入,越來越感覺到這款單片機功能的落后,再加上現在物聯網技術的發展,通信成了重要的一環,而許多模塊比如藍牙模塊,串口屏,無線模塊,GSM模塊,串口語言模塊等等都用串口通信,而這款單片機的串口就只有一個,遠遠不能滿足功能復雜的大型應用,所以有些人就轉向12,15AVRSTM32等等,但這些單片機的學習資源遠不如STC89C52RC,編程復雜了很多,但實際作品并不一定需要這么高級的單片機怎么辦,本文將介紹幾種常見的方法幫你擴展51單片機的串口:
1:先發一個常用的傳統串口程序,里面包含了各種收發程序。
#include <reg52.h>
#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') //發送字符串,直到遇到0才結束
        {
                SendByte(*pd); //發送一個字符
                pd++;  //移動到下一個字符
        }
}
//串口中斷函數
void InterruptUART() interrupt 4
{
        if(RI)
        {
                RI = 0;
                a= SBUF;
        }
}
2:其實不用單片機自帶的串口,用定時器可以讓任意兩個IO口模擬串口
#include<reg52.h>
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芯片等等。


圖片1.png (47.64 KB, 下載次數: 112)

圖片1.png

圖片3.png (59.45 KB, 下載次數: 105)

圖片3.png

圖片4.png (72.91 KB, 下載次數: 102)

圖片4.png
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏7 分享淘帖 頂2 踩
回復

使用道具 舉報

沙發
ID:427403 發表于 2018-11-18 22:57 | 只看該作者
沒有過模擬串口試試看
回復

使用道具 舉報

板凳
ID:472235 發表于 2019-12-19 22:44 | 只看該作者
樓主你好,我也是SCT15 89C52RC的,程序和助手波特率都是9600,但每次在串口助手輸入A,返回都是80的,找了很久找不出問題。。。。。
回復

使用道具 舉報

地板
ID:128463 發表于 2019-12-20 09:57 | 只看該作者
謝謝分享!!!
回復

使用道具 舉報

5#
ID:669065 發表于 2019-12-20 11:35 來自觸屏版 | 只看該作者
每個人定義的端口不同,接法也不同,需要你自己去了解一下
回復

使用道具 舉報

6#
ID:472235 發表于 2019-12-21 21:21 | 只看該作者
十分感謝樓主,可以搞定了,還做了個雙字節模擬的
回復

使用道具 舉報

7#
ID:495323 發表于 2020-4-8 11:01 來自觸屏版 | 只看該作者
121212121212123 發表于 2019-12-19 22:44
樓主你好,我也是SCT15 89C52RC的,程序和助手波特率都是9600,但每次在串口助手輸入A,返回都是80的,找了 ...

試試ASCII
回復

使用道具 舉報

8#
ID:299519 發表于 2021-10-12 15:23 | 只看該作者
4052,分時擴4。
回復

使用道具 舉報

9#
ID:208271 發表于 2022-3-10 17:35 | 只看該作者
不錯,試試樓主這些方法。之前都是用繼電器通斷通信線的。
回復

使用道具 舉報

10#
ID:208271 發表于 2022-3-10 18:06 | 只看該作者
程序完全沒問題,可以實現單字節收發。自己改了下多字節,這次只要發,下次再試試多字收
                //多字節發送
                for(i=0;i<8;i++)
                {
                         StartTXD(voice[i]);//發送接收數據
                while(!TxdEnd); //發送完成
                }

這樣發送8個字節,完全沒有問題。謝謝樓主,可以擴展簡單的串口應用
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表