微信公眾號免費(fèi)模板網(wǎng)站化妝品推廣軟文
1.通信有關(guān)的常見概念
區(qū)分:串口,COM口,UART,USART_usart和串口區(qū)別-CSDN博客
串口、COM口、UART口, TTL、RS-232、RS-485區(qū)別詳解-CSDN博客
1.什么是通信
(1)人和人之間的通信:說話,寫信
(2)人和計算機(jī)之間的通信:按鍵,顯示器,鼠標(biāo)
(3)計算機(jī)和計算機(jī)之間的通信
2.通信的關(guān)鍵
(1)事先約定
(2)基本的信息單元
(3)有效信息的編碼,傳輸和解碼
3.通信的專業(yè)性概念
(1)同步和異步:同一個步調(diào)
(2)單工,半雙工,全雙工:數(shù)據(jù)傳輸方向
(3)并行和串口:并行(多根線),串行(單根線)
(4)電平信號【傳輸近,易受干擾】和差分信號【傳輸遠(yuǎn),不易受干擾】:電平是通過高低電平進(jìn)行區(qū)分,差分是相對的
2.串行通信
1.串口通信基礎(chǔ)
(1)一種特定的通信協(xié)議【電平通信】
(2)串行通信,串口通信,UART,USART
(3)串口通信的特點:異步,串行,全雙工
2.串行通信的主要用途
(1)早期:計算機(jī)之間短距離通信(1.5米內(nèi)),完備通信機(jī)制
(2)現(xiàn)在:CPU之間近距離通信【CPU和周邊芯片】,調(diào)試信息輸入輸出,非完備通信
3.串行通信的工作方式
(1)3根線(GND,RxD【接收線】,TxD【發(fā)送線】---recive ,transmit)---不完備通信
或者9根線(DB9)-完備通信
(2)發(fā)送方有發(fā)送位移寄存器,接收方有接收移位寄存器
(3)數(shù)據(jù)在發(fā)送方和接收方的CPU中都以字節(jié)為單位整字節(jié)處理
(4)數(shù)據(jù)在通信線上以位為單位逐個bit的傳輸
4.串行通信的主要概念
傳輸都是一幀一幀的發(fā)
1.起始位
開始之前要發(fā)送一個起始位
2.數(shù)據(jù)位
比如我們傳輸“A”,轉(zhuǎn)換為ASCII就是8位二進(jìn)制,這8位就叫做8位數(shù)據(jù)位【有效數(shù)據(jù)】
數(shù)據(jù)位要雙方溝通確定的
3.奇偶校驗位
判斷傳輸過程中是否出錯
4.停止位(幀)
判斷是否結(jié)束
5.波特率
串行通信的速度
一秒鐘傳輸多少給bit位,發(fā)送方和接收方必須波特率設(shè)置為一樣【波特率越小,傳輸速度慢,抗干擾能力越強(qiáng)】
6.流控
速率協(xié)商,現(xiàn)在一般要禁用掉
3.51單片機(jī)的串行通信
1.基礎(chǔ)概念
SoC:把CPU以及其他功能集成到一個芯片上
(1)串行通信功能是SoC的一個(內(nèi)部)外設(shè)提供的,與CPU無關(guān)【CPU=運(yùn)算器+控制器】--CPU本身無法通信
(2)各種不同的SoC的串行通信大同小異【內(nèi)部差不多,編程時候可能不同】
(3)串行通信經(jīng)常作為主控SoC與其他外部芯片之間的通信接口【串行通信==SoC與外部其他芯片的通信】
2.STC51單片機(jī)的串行通信簡介
4.STC51的串行通信相關(guān)寄存器
1.總體瀏覽
2.SCON:串行控制寄存器
3.SBUF:串行口緩存寄存器
4.PCON:電源控制寄存器
5.IE:中斷允許寄存器
6.串口發(fā)送時的軟硬件協(xié)作方式
(1)查詢方式。硬盤在發(fā)送完一幀數(shù)據(jù)后會將一個標(biāo)志位置位(標(biāo)志位本來是0),軟件需要不斷讀取這個標(biāo)志位的值來判斷硬件是否完成了發(fā)送(如果讀出來的是0就表示硬件還在發(fā)還在發(fā)還沒完還在忙,所以我們就不能認(rèn)為硬件發(fā)完了,所以就不能給硬件安排下一幀數(shù)據(jù)的發(fā)送;如果讀出來的是1則說明硬件已經(jīng)發(fā)完了上一幀數(shù)據(jù),這時候軟件就應(yīng)該給硬件在給一幀數(shù)據(jù)去發(fā)送)
(2)因為串口發(fā)送完這個事件對CPU來說是個異步事件(因為不知道什么時候發(fā)送消息),所以這里查詢方式來處理和之前講過的查詢方式處理按鍵是非常類似的。
(3)常見情況下:串口發(fā)送會使用查詢方式,串口接收會使用中斷方式【因為不知道什么時候會接收到信息,使用中斷才不會過度銷毀CPU】
7.波特率加倍
PCON中的SMOD
所謂波特率加倍,就是正常計算出的波特率假設(shè)是2400,那么SMOD=1時則實際波特率就是4800;當(dāng)SMOD=0時不加倍,也就是2400還是2400
5.STC51的串行通信實戰(zhàn)
1.硬件接線分析
(1)目標(biāo):將PC機(jī)和51單片機(jī)通過串口連接起來
(2)PC機(jī)的串口情況:臺式機(jī)串口,筆記本USB轉(zhuǎn)串口
(3)開發(fā)板原理圖分析
2.接線方案
1.使用板載CH340
什么都不用動,默認(rèn)就是使用這個,最簡單最省事,最推薦
2.使用DB9接口USB轉(zhuǎn)串口線
用DB9接口的USB轉(zhuǎn)串口線
注意:跳線帽接到DB9一側(cè)
3.使用TTL接口USB轉(zhuǎn)串口線
只接三根線:TxD,RxD,GND
4.總結(jié)
3.使用板載CH340進(jìn)行串口實踐
1.接線+下載程序
2.查看設(shè)備管理器確定COM號
3.方法一:使用普中下載軟件自帶的串口助手監(jiān)視
4.方法二:使用第三方串口助手軟件監(jiān)視
5.方法三:使用SecureCRT軟件監(jiān)視
4.使用DB9接口USB轉(zhuǎn)串口線
1.接線+下載程序
2.注意對下載程序的影響
此時無法進(jìn)行程序下載
3.使用各種方式進(jìn)行監(jiān)視
5.串口初始化
//串口初始化函數(shù)
//預(yù)設(shè)一個串口條件:8位數(shù)據(jù)位,1停止位,0校驗位,波特率4800
//初始化的主要工作就是去設(shè)置相關(guān)的寄存器
void uart_init(void){SCON=0x50; //串口工作在模式1(8位串口),允許接收PCON=0x80; //波特率加倍,意思是本來需要波特率4800,等一下計算時按照2400去計算就好}
6.波特率計算
SMOD---》判斷是否進(jìn)行波特率加倍【如果加倍則為1,不加倍則為0】
?查看數(shù)據(jù)手冊中”串行通信中波特率的設(shè)置“
接著查看定時/計數(shù)器1的工作方式2的寄存器設(shè)置情況
TMOD=0x20; //設(shè)置T1為模式2
TR1=1; //開啟T1讓它開始工作
我們剛剛在上面計算出TH1=243;,所以進(jìn)行設(shè)置
TH1=243;
TL1=243; //8位自動重裝,意思就是TH1用完了下一個周期TL1會自動重裝到TH1中
?
7.串口發(fā)送字符【單個字符】
注意點:51單片機(jī)不一樣,要先發(fā)送在檢驗有沒有在發(fā)送
其他MCU都是先檢驗在發(fā)送
如果為【0】則表示在忙,如果為【1】則表示發(fā)送結(jié)束
//串口發(fā)送函數(shù),發(fā)送一個字節(jié)
void uart_send_byte(unsigned char c){//【第一步】發(fā)送一個字節(jié)SBUF=c;//【第二步】先確認(rèn)串口發(fā)送部分沒有在忙while(!TI);//TI=0,表示在忙//【第三步】軟件復(fù)位TI標(biāo)志位---數(shù)據(jù)手冊要求的TI=0;
}
8.測試一下
1.波特率不加倍
#include<reg51.h>//函數(shù)聲明
void uart_init(void);
void uart_send_byte(unsigned char c);
void delay();void main(){//第一步:初始化好串口到正確的狀態(tài)uart_init();while(1){//為了調(diào)試方便,讓A循環(huán)發(fā)送,才好監(jiān)視//第二步:通過串口發(fā)送信息出去uart_send_byte('A');delay();}}void delay(){unsigned char i,j;for(i=0;i<100;i++){for(j=0;j<200;j++);}
}//串口初始化函數(shù)
//預(yù)設(shè)一個串口條件:8位數(shù)據(jù)位,1停止位,0校驗位,波特率4800
//初始化的主要工作就是去設(shè)置相關(guān)的寄存器
void uart_init(void){//波特率不加倍的例子SCON=0x50; //串口工作在模式1(8位串口),允許接收PCON=0x00; //波特率不加倍//通信波特率相關(guān)的設(shè)置//此處我們使用【方式1】---對應(yīng)數(shù)據(jù)手冊TMOD=0x20; //設(shè)置T1為模式2TR1=1; //開啟T1讓它開始工作TH1=249;TL1=249; //8位自動重裝,意思就是TH1用完了下一個周期TL1會自動重裝到TH1中//中斷初始化ES=1;//串口中斷初始化EA=1;//整個中斷初始化}//串口發(fā)送函數(shù),發(fā)送一個字節(jié)
void uart_send_byte(unsigned char c){//【第一步】發(fā)送一個字節(jié)SBUF=c;//【第二步】先確認(rèn)串口發(fā)送部分沒有在忙while(!TI);//TI=0,表示在忙//【第三步】軟件復(fù)位TI標(biāo)志位---數(shù)據(jù)手冊要求的TI=0;
}
因為我們算出來的TH1和TL1=6.5,所以精確度可能會受到影響,我們將其設(shè)置為250 或者 249則結(jié)果都會輸出亂碼
2.換一個波特率:9600
我們前面算出TH1=6.5【這里我們的波特率為4800】,所以如果為9600則我們應(yīng)該將【6.5/2=3.25】才是我們9600的結(jié)果
//波特率為9600SCON=0x50; //串口工作在模式1(8位串口),允許接收PCON=0x00; //波特率不加倍//通信波特率相關(guān)的設(shè)置//此處我們使用【方式1】---對應(yīng)數(shù)據(jù)手冊TMOD=0x20; //設(shè)置T1為模式2TR1=1; //開啟T1讓它開始工作TH1=253;TL1=253; //8位自動重裝,意思就是TH1用完了下一個周期TL1會自動重裝到TH1中//中斷初始化ES=1;//串口中斷初始化EA=1;//整個中斷初始化
9.串口發(fā)送字符串【多個字符】
#include<reg51.h>//函數(shù)聲明
void uart_init(void);
void uart_send_byte(unsigned char c);
void delay();
void uart_send_string(unsigned char *str);void main(){//第一步:初始化好串口到正確的狀態(tài)uart_init();while(1){//發(fā)送字符串,也可以發(fā)送中文uart_send_string("abcdefg");delay();}}void delay(){unsigned char i,j;for(i=0;i<100;i++){for(j=0;j<200;j++);}
}//串口初始化函數(shù)
//預(yù)設(shè)一個串口條件:8位數(shù)據(jù)位,1停止位,0校驗位,波特率4800
//初始化的主要工作就是去設(shè)置相關(guān)的寄存器
void uart_init(void){//波特率加倍的例子SCON=0x50; //串口工作在模式1(8位串口),允許接收PCON=0x80; //波特率加倍,意思是本來需要波特率4800,等一下計算時按照2400去計算就好//通信波特率相關(guān)的設(shè)置//此處我們使用【方式1】---對應(yīng)數(shù)據(jù)手冊TMOD=0x20; //設(shè)置T1為模式2TR1=1; //開啟T1讓它開始工作TH1=243;TL1=243; //8位自動重裝,意思就是TH1用完了下一個周期TL1會自動重裝到TH1中//中斷初始化ES=1;//串口中斷初始化EA=1;//整個中斷初始化}//串口發(fā)送函數(shù),發(fā)送一個字節(jié)【單個字節(jié)】
void uart_send_byte(unsigned char c){//【第一步】發(fā)送一個字節(jié)SBUF=c;//【第二步】先確認(rèn)串口發(fā)送部分沒有在忙while(!TI);//TI=0,表示在忙//【第三步】軟件復(fù)位TI標(biāo)志位---數(shù)據(jù)手冊要求的TI=0;
}//發(fā)送字符串【多個字符】
void uart_send_string(unsigned char *str)
{while (*str != '\0'){uart_send_byte(*str); // 發(fā)送1個字符str++; // 指針指向下一個字符}
}
10.串口接收函數(shù)編寫
因為我們在程序執(zhí)行過程中如果要接收PC機(jī)傳輸過來的數(shù)據(jù),則表示程序要進(jìn)行中斷,則要進(jìn)行中斷處理。
void uart_isr(void) interrupt 4 using 1{
}
#include<reg51.h>//函數(shù)聲明
void uart_init(void);
void uart_send_byte(unsigned char c);
void delay();
void uart_send_string(unsigned char *str);void main(){//第一步:初始化好串口到正確的狀態(tài)uart_init();uart_send_string("串口回環(huán)測試\n");while(1);
}void delay(){unsigned char i,j;for(i=0;i<100;i++){for(j=0;j<200;j++);}
}//串口初始化函數(shù)
//預(yù)設(shè)一個串口條件:8位數(shù)據(jù)位,1停止位,0校驗位,波特率4800
//初始化的主要工作就是去設(shè)置相關(guān)的寄存器
void uart_init(void){//波特率加倍的例子SCON=0x50; //串口工作在模式1(8位串口),允許接收PCON=0x80; //波特率加倍,意思是本來需要波特率4800,等一下計算時按照2400去計算就好//通信波特率相關(guān)的設(shè)置//此處我們使用【方式1】---對應(yīng)數(shù)據(jù)手冊TMOD=0x20; //設(shè)置T1為模式2TR1=1; //開啟T1讓它開始工作TH1=243;TL1=243; //8位自動重裝,意思就是TH1用完了下一個周期TL1會自動重裝到TH1中//中斷初始化ES=1;//串口中斷初始化EA=1;//整個中斷初始化}//串口發(fā)送函數(shù),發(fā)送一個字節(jié)【單個字節(jié)】
void uart_send_byte(unsigned char c){//【第一步】發(fā)送一個字節(jié)SBUF=c;//【第二步】先確認(rèn)串口發(fā)送部分沒有在忙while(!TI);//TI=0,表示在忙//【第三步】軟件復(fù)位TI標(biāo)志位---數(shù)據(jù)手冊要求的TI=0;
}//發(fā)送字符串【多個字符】
void uart_send_string(unsigned char *str)
{while (*str != '\0'){uart_send_byte(*str); // 發(fā)送1個字符str++; // 指針指向下一個字符}
}//中斷處理程序
void uart_isr(void) interrupt 4 using 1
{unsigned char tmp;if(RI){tmp=SBUF; //讀取SBUF,其實就是讀出串口接收到的1個字節(jié)//RI:串行口1接收中斷標(biāo)志RI=0;}//自此已經(jīng)讀到了PC發(fā)給單片機(jī)的一個字節(jié),但是單片機(jī)沒有顯示器無法顯示//我們用最簡單的方法,就是直接回發(fā)uart_send_byte(tmp);
}
6.RS485
1.UART的缺點:傳輸距離受限
(1)理論上RS232不超過15米--電腦的COM端口【DB9】
(2)理論上TTL電平通信距離更短---TTL是在單片機(jī)上使用
(3)實際上幾百米也有人宣稱做到了,但是穩(wěn)定性不能保證
(4)波特率越高通信距離越短【速度越快,通信距離越短】
2.遠(yuǎn)距離傳輸
(1)提高電壓標(biāo)準(zhǔn)
(2)提高通信線抗干擾能力,降低阻抗
(3)使用差分信號--抗干擾能力強(qiáng)【RS485/RS422】
3.RS485(RS422)
(1)最大通信距離1200多米,最快通信速率10Mbps,距離和速度成反比(USB接口,網(wǎng)線)
(2)差分信號負(fù)邏輯【5V代表---0? ? ?-3V代表----1】
(3)更遠(yuǎn)距離可以加中繼器【中繼器---多個485的節(jié)點連接起來--放大】
(4)半雙工【如果要實現(xiàn)全雙工,則使用4根線】
(5)RS485只提高物理層通信能力,不提供數(shù)據(jù)層協(xié)議,需要用戶自定義,或者使用標(biāo)準(zhǔn)協(xié)議如MODBUS協(xié)議。
4.MAX485
MAX485就是相當(dāng)于UART與RS485之間的信號轉(zhuǎn)換
(1)CPU本身只會提供URAT接口,而不會提供RS485接口。CPU根本不認(rèn)識RS485
(2)RS485使用場景:CPUA-->UART轉(zhuǎn)RS485------>遠(yuǎn)距離通信----->RS485轉(zhuǎn)UART---->CPUB
(3)對RS485的理解:RS485是純硬件實現(xiàn)的,硬件芯片如MAX485來管理的,根本不涉及軟件編程。軟件工程師只關(guān)注串口,只通過串口將數(shù)據(jù)發(fā)送出去或者接收回來即可。UART轉(zhuǎn)485和485轉(zhuǎn)UART對CPU來說是透明的。