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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

第4章 單片機串口通信

  [復(fù)制鏈接]
ID:111078 發(fā)表于 2016-3-28 01:46 | 顯示全部樓層 |閱讀模式
51單片機輕松入門—基于STC15W4K系列(C語言版)
李友全
編著:http://www.zg4o1577.cn/bbs/dpj-37954-1.html


4章 串 口 通 信
1 串口通信電路
2 串口數(shù)據(jù)發(fā)送格式
3 串口相關(guān)寄存器
4 波特率計算公式與表格
5 單片機與計算機通信的簡單例子
6 數(shù)據(jù)通信中的錯誤校驗(校驗和)

7 單片機串口向計算機串口發(fā)送2進制、16進 制、數(shù)值與字符串


0.png

2 串口數(shù)據(jù)發(fā)送格式

串口數(shù)據(jù)發(fā)送格式如圖4-1所示,注意這里的格式是對于單片機串口TXD引腳而言的,信 號經(jīng)過SP3232或MAX232芯片后會被倒相,即+5V(邏輯1)變-9V(邏輯0,典型值是-9V, RS232標準范圍:-3V~-15V),0V(邏輯0)變+9V(邏輯1,典型值是+9V,RS232標準范圍:

%E7%AC%AC4%E7%AB%A0-%E4%B8%B2%E5%8F%A3%E9%80%9A%E4%BF%A1-4.jpg +3V~+15V)。

圖4-1 串口數(shù)據(jù)發(fā)送格式

當單片機執(zhí)行一條寫SBUF的指令時,就啟動串行通信的發(fā)送,數(shù)據(jù)由串行發(fā)送端TXD輸 出,發(fā)送時,先發(fā)送一個起始位(低電平),用來表示數(shù)據(jù)傳輸開始,接著將1個字節(jié)的8個位 按低位在前高位在后的順序發(fā)送輸出,第9 位通常作為奇偶校驗位,最后發(fā)送停止位(高電平) 用來表示數(shù)據(jù)傳送結(jié)束。這樣的數(shù)據(jù)格式通常作為一個串行幀,如無奇偶校驗位,即是最為常 見的N.8.1幀格式(無奇偶校驗、8位數(shù)據(jù)位、1位停止位)。

接收時,只要單片機允許接收(REN=1),單片機硬件就會不斷的以16倍波特率的采樣速率

采樣RXD引腳電壓,一旦檢測到RXD引腳上出現(xiàn)一個從“1”到“0”的負跳變(即起始 位)時,就啟動接收。串行通信中,每秒鐘傳送二進制碼的位數(shù)稱為波特率,單位是 bps,即 “位/秒”,比如數(shù)據(jù)傳送的波特率為9600 比特,采用N.8.1 幀格式(10 位),則每秒傳送字節(jié)為9600/10=960 個,而字節(jié)中每一位傳送時間即為波特率的倒

數(shù):T = 1/9600 (S) = 104uS,根據(jù)數(shù)據(jù)傳送的波特率即字節(jié)中每一位的傳送時間, 我們也可通過編寫程序控制普通I/O 口實現(xiàn)圖4-1的通信時序。

圖4-1數(shù)據(jù)格式進一步說明如下:

l ① 起始位:發(fā)送線TXD上沒有發(fā)送數(shù)據(jù)時呈高電平1狀態(tài)(即5V),當需要發(fā)送一幀數(shù) 據(jù)時,首先發(fā)送一位0(低電平)信號,稱起始位。
l ② 數(shù)據(jù)位:緊接起始位后是8位數(shù)據(jù)位(51單片機格式固定8位,不能修改),發(fā)送時 從數(shù)據(jù)的最低位開始,順序發(fā)送輸出)。
l ③ 奇偶校驗位:緊接數(shù)據(jù)位后是1位奇偶校驗位(SCON寄存器設(shè)為方式0和方式1沒有 這一位),奇偶校驗位無實用價值,實際運用是可靠性高的校驗和、異或校驗或CRC。
l ④ 停止位:在校驗位后是停止位1 (高電平5V),用于表示一幀數(shù)據(jù)結(jié)束(51單片機 停止位固定1位,不能修改)。

l ⑤ 幀與幀之間間隙不固定,間隙處用空閑位1(高電平)填補。

3 串口相關(guān)寄存器

