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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2723|回復(fù): 9
收起左側(cè)

通過單片機串口通訊發(fā)送一串數(shù)據(jù)失敗

[復(fù)制鏈接]
ID:973810 發(fā)表于 2021-10-21 14:54 | 顯示全部樓層 |閱讀模式
新人,學(xué)51單片機。這個問題困住了好久,解決不了,希望有大神能幫助解答一下,感謝
我想要通過串口發(fā)送一串數(shù)據(jù),之前實驗發(fā)送和接收一幀數(shù)據(jù),都在串口中斷中處理,通過STC-TSP串口助手是能夠正常接收和發(fā)送的;
但是現(xiàn)在把發(fā)送程序從串口中斷中提取出來,寫成了SendByte和SendString兩個函數(shù),串口中斷中接收數(shù)據(jù)后,在主函數(shù)里調(diào)用這兩個函數(shù)進行發(fā)送。
但是在串口助手里,接收緩沖區(qū)一直沒有數(shù)據(jù),后來通過對比手冊,覺得51單片機的全雙工并不是完全的能夠同時進行,所以對串口是接收還是發(fā)送也做了判斷,再進行處理,這個時候發(fā)送一幀數(shù)據(jù)是可以了,可還是不能發(fā)送一串數(shù)據(jù)。
下面是我的代碼
#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;
}

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

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

回復(fù)

使用道具 舉報

ID:973810 發(fā)表于 2021-10-21 15:03 | 顯示全部樓層
后面調(diào)試能通過SendByte函數(shù)發(fā)送成功也是因為問了前輩,說串口有進有出,如果不確定現(xiàn)在是進還是出,就會擁堵,就像堵車一樣,所以我設(shè)置了recv_flag和send_flag區(qū)分,但是現(xiàn)在還是不能正常發(fā)送一串數(shù)據(jù),實在不知道從哪里改了,希望有前輩能指導(dǎo)一下
回復(fù)

使用道具 舉報

ID:94031 發(fā)表于 2021-10-21 16:37 | 顯示全部樓層
小主可以學(xué)會 發(fā)表于 2021-10-21 15:03
后面調(diào)試能通過SendByte函數(shù)發(fā)送成功也是因為問了前輩,說串口有進有出,如果不確定現(xiàn)在是進還是出,就會擁 ...

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

#define        UART1_BUF_LENGTH        16

unsigned char recv_data,recv_flag,send_flag,recv_length;

unsigned char        TX1_Cnt;        //發(fā)送計數(shù)
unsigned char        RX1_Cnt;        //接收計數(shù)

bit        B_TX1_Busy;        //發(fā)送忙標志

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))        //收到數(shù)據(jù), 發(fā)送空閑
                {
                        SBUF = RX1_Buffer[TX1_Cnt];
                        B_TX1_Busy = 1;
                        if(++TX1_Cnt >= UART1_BUF_LENGTH)        TX1_Cnt = 0;
                }
        }
}
回復(fù)

使用道具 舉報

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

使用道具 舉報

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

使用道具 舉報

ID:973810 發(fā)表于 2021-10-21 22:52 | 顯示全部樓層
188610329 發(fā)表于 2021-10-21 20:42
有些小習(xí)慣要一開始就不要養(yǎng)成。
void SendByte(unsigned char dat)
{

謝謝,您說的這里明白了。受教
回復(fù)

使用道具 舉報

ID:973810 發(fā)表于 2021-10-22 10:13 | 顯示全部樓層
xuyaqi 發(fā)表于 2021-10-21 16:37
給你改了一下,收到一串字符,同樣發(fā)出去。
#include

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

使用道具 舉報

ID:973810 發(fā)表于 2021-10-22 10:21 | 顯示全部樓層
xuyaqi 發(fā)表于 2021-10-21 16:37
給你改了一下,收到一串字符,同樣發(fā)出去。
#include

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

使用道具 舉報

ID:973810 發(fā)表于 2021-10-22 10:27 | 顯示全部樓層
xuyaqi 發(fā)表于 2021-10-21 16:37
給你改了一下,收到一串字符,同樣發(fā)出去。
#include

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

使用道具 舉報

ID:94031 發(fā)表于 2021-10-22 12:02 | 顯示全部樓層
小主可以學(xué)會 發(fā)表于 2021-10-22 10:13
感謝!我修改并測試成功了。我還有一個問題:
測試效果我可以發(fā)送1 2 3 a b c這樣的一串數(shù)據(jù)并正常接收, ...

我能正常收發(fā),你的波特率有問題吧。 發(fā)收.png

回復(fù)

使用道具 舉報

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

本版積分規(guī)則

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

Powered by 單片機教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 欧美日韩精品一区 | 精品一区二区三区四区 | 久久r免费视频 | a免费视频 | 国户精品久久久久久久久久久不卡 | 在线三级网址 | 欧美日韩手机在线观看 | 操久久久| 国产精品久久久久久影视 | 久久一区二区视频 | 亚洲精品一区国产精品 | 午夜视频免费在线观看 | 日韩一区二区在线视频 | 亚洲精品成人在线 | 欧美极品一区二区 | 日本不卡一区二区三区在线观看 | 日韩免费视频一区二区 | 亚洲成人免费观看 | 综合久久av| 96国产精品久久久久aⅴ四区 | 午夜在线视频 | 美女黄频 | 97精品国产97久久久久久免费 | 亚洲视频一区二区三区 | 国产精品一区二区三区四区 | 91夜夜夜| 波多野结衣中文字幕一区二区三区 | 天天操天天射综合 | 成人在线观看免费 | 黄色大片在线播放 | 中文字幕视频在线观看 | 国产欧美一区二区三区在线看 | 福利电影在线 | 精品久久久久久久久久久 | 一级美国黄色片 | 日韩精品一区二区三区 | 国产精彩视频 | 欧洲视频一区二区 | 91大神在线资源观看无广告 | 精品国产欧美在线 | 最新伦理片 |