找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

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

新手請(qǐng)教個(gè)關(guān)于單片機(jī)串口和pc通信的問題

[復(fù)制鏈接]
ID:70774 發(fā)表于 2014-12-20 12:05 | 顯示全部樓層 |閱讀模式
我用PC(串口調(diào)試助手)給單片機(jī)發(fā)送兩個(gè)字節(jié)的數(shù)據(jù),我搞不清楚這兩個(gè)字節(jié)發(fā)送時(shí)的具體情況,于是寫了下面的程序校驗(yàn)一下,我疑惑的是在if語(yǔ)句中如果把ES=1這句去掉,為什么一個(gè)字節(jié)都收不到了,程序如下
#include <reg52.h>
unsigned char flag,a;
void init();
void main()
{
init();
while(1)
{
if(flag==1)
{
ES=0;
flag=0;
SBUF=a;
while(!TI);
TI=0;
ES=1;//把這個(gè)去掉就一個(gè)字節(jié)都收不到了。
}
}
}
void ser() interrupt 4
{
RI=0;
flag=1;
a=SBUF;
}
void init()
{
TMOD=0x20;
TH1=0xf4;
TL1=0xf4;
TR1=1;
REN=1;
SM0=0;
SM1=1;
EA=1;
ES=1;
}
我對(duì)程序的理解是:我在PC上寫兩個(gè)字節(jié)的數(shù)據(jù),一個(gè)一個(gè)發(fā)送,首先發(fā)送一個(gè)字節(jié)。那么單片機(jī)SBUF收到一個(gè)字節(jié)后會(huì)請(qǐng)求中斷,這時(shí)我把sbuf中的值取走,并且主程序中檢測(cè)標(biāo)志位flag等于1,再把這個(gè)數(shù)據(jù)發(fā)送到PC,如果在主程序中最后一句ES=1保留,那么第二個(gè)發(fā)送的數(shù)據(jù)發(fā)送完時(shí),在中斷中又去取數(shù),取完后再發(fā)送到PC,但是如果我把這一句刪除掉,那么我理應(yīng)收到第一個(gè)字節(jié)啊,第二字節(jié)由于沒有開中斷,就無法執(zhí)行中斷,也無法取出第二個(gè)字節(jié)的數(shù)據(jù),進(jìn)而無法發(fā)送到PC啊,可是我一個(gè)字節(jié)都收不到了。。有大神解惑嗎?不太理解傳輸過程,我的理解是,單片機(jī)一直在執(zhí)行主程序,只不過SBUF收到一個(gè)數(shù)據(jù),CPU停下手頭的工作去執(zhí)行取數(shù)據(jù)的命令(或者不取,主程序跟所取數(shù)據(jù)無關(guān),一般通信也不會(huì)這么干吧),那么為什么一個(gè)字節(jié)都收不到呢,我覺得應(yīng)該可以收到一個(gè)字節(jié)的數(shù)據(jù)啊

回復(fù)

使用道具 舉報(bào)

ID:250542 發(fā)表于 2017-11-17 20:33 來自觸屏版 | 顯示全部樓層
這里可以學(xué)習(xí)很多
回復(fù)

使用道具 舉報(bào)

ID:250537 發(fā)表于 2017-11-17 20:12 | 顯示全部樓層
單片機(jī) 的ES是串行口中斷允許位。 如果ES=0,不會(huì)即使有數(shù)據(jù)發(fā)給單片機(jī),也不會(huì)產(chǎn)生中斷。 這里ES=0,然后進(jìn)行發(fā)送。(為了發(fā)送時(shí)禁止產(chǎn)生接受中斷) 而發(fā)送完后,再設(shè)置ES=1,允許串口中斷,可以接受數(shù)據(jù)并產(chǎn)生串口中斷,執(zhí)行串口中斷程序。
回復(fù)

使用道具 舉報(bào)

ID:241242 發(fā)表于 2017-11-17 19:10 | 顯示全部樓層
學(xué)習(xí)一下!
回復(fù)

使用道具 舉報(bào)

ID:70774 發(fā)表于 2014-12-21 11:47 | 顯示全部樓層
dgahz 發(fā)表于 2014-12-21 11:34
你沒輸數(shù)據(jù),里面數(shù)據(jù)默認(rèn)為FF。

明白,謝謝
回復(fù)

使用道具 舉報(bào)

ID:67992 發(fā)表于 2014-12-21 11:34 來自觸屏版 | 顯示全部樓層
你沒輸數(shù)據(jù),里面數(shù)據(jù)默認(rèn)為FF。
回復(fù)

使用道具 舉報(bào)

ID:67992 發(fā)表于 2014-12-21 11:32 來自觸屏版 | 顯示全部樓層
燒錄完它自己進(jìn)了一次中斷,原因不明。
回復(fù)