串口1控制寄存器SCON:我們把此寄存器設(shè)為“格式固定的10位串口通信,允許 接收”,固定值:0x50,幾乎任何時候都不用修改用這個值,可使用定時器1或 定時器2作波特率發(fā)生器。

輔助寄存器 AUXR :使用語句AUXR &= 0xFE; 串口1選擇定時器1為波特率發(fā)生 器,使用語句AUXR |= 0x01;串口1選擇定時器2為波特率發(fā)生器(默認值,建 議),當然還需在程序中啟動相應(yīng)定時器。

電源控制寄存器PCON(復(fù)位值為0011 0000B)
D7
D6
D5
D4
D3
D2
D1
D0

位名稱

SMOD








SMOD用于設(shè)置串口1的波特率是否加倍,其它串口波特率與此寄存器無關(guān)。
1:波特率加倍。0:波特率不加倍。
串口1數(shù)據(jù)緩沖區(qū)寄存器SBUF,復(fù)位值是xxxx xxxxB(即不確定的數(shù)據(jù)),需要發(fā)送 輸出的數(shù)據(jù)放這里就能自動發(fā)送出去,串口自動接收到的數(shù)據(jù)也存放在這里

串口2控制寄存器S2CON ,我們把此寄存器設(shè)為“格式固定的10位串口通信 , 允許接收”,固定值:0x10,只能使用定時器2作波特率發(fā)生器,當然還需在程 序中啟動定時器2。

串口3控制寄存器S3CON ,我們把此寄存器設(shè)為“格式固定的10位串口通信 , 允許接收”,值為0x10時使用定時器2作波特率發(fā)生器(建議),值為0x50時 使用定時器3作波特率發(fā)生器,當然還需在程序中啟動相應(yīng)定時器。

串口4控制寄存器S4CON ,我們把此寄存器設(shè)為“格式固定的10位串口通信 , 允許接收”,值為0x10時使用定時器2作波特率發(fā)生器(建議),值為0x50時 使用定時器4作波特率發(fā)生器,當然還需在程序中啟動相應(yīng)定時器。

4 波特率計算公式與表格

%E7%AC%AC4%E7%AB%A0-%E4%B8%B2%E5%8F%A3%E9%80%9A%E4%BF%A1-1.jpg

4-17 常用波特率與定時器初值對應(yīng)表(T1定時器8位自動重裝方式)

時鐘頻率

定時器 分頻模式

波特率(bps)

預(yù)置初值 (SMOD=0)
預(yù)置初值 (SMOD=1)

11.0592

1T

9600
DCH
B8H
57600
FAH
F4H
115200
FDH
FAH

12T

9600
FDH
FAH
57600
不能實現(xiàn)
FFH
115200
不能實現(xiàn)
不能實現(xiàn)

22.1184

1T

9600
B8H
70H
57600
F4H
E8H
115200
FAH
F4H

12T

9600
FAH
F4H
57600
FFH
FEH
115200
不能實現(xiàn)
FFH
對于表4-17中“不能實現(xiàn)”的波特率,一般可以通過換用16位定時器方式解決,因為16位
定時器出來的溢出信號傳輸速度更快,適用于波特率要求很高的場合。 注意:對于STC15系列單片機,當各個串口的波特率都相同時,各串口可以共享定時器2
作為其波特率發(fā)生器,實際使用中建議各串口都優(yōu)先選擇定時器T2作波特率發(fā)生器。
5 單片機與計算機通信的簡單例子

例4.1 單片機向電腦發(fā)送0~255范圍內(nèi)不斷增大的數(shù)據(jù),使用串口1,定時器T1作波特率 發(fā)生器,波特率9600/22.1184MHz。單片機串口1接收引腳是RXD/P3.0,串口1發(fā)送引腳是 TXD/P3.1,也就是默認的程序下載引腳,程序下載完畢即可通過串口助手進行測試。

