『壹』 51單片機串口通信是全雙工的,但是為什麼又說它的發送和接受不可以同時進行呢
51單片機串口通信是全雙工的,發送和接受可以同時進行。不可以同時進行的是半雙工。
全雙工方式分別由兩根不同的傳輸線傳送數據時,通信雙方都能在同一時刻進行發送和接收操作,通信系統的每一端都設置了發送器和接收器,因此,能控制數據同時在發送和接受兩個方向上傳送。
半雙工使用同一根傳輸線既作接收又作發送,雖然數據可以在兩個方向上傳送,但通信雙方不能同時收發數據。採用半雙工方式時,通信系統每一端的發送器和接收器,通過收/發開關轉接到通信線上,進行方向的切換,因此,會產生時間延遲。收/發開關實際上是由軟體控制的電子開關。
(1)51單片機如何串口發送數據擴展閱讀:
全雙工方式在發送設備的發送方和接收設備的接收方之間採取點到點的連接,這意味著在全雙工的傳送方式下,可以得到更高的數據傳輸速度。
全雙工方式無需進行方向的切換,因此,沒有切換操作所產生的時間延遲,這對那些不能有時間延誤的互動式應用(例如遠程監測和控制系統)十分有利。這種方式要求通訊雙方均有發送器和接收器,同時,需要2根數據線傳送數據信號。
『貳』 請教51單片機使用串口中斷發送和非中斷發送有
51單片機串口發送數據,有兩種方式,中斷方式和查詢方式。就發送數據的結果而言沒有任何區別,也都很簡單容易。要找區別,中斷方式適合於稍復雜的系統,單片機執行程序需要完成的任務比較多,就不能采有查詢方式發送,這樣會白白浪費單片機大量的時間而影響完成其它任務了。
所以,中斷方式,節省單片機的時間,效率是最高的,也是正式產品採用的方式。
查詢方式,要整個發送數據期間內,除了發送數據是有效的指令,其餘時間都是在循環等待,浪費了大量的時間,效率極低。但是,很適合一個小題目小程序採用,對於初學者編程比較容易。
『叄』 51單片機串口發送「」是怎麼回事
一、51單片機串口概念
1、51單片機的串列口
51單片機的串列口是一個可編程全雙工的通信介面,具有UART(通用非同步收發器)的全部功能。
2、51單片機的硬體連接
簡單雙向串口通信有兩根數據通信線:
發送端TXD(Transmit Data)
接收端RXD(Receive Data)
TXD和RXD要交叉連接
3、51單片機串口通信的基本結構
51單片機的串列口主要是由兩個獨立的串列數據緩存器SUBF(一個發送緩存寄存器,一個接收緩存寄存器)和發送控制器、接收控制器、輸入移位寄存器及若干控制門電路組成。串列口的基本結構如圖所示:
關於SUBF:串口數據緩存寄存器,物理上是兩個獨立的寄存器,但是佔用相同的地址。寫操作時,寫入的是發送寄存器;讀操作時,讀出的是接收寄存器。
①:接收端:數據通過RXD接收引腳,再通過移位寄存器將數據轉存到接收寄存器中
②:發送端:講數據從發送寄存器中移出,通過TXD發送引腳將數據發送出去
③:波特率:通過設置定時器1的初值,獲取T1溢出率,通過SMOD模式的設置求取波特率
④:中斷:通過發送中斷標志位或接收中斷標志位是否被置位,判斷是否進入串口中斷程序,在接收數據完成後,會將RI置位,產生一個接收中斷;在發送完成後,會將TI置位,產生發送中斷
4、傳播速率——比特率
比特率是指每秒傳送的比特(bit)數。單位為bps(bit per second)也可表示為b/s,比特率越高,單位時間傳送的數據量(位數)越大。
5、波特率
在串口通信中,收發雙方對發送或接收數據的速率有約定,即雙方要有相同的波特率,我們可以通過編程對單片機串列口設定4中工作方式:
其中,T1的溢出率 = 1/T1溢出的時間
①:關於定時器1方式的選擇
在說選取定時器1方式之前插一句:這里的定時器1方式2不是串口那4中方式中的方式2;
在學習定時器的相關知識的時候,我們知道定時器有4種不同的工作方式,在串口通信的實驗中,我們選擇的是定時器1的工作方式2;
定時器T1工作於方式0:溢出所需周期數=8192-x
定時器T1工作於方式1:溢出所需周期數=65536-x
定時器T1工作於方式2:溢出所需周期數=256-x
為什麼不選擇定時器1的工作方式1:
如果我們使用定時器1的工作方式1在中斷中裝初值的方法來T1溢出率的話,在進入中斷、重裝值、出中斷這個過程中很容易產生時間上的微小的誤差,當多次操作時微小的誤差不斷累積,終會產生錯誤;
為什麼選擇定時器1的工作方式2:
因為方式2為自動重裝初值的8位定時器/計數器模式(自動重裝載就是在定時器溢出後自動裝入設定的初值,這樣的好處當然是顯而易見的,不需要在中斷伺服器裏手動賦值了,所以可以精確的定時)所以用它來做波特率發生器最恰當。
②:波特率的計算
在上面介紹串口四種方式的時候提到了波特率的計算公式,由公式可以看出,串口方式0和方式2的波特率是固定的;方式1和方式3的波特率是可變的(根據定時器T1的溢出率來控制)
話不多說,根據題來理解:
根據已知波特率,如何計算定時器1方式2下計數寄存器中的初值:
已經波特率 = 9600,系統的晶振頻率 = 12Mhz,求給TH1和TL1的初值:
由此可見,當系統的晶振頻率為12Mhz時,定時器的初值不是整數;經過計算可得,當晶振頻率為11.0592Mhz時,(256-x) = 3;
當時鍾頻率選用11.0592MHZ時,取易獲得標準的波特率,所以很多單片機系統選用這個看起來「怪」的晶振就是這個道理。
6、波特率與比特率關系與區別
碼元:在數字通信中常常用時間間隔相同的符號來表示一個 二進制數字 ,這樣的時間間隔內的信號稱為 (二進制)碼元。
在信息傳輸通道中,攜帶數據信息的信號單元叫碼元,每秒鍾通過信道傳輸的碼元數稱為碼元傳輸速率,簡稱波特率。即波特率是指數據信號對載波的調制速率,它用單位時間內載波調制狀態改變次數來表示。每秒鍾通過信道傳輸的信息量稱為位傳輸速率,簡稱比特率。比特率表示有效數據的傳輸速率。波特率與比特率的關系是比特率=波特率X單個調制狀態對應的二進制位數。波特率是傳輸通道頻寬的指標。
二、串口通信有關寄存器
1、數據緩存寄存器
SBUF是可以直接定址的專用寄存器。物理上,它對應著兩個寄存器,即一個發送寄存器一個接收寄存器,CPU寫SBUF就是修改發送寄存器;讀SBUF就是讀接收寄存器。接收器是雙緩沖的,以避免在接收下一幀數據之前,CPU未能及時的響應接收器的中斷,沒有把上一幀的數據讀走而產生兩幀數據重疊的問題。對於發送器,為了保持最大的傳輸速率,一般不需要雙緩沖,因為發送時CPU是主動的,不會產生重疊問題。
2、電源寄存器PCON
該寄存器是用來管理單片機的電源部分,包括上電復位檢測,掉電模式,空閑模式等
在串口通信中,我們僅僅需要關注SMOD這一位
SMOD = 0且串口方式為1、2、3時,波特率正常
SMOD = 1且串口方式為1、2、3時,波特率加倍
3、狀態寄存器SCON(98H)
SM0 SM1:工作方式選擇位,串列口有四種工作方式,他們由SM0和SM1設定,其對應關系表如下:
SM2:多機通信時的接收允許標志位
REN:允許串列接收位
TB8,RB8:發送接收數據的第9位,當串口工作於方式2或3 時使用到,指向的是串列傳輸的第9位數據;
1)SM2=0,在方式2或3下,TB8、RB8 發送與接收第9位奇偶校驗位;
2)SM2=1,多機通信時的接收允許位,並且在方式2或3下工作;
TI:發送中斷標志位,在方式0時,當串列發送第8位數據結束時,或在其他方式,串列發送停止位的開始時,由其內部硬體使TI置1,向CPU發出中斷申請。在中斷服務程序中,必須用軟體將其清 0,取消此中斷申請。
RI:接收中斷標志位,在方式0時,當串列接收第8位數據結束時,或在其他方式,串列接收停止位的中間時,由內部硬體使RI置1,向CPU發出中斷申請。也必須在中斷服務程序中,用軟體將其清0,取消此中斷申請。
三、串口通信代碼
串列口在工作之前,應對其進行初始化,主要是設置產生波特率的定時器1,串列口控制和中斷控制。
void usart_init()
{
TMOD = 0x20; //選擇定時器1的工作方式2
TH1 = 0xF3; //通過設置定時器1的初值來選擇波特率
TL1 = 0xf3;
TR1 = 1; //打開計數器
SCON = 0x50; //0101 0000
PCON = 0x80;
ES = 1; //打開通信中斷 ①
EA = 1; //打開總中斷 ②
}
或者
void usart_init()
{
TMOD = 0x20;
TH1 = 253;
TL1 = 253;
TR1 = 1;
SM0 = 0;
SM1 = 1;
// REN = 1
// EA = 1;
// ES = 1;
}
在編寫串口發送端程序時,無需用到接收數據和中斷服務函數,所以REN、EA、ES不需要對他們進行操作
『肆』 51單片機串口怎麼連續發送數據
這個很容易,直接一個一個的發送就可以了。比如:
#include<reg51.h>
main()
{
unsigned char str="this is a test",a;
TMOD=0x20;
TH1=0xfd;
TL1=0xfd;
TR1=1;
while(1)
{
while(*str!='\0')
{
SBUF=*str;
str++;
a=200;
while(a--);
}
}
}
『伍』 51單片機串口發送
//這是一個單片機C51串口接收(中斷)和發送常式,可以用來測試51單片機的中斷接收
//和查詢發送,另外我覺得發送沒有必要用中斷,因為程序的開銷是一樣的
//程序編寫: 龔建偉 [email protected]
//技術主頁:http://www.gjwtech.com
//您有這方面的問題可以和我討論
#include <reg51.h>
#include <string.h>
#define INBUF_LEN 4 //數據長度
unsigned char inbuf1[INBUF_LEN];
unsigned char checksum,count3;
bit read_flag=0;
void init_serialcomm(void)
{
SCON = 0x50; //SCON: serail mode 1, 8-bit UART, enable ucvr
TMOD |= 0x20; //TMOD: timer 1, mode 2, 8-bit reload
PCON |= 0x80; //SMOD=1;
TH1 = 0xF4; //Baud:4800 fosc=11.0592MHz
IE |= 0x90; //Enable Serial Interrupt
TR1 = 1; // timer 1 run
// TI=1;
}
//向串口發送一個字元
void send_char_com(unsigned char ch)
{
SBUF=ch;
while(TI==0);
TI=0;
}
//向串口發送一個字元串,strlen為該字元串長度
void send_string_com(unsigned char *str,unsigned int strlen)
{
unsigned int k=0;
do
{
send_char_com(*(str + k));
k++;
} while(k < strlen);
}
//串口接收中斷函數
void serial () interrupt 4 using 3
{
if(RI)
{
unsigned char ch;
RI = 0;
ch=SBUF;
if(ch>127)
{
count3=0;
inbuf1[count3]=ch;
checksum= ch-128;
}
else
{
count3++;
inbuf1[count3]=ch;
checksum ^= ch;
if( (count3==(INBUF_LEN-1)) && (!checksum) )
{
read_flag=1; //如果串口接收的數據達到INBUF_LEN個,且校驗沒錯,
//就置位取數標志
}
}
}
}
main()
{
init_serialcomm(); //初始化串口
while(1)
{
if(read_flag) //如果取數標志已置位,就將讀到的數從串口發出
{
read_flag=0; //取數標志清0
send_string_com(inbuf1,INBUF_LEN);
}
}
}
『陸』 如何51單片機的串口發送多個數據和接受多個數據
你發送時,用循環控制,發幾個位元組,循環幾次。連續發送多個數據,都是小意思,也是最基本的了。
接收更好辦了,用中斷接收,中斷一次接收一次,你就保存一次唄,這有什麼難的。
『柒』 怎麼樣通過51單片機串口一次發送3個16進制數據
配置好串口,然後寫到SBUF裡面就能自動發送
『捌』 51單片機串口發送數據
程序採用了查詢式發送,for(i=0;i<6;i++){SendChar(askconfig[i]); },共發送了6個字元。
再去查詢收到否。
這種方法,就是有問題的,發送6個字元時,就可能收到了好幾個字元,而沒有及時保存,完全可能丟失信息。
應該採用中斷方式接收;發送,也可以用查詢,也可以用中斷。
方法弄清楚了,程序就容易編寫、調試了。
『玖』 C51單片機發送串口數據到電腦
#include
<reg52.h>
sbit
RELAY
=
P1^2;
//定義繼電器:接P1^1
unsigned
char
command[3],ptr=0,dat;
void
delay(unsigned
int
cnt)
{
while(--cnt);
}
main()
{
TMOD=0x20;
//
TH1=0xfd;
TL1=0xfd;
SM0=0;
SM1
=1;
REN=1;
//控制RI
TR1=1;
/*以上為定時器設置和
波特率
設置,這樣的話,通過串口調試助手發送數據(隨意數據)通過改變RI(串口接收標志來實現繼電器的吸合與打開
*/
while(1)
{
if(RI==1)
{
RI=0;
command[ptr]=SBUF;
ptr++;
if(ptr==2)
{
ptr=0;
if((command[0]=='0')&&(command[1]=='0')&&(command[2]=='7'))RELAY=0;
if((command[0]=='0')&&(command[1]=='0')&&(command[2]=='8'))RELAY=1;
}
}
}
}