久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

通過單片機串口通訊發送一串數據失敗

[復制鏈接]
跳轉到指定樓層
樓主
新人,學51單片機。這個問題困住了好久,解決不了,希望有大神能幫助解答一下,感謝
我想要通過串口發送一串數據,之前實驗發送和接收一幀數據,都在串口中斷中處理,通過STC-TSP串口助手是能夠正常接收和發送的;
但是現在把發送程序從串口中斷中提取出來,寫成了SendByte和SendString兩個函數,串口中斷中接收數據后,在主函數里調用這兩個函數進行發送。
但是在串口助手里,接收緩沖區一直沒有數據,后來通過對比手冊,覺得51單片機的全雙工并不是完全的能夠同時進行,所以對串口是接收還是發送也做了判斷,再進行處理,這個時候發送一幀數據是可以了,可還是不能發送一串數據。
下面是我的代碼
#define MAX_RECV 10
unsigned char recv_data,recv_flag,send_flag,recv_length;
unsigned char recv_buf[MAX_RECV];

void Delay_xms(unsigned char x);
void Uart_Init();
void SendByte(unsigned char dat);
void SendString(unsigned char *buf);

void main()
{
        Uart_Init();
        Delay_xms(500);
        while(1)
        {
                while(recv_flag )
                {

                        SendString(recv_buf);
                        recv_flag = 0;
                }
        }
}

void Delay_xms(unsigned char x)
{
        unsigned char y,z;
        for(y = x;y>0;y--)
                for(z=110;z>0;z--);
}

//串口初始化
void Uart_Init()
{
        TMOD = 0x20;
        SCON = 0x50;
        TH1 = 0xfd;
        TL1 = 0xfd;
        TR1 = 1;
        EA = 1;
        ES = 1;
}

//串口中斷,這里以回車符作為一串數據接收完成的標志
void Uart() interrupt 4
{
        static unsigned char count = 0;  //接收幀數計數
        unsigned char temp;   //一個中間變量
        if(RI)
        {
                RI = 0;
                temp = SBUF;
                if(temp != 0x0D)     //以回車符為結束符
                {
                        recv_buf[count] = SBUF;
                        count++;
                        if(count > MAX_RECV)
                        {
                                count = MAX_RECV;
                        }
                }
                else   
                //如果接收的數據是回車符,說明一串數據接收完成,count歸零
                //接收完成以后才把接收標志置1
                {
                        recv_flag = 1;     //數據接收完成標志
                        recv_length = count;
                        count = 0;
                }
        }
        if(TI)
        {
                TI = 0;
                send_flag = 0;     //send_flag:發送標志
        }
}

//發送一幀數據
void SendByte(unsigned char dat)
{
        SBUF = dat;
        send_flag = 1;
        while(send_flag);
}
//發送一串
void SendString(unsigned char *buf)
{
        while(*buf != '\0')   
        {
                SendByte(*buf);
                buf++;
        }
}

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:973810 發表于 2021-10-21 15:03 | 只看該作者
后面調試能通過SendByte函數發送成功也是因為問了前輩,說串口有進有出,如果不確定現在是進還是出,就會擁堵,就像堵車一樣,所以我設置了recv_flag和send_flag區分,但是現在還是不能正常發送一串數據,實在不知道從哪里改了,希望有前輩能指導一下
回復

使用道具 舉報

板凳
ID:94031 發表于 2021-10-21 16:37 | 只看該作者
小主可以學會 發表于 2021-10-21 15:03
后面調試能通過SendByte函數發送成功也是因為問了前輩,說串口有進有出,如果不確定現在是進還是出,就會擁 ...

給你改了一下,收到一串字符,同樣發出去。
#include<reg51.h>

#define        UART1_BUF_LENGTH        16

unsigned char recv_data,recv_flag,send_flag,recv_length;

unsigned char        TX1_Cnt;        //發送計數
unsigned char        RX1_Cnt;        //接收計數

bit        B_TX1_Busy;        //發送忙標志

unsigned         idata RX1_Buffer[UART1_BUF_LENGTH];        //接收緩沖

void UART1_int (void) interrupt 4
{
        if(RI)
        {
                RI = 0;
                RX1_Buffer[RX1_Cnt] = SBUF;
                if(++RX1_Cnt >= UART1_BUF_LENGTH)        RX1_Cnt = 0;
        }

        if(TI)
        {
                TI = 0;
                B_TX1_Busy = 0;
        }
}

//串口初始化
void Uart_Init()
{
        TMOD = 0x20;
        SCON = 0x50;
        TH1 = 0xfd;
        TL1 = 0xfd;
        TR1 = 1;
        EA = 1;
        ES = 1;
}

void Delay_xms(unsigned char x)
{
        unsigned char y,z;
        for(y = x;y>0;y--)
                                        for(z=110;z>0;z--);
}

void main()
{
        Uart_Init();
        Delay_xms(500);
        while(1)
        {
                if((TX1_Cnt != RX1_Cnt) && (!B_TX1_Busy))        //收到數據, 發送空閑
                {
                        SBUF = RX1_Buffer[TX1_Cnt];
                        B_TX1_Busy = 1;
                        if(++TX1_Cnt >= UART1_BUF_LENGTH)        TX1_Cnt = 0;
                }
        }
}
回復

使用道具 舉報