#include "STC15W4K.H" // 包含 "STC15W4K.H"寄存器定義頭文件
void delay500ms(void)
{ // 由第一章介紹的軟件計算得出
}
void UART_init(void)
{
// 下面代碼設(shè)置定時器1
TMOD = 0x20; // 0010 0000 定時器1工作于方式2(8位自動重裝方式) TH1 = 0xFA; // 波特率:9600 /22.1184MHZ
TL1 = 0xFA; // 波特率:9600 /22.1184MHZ
TR1 = 1;
// 下面代碼設(shè)置定串口
AUXR = 0x00; // 很關(guān)鍵,使用定時器1作為波特率發(fā)生器,S1ST2=0
SCON = 0x50;
// 0101 0000 SM0.SM1=01(最普遍的8位通信),REN=1 (允許接收)
}
void UART_send_byte(unsigned char dat)
{
SBUF = dat;
while(!TI);
TI=0; // 此句可以不要,不影響后面數(shù)據(jù)的發(fā)送,只供代碼查詢數(shù)據(jù)是否發(fā)送完成
}
void main()
{
unsigned char num=0; UART_init();
while(1)
{
UART_send_byte(num++);
delay500ms();
}
}
運行結(jié)果如圖所示。

%E7%AC%AC4%E7%AB%A0-%E4%B8%B2%E5%8F%A3%E9%80%9A%E4%BF%A1-2.jpg

例4.2 單片機接收電腦數(shù)據(jù),加1后發(fā)回電腦,使用串口1,定時器T2作波特率發(fā)生器,波特率9600/22.1184MHz。
#include "STC15W4K.H" // 包含 "STC15W4K.H"寄存器定義頭文件
unsigned char num=0; // 存放接收到的1個字節(jié)的數(shù)據(jù)

void UART_init(void)

{

}

void main()

{

}

// 下面代碼設(shè)置定時器2
T2H = 0xFD; // 波特率:9600 /22.1184MHZ,1T
T2L = 0xC0; // 波特率:9600 /22.1184MHZ,1T
AUXR = 0x15; // 0001 0101,T2R=1啟動T2運行,T2x12=1,定時器2按1T計數(shù),S1ST2=1
// 下面代碼設(shè)置定串口1
SCON = 0x50; // 0101 0000 SM0.SM1=01(最普遍的8位通信),REN=1(允許接收)
// 下面代碼設(shè)置中斷
ES = 1; // 開串口1中斷
EA = 1; // 開總中斷

UART_init();

while(1);

void UART1(void) interrupt 4 // 串行口1中斷函數(shù)
{

if(TI)

{

}

if(RI)

{

}

}


TI = 0;

RI = 0;

num = SBUF;

num++;

SBUF = num; // 啟動數(shù)據(jù)發(fā)送過程
6 數(shù)據(jù)通信中的錯誤校驗

數(shù)據(jù)通信難免可能發(fā)生錯誤,為了讓接收端判斷數(shù)據(jù)傳輸過程是否發(fā)生錯誤,我們需要 在發(fā)送的數(shù)據(jù)中傳送額外的附加數(shù)據(jù),簡單常用的附加數(shù)據(jù)是校驗和。

校驗和的方法就是把需要發(fā)送或接收的一組數(shù)據(jù)的所有字節(jié)進行相加,相加結(jié)果與256進行 相除,取其余數(shù),將此余數(shù)組合成發(fā)送數(shù)據(jù)的一部分而發(fā)送出去,同樣,接收數(shù)據(jù)的一方也 以相同的方式將所發(fā)送過來的數(shù)據(jù)進行相加計算,并與發(fā)送方所發(fā)過來的計算值比較,若其 值相同,則代表所發(fā)送的數(shù)據(jù)是正確的,反之則是錯誤的,檢查錯誤時,接收方可能要求發(fā) 送方重新發(fā)送,以確保數(shù)據(jù)的正確性。

例如,被發(fā)送數(shù)值為 0xAB 0xCD 0xEF 0x01 0x02 0x03 ,則將它們數(shù)值相加結(jié)果是
0x026D,以十進制表示為 621,與256 相除后取余數(shù),其值為109,再轉(zhuǎn)換成16進制為
0x6D,因此發(fā)送數(shù)據(jù)時在數(shù)據(jù)的尾端再加上一個字節(jié)0x6D,因此實際發(fā)送出去的數(shù)據(jù)成為
0xAB 0xCD 0xEF 0x01 0x02 0x03 0x6D,對方收到所發(fā)送的數(shù)據(jù)后會根據(jù)以上方式再進行一
次計算,如果計算出來的結(jié)果是0x6D,表示此次發(fā)送的數(shù)據(jù)是正確的。校驗和計算函數(shù)如下:

