文章框架
前言
猴袖外!今兒扯串口示绊,相對于并行——一口氣全把數(shù)據(jù)扔過去,串行顯得更加穩(wěn)重——一位一位來店雅。
串行就是這樣阵子,只需要一條數(shù)據(jù)線(全雙工和同步串行時(shí)兩條)思杯,一位一位的傳過去。為了讓大家在直到你是在給我傳數(shù)據(jù)而不是外面的噪音或者是胡說八道挠进,所以串行數(shù)據(jù)的各位要組裝幀(看正文中的幀格式)色乾。乍一看,這種方式跟并行比肯定慢的一腿领突。但實(shí)際上暖璧,多虧了它的穩(wěn)定性,可以在波特率極高的情況下依然保持穩(wěn)定君旦,這是并行所辦不到的(傳的快了或距離遠(yuǎn)了就張牙舞爪了)澎办,所以發(fā)展到現(xiàn)在嘲碱,串口已經(jīng)把并口甩走幾條街啦。
并口傳輸?shù)睦樱?a href="http://www.reibang.com/p/c994aa660874" target="_blank">《51單片機(jī)實(shí)戰(zhàn):液晶顯示器のLCD1602》
除此之外局蚀,串行傳輸分同步和異步至会。同步除了傳輸數(shù)據(jù)外宵蛀,還要傳輸時(shí)鐘信號术陶,以保持雙方同步梧宫。另一種塘匣,異步,就沒這么麻煩了楞泼,也是本例中要講到的棍厂,各自走各自的時(shí)鐘就好牺弹,只要幀格式和波特率都商量好是一樣的就好例驹。
知識點(diǎn)
電平
電平 | 高電平 | 低電平 | 說明 |
---|---|---|---|
TTL | +5V | 0V | Transistor–Transistor Logic。常用于設(shè)備內(nèi)部的數(shù)據(jù)傳輸屎债,10英尺內(nèi)盆驹。 |
RS-232C | -12V | +12V | RS(recommended standard)代表推薦標(biāo)準(zhǔn)躯喇,232是標(biāo)識號倦微,C代表RS232的最新一次修改(1969)欣福,用于計(jì)算機(jī)串口 |
電平之前在文章《51單片機(jī)實(shí)戰(zhàn):液晶顯示器のLCD1602》中介紹過拓劝,那里只說了TTL郑临,本例中由于要和計(jì)算機(jī)打交道牧抵,所以多了一種電平:RS-232C
在單片機(jī)中是TTL妹孙,電腦那邊傳出和接收都是RS232蠢正,所以兩種電平需要作轉(zhuǎn)換嚣崭。
當(dāng)當(dāng)當(dāng)雹舀!它就是干這活的虚吟。
T#IN | T#OUT | R#IN | R#OUT | VS | C |
---|---|---|---|---|---|
TTL輸入 | TTL輸出 | RS232輸入 | RS232輸出 | 電源 | 接電容 |
舉個(gè)栗子串慰,比如單片機(jī)從T1IN輸入TTL電平,轉(zhuǎn)換好的RS232電平就從R1OUT輸出灸叼。其他的照貓畫虎,這里不詳細(xì)說這個(gè)東西沧卢,因?yàn)樵蹅冊赑roteus里干活但狭,用不著轉(zhuǎn)換(Proteus光環(huán))立磁。
波特率(Baud Rate)
在此描述串行傳輸數(shù)據(jù)速率唱歧。
正兒八經(jīng)的說颅崩,波特率乃碼元的傳輸速率沿后,即每秒傳輸?shù)拇a元個(gè)數(shù)(碼元可以是任意進(jìn)制的)朽砰,并不是什么每秒傳輸?shù)谋忍財(cái)?shù)漆弄,大家注意撼唾。
波特來源于一個(gè)人的名字:Jean-Maurice-émile Baudot券坞,因此簡寫為Baud宇驾,單位符號:Bd猴伶。波特率可簡寫成Bd/s筝尾。
在串口通信中办桨,其碼元就是二進(jìn)制信號损姜,所以波特率的數(shù)值等于比特率數(shù)值摧阅,但你不能說波特率就是比特率鞍艟怼比规!
單片機(jī)的串口通信有四種方式(各方式具體是干什么的,別著急,在后面)乞封,其中方式0和方式2的波特率是固定的锚贱。方式1和方式3的波特率是可變的拧廊,其脈沖周期由定時(shí)器1溢出產(chǎn)生凰盔。
方式 | 波特率 |
---|---|
0 |
f / 12 |
1 | ((2^SMOD ) / 32) × (T1溢出率) |
2 | ((2^SMOD ) / 64) × f
|
3 | ((2^SMOD ) / 32) × (T1溢出率) |
其中f
是系統(tǒng)晶振頻率,T1是計(jì)時(shí)器1尿庐,SMOD
是PCON中的最高位(PCON見相關(guān)寄存器的第一個(gè))抄瑟。
可以從上述公式看出皮假,波特率不可變是因?yàn)橹苯优c系統(tǒng)晶振頻率相關(guān)(晶振頻率不可變,除非換晶振)席舍,而可變是因?yàn)橹苯优cT1的溢出率相關(guān)(溢出率可以改變)来颤。
溢出率
在之前定時(shí)器應(yīng)用的例子(《51單片機(jī)實(shí)戰(zhàn):定時(shí)器與數(shù)碼管的應(yīng)用》)中萝毛,我們計(jì)算的是溢出周期笆包,也就是多長時(shí)間會溢出一次。這次我們用到的溢出率其實(shí)是同一個(gè)東西巴粪,取倒數(shù)就可以了辫塌。
詳見:《51單片機(jī)實(shí)戰(zhàn):定時(shí)器與數(shù)碼管的應(yīng)用》 - 知識點(diǎn) - 定時(shí)器/計(jì)數(shù)器 - 初值
-
使用定時(shí)器1的方式2
定時(shí)器的方式2是一個(gè)自動重裝初值的8位定時(shí)器。低8位(TLX)用于自加計(jì)時(shí)一也,高8位(THX)保存每次自動重裝的初值。
所以舆蝴,用于產(chǎn)生脈沖周期的定時(shí)器的
溢出周期
= [(2^8) -i
] × 12 /f
其中,i
為定時(shí)器初值性锭,f
還是晶振頻率赠潦。溢出率
= 1 /溢出周期
11.0592MHz
為什么要用這么蹩腳的數(shù)字作晶振頻率哈,就是跟這里有關(guān)草冈。如果你已經(jīng)用上述公式計(jì)算過串口方式1下的12MHz和11.0592MHz在9600波特率下的定時(shí)器初值她奥,你就會發(fā)現(xiàn),前者得出一個(gè)小數(shù)怎棱,而后者是個(gè)整數(shù)哩俭。
我們可沒辦法用小數(shù)賦初值,所以你若用近似的整數(shù)作初值拳恋,就意味著會產(chǎn)生誤差凡资。
- 常用:
11.0592MHz
&9600Bd
?THX = TLX = 0xfd
若用其他的晶振和波特率的話鸳谜,請自行按前面的公式計(jì)算蝗肪。
幀格式
串行傳輸按比特來豁延,一個(gè)個(gè)比特組成一個(gè)幀,幀需要一定的格式才能被雙方識別這是一個(gè)幀信息棚点。
S | D | P | E |
---|---|---|---|
起始位 | 數(shù)據(jù)位 | 奇偶校驗(yàn)位 | 終止位 |
標(biāo)明幀頭 | 數(shù)據(jù)信息 | 用于檢驗(yàn)此幀是否出錯(cuò) | 標(biāo)明幀尾 |
1位么库,低電平 | 可以是5、6、7、8位 | 可加可不加宣谈,可奇校驗(yàn)也可偶校驗(yàn) | 可以是1、1/2怪得、2位,高電平 |
相關(guān)寄存器
PCON
電源管理寄存器障陶,用于管理單片機(jī)的電源部分。
字節(jié)地址:87H
苦银,不能位尋址柠辞,reg52.h
中已定義,單片機(jī)復(fù)位時(shí)全部清零冬阳。
位 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|---|
符號 | SMOD | (SMOD0) | (LVDF) | (P0F) | GF1 | GF0 | PD | IDL |
說明 | 串口方式為1柒竞、2渡蜻、3時(shí)毯侦,設(shè)置串口波特率的速率 | STC單片機(jī)特有功能 | STC單片機(jī)特有功能 | STC單片機(jī)特有功能 | 通用工作標(biāo)志位 | 通用工作標(biāo)志位 | 掉電模式 | 空閑模式 |
值 | 0:正常;1:加倍 | ||||1:進(jìn)入掉電模式 | 1:進(jìn)入空閑模式 |
上表中出現(xiàn)的“串口方式”見下表的SM0和SM1颖御。
SCON
串口控制寄存器,用于設(shè)定串口工作方式袱饭。
字節(jié)地址:98H
,可位尋址,reg52.h
中已定義幻锁,單片機(jī)復(fù)位時(shí)全部清零。
位 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|---|
符號 | SM0 | SM1 | SM2 | REN | TB8 | RB8 | TI | RI |
說明 | 工作方式選擇位 | 工作方式選擇位 | 多機(jī)通信控制位 | 允許串行接收位 | 方式2、3時(shí)沃呢,發(fā)送數(shù)據(jù)的第9位 | 方式2、3時(shí)拆挥,接收數(shù)據(jù)的第9位 | 發(fā)送中斷標(biāo)志 | 接收中斷標(biāo)志 |
值 | 看下表 | 看下表 | 與本例無關(guān)懶得說 | 1:允許串口接收數(shù)據(jù) | |第八位發(fā)送結(jié)束時(shí)薄霜,硬件置1 | 第八位接收結(jié)束時(shí),硬件置1 |
SM0 | SM1 | 方式 | 說明 |
---|---|---|---|
0 | 0 | 0 | 同步移位寄存器方式 |
0 | 1 | 1 | 10位異步收發(fā)(8數(shù)據(jù)位)纸兔,波特率可變 |
1 | 0 | 2 | 11位異步收發(fā)(9數(shù)據(jù)位)惰瓜,波特率固定 |
1 | 1 | 3 | 11位異步收發(fā)(9數(shù)據(jù)位),波特率可變 |
上表中波特率可變的方式汉矿,都由定時(shí)器1的溢出率控制崎坊。
實(shí)例
需求說明
當(dāng)單片機(jī)接收到字符a
時(shí),點(diǎn)亮一個(gè)LED燈洲拇。傳送方式:9600波特率奈揍,8數(shù)據(jù)位,無校驗(yàn)位赋续,1停止位男翰。
程序清單
本例中我就不寫電腦端程序了,直接用現(xiàn)成的纽乱。
程序 | 說明 | 下載 |
---|---|---|
VSPD | Visual Serial Port Driver蛾绎,用于建立虛擬串口連接,因?yàn)槲覀冞€是用Proteus模擬接口鸦列,所以需要VSPD模擬串口之間連接起來 | 度娘網(wǎng)盤 |
UartAssist | 串口調(diào)試助手租冠,用來給單片機(jī)發(fā)送消息 | 度娘網(wǎng)盤 |
電路
注意,這里面我沒有放轉(zhuǎn)換電平轉(zhuǎn)換芯片(MAX232)敛熬,只有在Proteus里可以這么干肺稀,現(xiàn)實(shí)中焊板子還是要做電平轉(zhuǎn)換的,這里這個(gè)軟件給簡化了应民。
COMPIM
乃虛擬9Pin串口话原,模擬前記得要設(shè)置參數(shù)。
注意诲锹,波特率要設(shè)置虛擬波特率那個(gè)繁仁,物理波特率在本例中沒用。
虛擬終端
右下角那個(gè)東西是虛擬終端(Virtual Terminal)归园,他可以直接截獲串口傳來的消息然后顯示出來黄虱。很方便做這方面調(diào)試時(shí)使用。
路徑:邊欄
→ instruments
→ virtual terminal
如果在調(diào)試的時(shí)候不小心把它的終端窗口關(guān)了庸诱,再次打開路徑:菜單
→ debug
- virtual terminal
捻浦,注意是在啟動調(diào)試的情況下晤揣。
代碼
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
char a; //用于從緩沖區(qū)中接收數(shù)據(jù),雖然在此例中顯得有點(diǎn)多此一舉朱灿,但最好還是把東西放到自家變量中放心昧识。
//初始化函數(shù)
void init(){
a = 0;
//定時(shí)器初始化
TMOD = 0x20; //定時(shí)器1的方式2
TH1 = 0xfd;
TL1 = 0xfd;
TR1 = 1;
//串口初始化,方式1
SM0 = 0;
SM1 = 1;
REN = 1; //允許接收
EA = 1; //中斷總閘·開盗扒!
ES = 1; //串口中斷·開跪楞!
}
void main() {
init();
while(1);
}
void com() interrupt 4{
a = SBUF; //SBUF為串口接收緩沖區(qū)
while(!RI); //判斷接收是否完畢
if(a == 0x61) //如果是'a',亮燈
P0 = 0;
RI = 0; //準(zhǔn)備下一次接收
}
效果
-
發(fā)送
c
注意這里串口調(diào)試助手中的通訊設(shè)置那一塊侣灶,要和Proteus中COMPIM元件保持一致甸祭。
可以看出發(fā)送c
后,端口正確收到了c
褥影,但并沒有亮燈池户。 -
發(fā)送
a
收到a
后,亮燈凡怎。
結(jié)語
大年初二煞檩,拜訪完姥姥家就該看看單片機(jī)怎么玩,你說是吧栅贴!這兩天快馬加鞭了,下一站:一周目大BOSS熏迹。各位加油檐薯。