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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

新手請教個關(guān)于單片機串口和pc通信的問題

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

回復(fù)

使用道具 舉報

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

使用道具 舉報

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;//把這個去掉就一個字節(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ù)

使用道具 舉報

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

使用道具 舉報

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

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

使用道具 舉報

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

使用道具 舉報

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

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

使用道具 舉報

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

使用道具 舉報

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

使用道具 舉報

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

使用道具 舉報

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

使用道具 舉報

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

#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; //這句去掉,一個字節(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)試助手的“打開串口”,我沒點發(fā)送,嘩啦啦,F(xiàn)FFF就出現(xiàn)了,不斷在接收。
回復(fù)

使用道具 舉報

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

使用道具 舉報

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

使用道具 舉報

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

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

使用道具 舉報

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

使用道具 舉報

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

使用道具 舉報

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

使用道具 舉報

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

明白,謝謝
回復(fù)

使用道具 舉報

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

使用道具 舉報

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

使用道具 舉報

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

使用道具 舉報

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

本版積分規(guī)則

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

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

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