unsigned char CheckSum(unsigned char *ptr, unsigned char len)

{

unsigned char i; unsigned char a; unsigned int Value=0;

for(i=0;i<len;i++) //len結(jié)束后第一個字節(jié)為接收到的校驗和
{

Value = Value + ptr[ i ];

}
a=Value; // 長送短,傳送完整低字節(jié)

return(a);

}

7 單片機串口向計算機串口發(fā)送2進制、16進制、數(shù)值與字符串
例4.15 單片機串口向計算機串口發(fā)送2進制、16進制、數(shù)值與字符串
//////////////////////////////// main.c //////////////////////////////
#include "uart_debug.h" void main()
{

unsigned char a=0x55; unsigned int b=0xAB98; unsigned long c=1234567890;

unsigned char Buf[]="歡迎使用STC15單片機!\n"; //字符串在內(nèi)存結(jié)尾必然有一個附 加字符:\0
UART_init(); // 波特率:9600 /22.1184MHZ UART_Send_Str("串口設(shè)置完畢:123ABC\n"); // 發(fā)送字符串 UART_Send_Str(Buf);
UART_Send_Num(b);
// 發(fā)送數(shù)值
UART_Send_StrNum("數(shù)值=:",c); // 發(fā)送字符串+數(shù)值 UART_Send_Hex(b) ; // 發(fā)送16進制 UART_Send_binary(a); // 發(fā)送2進制 while(1);
}

實驗結(jié)果如下圖所示

%E7%AC%AC4%E7%AB%A0-%E4%B8%B2%E5%8F%A3%E9%80%9A%E4%BF%A1-3.jpg

本程序使用了一個程序包和程序包對應(yīng)的頭文件,程序移植時請將這兩個
文件復(fù)制到自己的工程文件夾, 串口初始化函數(shù)UART_init(); 默認波特率:
9600 /22.1184MHZ,可調(diào)整,其余部分不要修改。

相關(guān)帖子

回復(fù)

使用道具 舉報

ID:118796 發(fā)表于 2016-6-22 11:19 | 顯示全部樓層
不太懂!
回復(fù)

使用道具 舉報

ID:350005 發(fā)表于 2018-7-16 20:55 | 顯示全部樓層
請問"uart_debug.h"里面的程序是什么   看書沒找到
回復(fù)

使用道具 舉報

ID:439493 發(fā)表于 2018-12-4 19:45 | 顯示全部樓層
初步學(xué)習(xí)一下,謝謝
回復(fù)

使用道具 舉報

ID:288930 發(fā)表于 2019-1-29 10:10 | 顯示全部樓層
謝謝分享!
回復(fù)

使用道具 舉報

ID:676789 發(fā)表于 2019-12-29 18:01 | 顯示全部樓層

謝謝分享!!
回復(fù)

使用道具 舉報

7#
無效樓層,該帖已經(jīng)被刪除
您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 亚洲欧美一区二区三区国产精品 | 黄色网址在线播放 | 亚洲欧美综合 | 成人性视频在线 | 中文字幕一级毛片视频 | 欧美成人精品在线 | 国产欧美久久一区二区三区 | 国产精品99久久久久久久vr | av大全在线观看 | 91嫩草精品| 久久久2o19精品 | 国产 日韩 欧美 在线 | 在线欧美 | 日韩高清一区二区 | 欧美精品一区二区三区四区五区 | 亚洲精品久久久久久久久久吃药 | 中文字幕 亚洲一区 | 国产69精品久久99不卡免费版 | 国产精品久久久久久久久久久久久 | 国产一区二区精品在线 | 最新毛片网站 | 特黄特色大片免费视频观看 | 精品一区二区观看 | 成人国产精品久久 | 亚洲国产精品精华素 | 精品成人免费一区二区在线播放 | 99久久日韩精品免费热麻豆美女 | 日韩午夜影院 | av香蕉| 久久久久国色av免费观看性色 | 国产一区在线免费 | 欧美日韩视频网站 | 啪一啪 | 在线免费国产视频 | 99re在线视频观看 | 亚洲一区成人 | 国产视频h | 免费激情av | 97精品国产一区二区三区 | 涩涩视频在线观看免费 | 奇米四色在线观看 |