地板
ID:123289 發表于 2021-10-21 16:41 | 只看該作者
【覺得51單片機的全雙工并不是完全的能夠同時進行】
你錯了!
串口收或發一個字節的時間,CPU在此時間內可以執行幾千條指令。
所以讓串口同時收、發你是根本看不出來的。它們可以相差幾個微秒地進行。
但是,這里強調【但是】,你的串行收、發程序,是調用了別人的程序。
如果,別人的程序必須等一幀收完,或發完后,才能執行其它的指令呢。
這樣就很蠢了,浪費了大量的CPU時間。
例如發N個字符:應當是,發出一個字后,就立即轉去干其它的活,直到這個字發送完成后,再回頭發下一個字。收與發,是可以交叉進行的,而不是發完一幀再收一幀,或收完一幀再發一幀。
如果你是,發一個字符等發完再發下一個再等發完……,直到最后一個字符。這就太浪費時間了。
你是這樣做的嗎?
回復

使用道具 舉報

5#
ID:624769 發表于 2021-10-21 20:42 | 只看該作者
有些小習慣要一開始就不要養成。
void SendByte(unsigned char dat)
{
        SBUF = dat;
        send_flag = 1;
        while(send_flag);
}
這個習慣很不好,你這個send_flag 的作用完全沒有出來,還是傻等,要這樣寫:
void SendByte(unsigned char dat)
{
        while(send_flag);
        SBUF = dat;
        send_flag = 1;
}
那么,這個時候你就可以做其他的事情,直道下次要再發東西的時候,才會等串口空閑。雖然在SendString的時候,意義不大,但是你想切實做到“全雙工” 這點就很重要,在等待發送完成的這個時間,完全可以看看串口有沒有收到新的數據,要不要處理一下之類的。
回復

使用道具 舉報

6#
ID:973810 發表于 2021-10-21 22:52 | 只看該作者
188610329 發表于 2021-10-21 20:42
有些小習慣要一開始就不要養成。
void SendByte(unsigned char dat)
{

謝謝,您說的這里明白了。受教
回復

使用道具 舉報

7#
ID:973810 發表于 2021-10-22 10:13 | 只看該作者
xuyaqi 發表于 2021-10-21 16:37
給你改了一下,收到一串字符,同樣發出去。
#include

感謝!我修改并測試成功了。我還有一個問題:
測試效果我可以發送1 2 3 a b c這樣的一串數據并正常接收,我發現這和之前我把接收和發送都寫在串口中斷里時的效果一樣,可能我問題里表述不清,我其實是想要發送類似“yes,I do”這樣的一句話,用您這個程序測試的話,文本模式收到的是亂碼,hex模式收到的是CE CD,不明白怎么才能正確的發送。期待您的回復,萬分感謝!!!
回復

使用道具 舉報

8#
ID:973810 發表于 2021-10-22 10:21 | 只看該作者
xuyaqi 發表于 2021-10-21 16:37
給你改了一下,收到一串字符,同樣發出去。
#include

還有一個問題,在您修改后的程序下,我發送數據,比如67,有時候它接收到的就是67,但是有時候又是A7。又比如我發送 67 22 34,接收到的是 67 3
回復

使用道具 舉報

9#
ID:973810 發表于 2021-10-22 10:27 | 只看該作者
xuyaqi 發表于 2021-10-21 16:37
給你改了一下,收到一串字符,同樣發出去。
#include

還有一個問題,在您修改后的程序下,我發送同樣的數據有時接收到的數據卻不一樣,請問這是為什么呢。
比如我發送 67,有時候收到的是67,有時候是A7;又例如我發送67 22 34,接收的是67 3B 3C。之前自己寫串口程序的時候測試也遇到了這樣的問題,沒有弄明白
回復

使用道具 舉報

10#
ID:94031 發表于 2021-10-22 12:02 | 只看該作者
小主可以學會 發表于 2021-10-22 10:13
感謝!我修改并測試成功了。我還有一個問題:
測試效果我可以發送1 2 3 a b c這樣的一串數據并正常接收, ...

我能正常收發,你的波特率有問題吧。

回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 欧美一级免费 | 91网站视频在线观看 | 91在线视频国产 | 热re99久久精品国99热观看 | 久久一区 | 精品国产精品国产偷麻豆 | 成人性视频免费网站 | 中文字幕在线看第二 | 午夜网站视频 | 欧美亚洲国产一区 | 国产一区高清 | 欧美综合一区二区 | 99精品国产一区二区青青牛奶 | 性高湖久久久久久久久 | 成人性生交大片免费看中文带字幕 | 91文字幕巨乱亚洲香蕉 | 国产精品乱码一区二区三区 | 国产精品一区二区三区在线 | 97色在线观看免费视频 | 久草a√| 亚洲国产日韩欧美 | 成人在线视频一区二区三区 | 天天拍天天射 | 亚洲成人av | 91久久夜色精品国产网站 | 成人在线电影在线观看 | 亚洲精品欧洲 | 国产乱肥老妇国产一区二 | 亚洲成av人片在线观看 | 成人福利网站 | 爱综合| 日本在线免费 | 黑人精品欧美一区二区蜜桃 | 范冰冰一级做a爰片久久毛片 | 天堂中文资源在线 | 99精品视频网 | 日韩中文字幕免费在线观看 | 国产精品一区二区欧美 | 日本不卡一区 | 成人妇女免费播放久久久 | 日本大香伊一区二区三区 |