使用道具 舉報(bào)

ID:67992 發(fā)表于 2014-12-21 11:28 來自觸屏版 | 顯示全部樓層
我之前不是說過了嗎,燒錄完單片機(jī)自己發(fā)送了FF一次,RI置1了,結(jié)果就有你說的現(xiàn)象了。
回復(fù)

使用道具 舉報(bào)

ID:70774 發(fā)表于 2014-12-21 11:11 | 顯示全部樓層
dgahz 發(fā)表于 2014-12-21 10:58
去掉ES=0,TI置1也進(jìn)中斷了。

但是我還沒有發(fā)送數(shù)據(jù),整個(gè)程序應(yīng)該還沒執(zhí)行,當(dāng)我發(fā)送一個(gè)數(shù)據(jù)之后,才應(yīng)該陷入死循環(huán)啊。不知道為什么就直接陷入死循環(huán)了
回復(fù)

使用道具 舉報(bào)

ID:67992 發(fā)表于 2014-12-21 10:58 | 顯示全部樓層
去掉ES=0,TI置1也進(jìn)中斷了。
回復(fù)

使用道具 舉報(bào)

ID:67992 發(fā)表于 2014-12-21 10:54 | 顯示全部樓層
RI和TI是或的關(guān)系,看說明書有講到。只要兩者之一置1,都 會(huì)執(zhí)行中斷服務(wù)函數(shù),就會(huì)不斷發(fā)送和接收。SBUF沒數(shù)據(jù)就會(huì)填充FF.
回復(fù)

使用道具 舉報(bào)

ID:70774 發(fā)表于 2014-12-21 10:40 | 顯示全部樓層
dgahz 發(fā)表于 2014-12-21 10:26
燒錄停不下來的程序貼上來我看看,應(yīng)該不會(huì)有這樣的問題。

#include <reg52.h>
unsigned char flag,a,p,temp;
void init();
void main()
{

  flag=0;
  init();
  while(1)
   {  
    if(flag==1)
     {
       
                flag=0;
                SBUF=p;
                while(!TI);
                TI=0;
                ES=1; //這句去掉,一個(gè)字節(jié)都收不到了      
     }


       
         
}

}
void   dd() interrupt 4
{
        RI=0;
        p=SBUF;
        flag=1;
}

void init()
{
TMOD=0x20;
TH1=0xf4;
TL1=0xf4;
TR1=1;
REN=1;
SM0=0;
SM1=1;
EA=1;
ES=1;
}
只是把上面的ES=0去掉了,燒錄完,打開調(diào)試助手的“打開串口”,我沒點(diǎn)發(fā)送,嘩啦啦,F(xiàn)FFF就出現(xiàn)了,不斷在接收。
回復(fù)

使用道具 舉報(bào)

ID:67992 發(fā)表于 2014-12-21 10:26 來自觸屏版 | 顯示全部樓層
燒錄停不下來的程序貼上來我看看,應(yīng)該不會(huì)有這樣的問題。
回復(fù)

使用道具 舉報(bào)

ID:67992 發(fā)表于 2014-12-21 10:23 來自觸屏版 | 顯示全部樓層
程序運(yùn)行不外乎兩個(gè)地方,中斷內(nèi)和中斷外,中斷內(nèi)處理一些cPu無法預(yù)知何時(shí)發(fā)生的事件,中斷外cpu以查詢指令的方式運(yùn)行,當(dāng)沒有查詢到某個(gè)指令時(shí),即使和這個(gè)指令相關(guān)的事件已發(fā)生,cPu是蒙在鼓里的,它不可能去處理,如此時(shí)它在處理一些延時(shí)較長(zhǎng)的其它事件,情況更糟。
回復(fù)

使用道具 舉報(bào)

ID:67992 發(fā)表于 2014-12-21 10:14 來自觸屏版 | 顯示全部樓層
清標(biāo)志接收一般在中斷吧,cPu可及時(shí)處理,發(fā)送給串口助手由cPu掌控,幾時(shí)發(fā)由編好的程序決定。
回復(fù)

使用道具 舉報(bào)

ID:67992 發(fā)表于 2014-12-21 10:09 來自觸屏版 | 顯示全部樓層
我調(diào)試中初始(燒錄完程序)發(fā)現(xiàn)RI有置1的現(xiàn)象,按道理應(yīng)該不會(huì)有這個(gè)現(xiàn)象,只能猜想硬件須平穩(wěn)過程,也有可能如你所說和燒錄共用了串口的原因。
回復(fù)

使用道具 舉報(bào)

ID:70774 發(fā)表于 2014-12-21 09:58 | 顯示全部樓層
dgahz 發(fā)表于 2014-12-20 23:29
我很少上Q,有什么問題發(fā)本壇我看到會(huì)的話會(huì)答復(fù)的,我初學(xué)單片機(jī),喜歡分析,從中也可學(xué)到東西,原理性的東 ...

真實(shí)太感謝您了。以后有電路方面不懂的還需向您多多請(qǐng)教啊。感覺找到了志同道合的。對(duì)了下面還有一個(gè)問題,想問問您的看法。有時(shí)候我把程序燒錄到單片機(jī)中,打開串口助手,還沒點(diǎn)發(fā)送呢,它就直接發(fā)送了而且停不下來,這又是為什么呢?我也沒有按復(fù)位鍵。是不是因?yàn)闊洉r(shí),也是通過RXD引腳燒錄進(jìn)去的,這時(shí)已經(jīng)在接收數(shù)據(jù)了,從而導(dǎo)致程序收到燒錄的影響?(不知道你所說的上電復(fù)位是什么意思,因?yàn)闊浀臅r(shí)候就需要上電啊。)還有就是通信過程和定時(shí)器工作差不多,就是通信時(shí),CPU不問事,等到串口中斷標(biāo)志位置一,cPU才會(huì)去取數(shù),當(dāng)然也可以不開中斷,但是總要有某種方式來清空標(biāo)志位把(比如位檢測(cè),一直檢測(cè)是否中斷標(biāo)志位是否置一,但是這樣會(huì)影響效率,占用CPU),要不然標(biāo)志位一直是1,無法判斷是否又完成了一次數(shù)據(jù)的傳輸,一般來說單片機(jī)會(huì)用中斷的形式對(duì)SBUF里的值進(jìn)行操作(。,畢竟通信的目的就是發(fā)送指令或者傳遞數(shù)據(jù)啊,這都是我自己的想法,不知道里面有沒有錯(cuò),希望您能解答!謝謝您。
回復(fù)

使用道具 舉報(bào)

ID:67992 發(fā)表于 2014-12-20 23:29 | 顯示全部樓層
我很少上Q,有什么問題發(fā)本壇我看到會(huì)的話會(huì)答復(fù)的,我初學(xué)單片機(jī),喜歡分析,從中也可學(xué)到東西,原理性的東西我說的也不一定對(duì),大家一起探討,理不辯不明。
回復(fù)

使用道具 舉報(bào)

ID:70774 發(fā)表于 2014-12-20 22:38 | 顯示全部樓層
dgahz 發(fā)表于 2014-12-20 16:33
改成這樣試下:
#include
unsigned char flag,a;

謝謝您的回答,可以加您的微信或者qq嗎?
回復(fù)

使用道具 舉報(bào)

ID:18297 發(fā)表于 2014-12-20 16:37 | 顯示全部樓層
單片機(jī) 的ES是串行口中斷允許位。
如果ES=0,不會(huì)即使有數(shù)據(jù)發(fā)給單片機(jī),也不會(huì)產(chǎn)生中斷。
這里ES=0,然后進(jìn)行發(fā)送。(為了發(fā)送時(shí)禁止產(chǎn)生接受中斷)
而發(fā)送完后,再設(shè)置ES=1,允許串口中斷,可以接受數(shù)據(jù)并產(chǎn)生串口中斷,執(zhí)行串口中斷程序。
回復(fù)

使用道具 舉報(bào)

ID:67992 發(fā)表于 2014-12-20 16:33 | 顯示全部樓層
改成這樣試下:
#include <reg52.h>
unsigned char flag,a;
void init();
void main()
{
init();
while(1)
{
if(flag==1)
{
ES=0;
flag=0;
SBUF=a;
while(!TI);
TI=0;
//ES=1;//把這個(gè)去掉就一個(gè)字節(jié)都收不到了。
}
}
}
void ser() interrupt 4
{
RI=0;
a=SBUF;
if(a!=0xff)
flag=1;
}
void init()
{
TMOD=0x20;
TH1=0xf4;
TL1=0xf4;
TR1=1;
REN=1;
SM0=0;
SM1=1;
EA=1;
ES=1;
}
回復(fù)

使用道具 舉報(bào)

ID:67992 發(fā)表于 2014-12-20 16:29 | 顯示全部樓層
單片機(jī)上電復(fù)位時(shí)是不穩(wěn)定的,理想情況當(dāng)然如你所想那樣。上電不該運(yùn)行的中斷服務(wù)程序自動(dòng)運(yùn)行了一次,導(dǎo)致flag=1,結(jié)果主程序里滿足if條件也運(yùn)行了,發(fā)送a給串口,a的內(nèi)容是自動(dòng)運(yùn)行讀取的內(nèi)容,大多為0xff.
結(jié)果你又把ES關(guān)住了。你第一次輸入數(shù)據(jù),對(duì)單片機(jī)來說是第二次了,當(dāng)然沒反應(yīng)了。
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表