可以說除了LCD屏,串口應該是最好的交互工具了。先過一遍串口的基本通信原理。
Ⅰ、協議:
通信無非就是雙方交換消息,雙方要有共同的語言,這樣你說什麼我才能知道。另外還要有時序同步,你說的太快,我也聽不清楚。
Ⅱ、時序圖
平時串口發送線是高電平的,當要向串口發送消息時,拉低串口發送線(起始位),此時PC端發現RX接收線由高電平變爲低電平,那麼PC端就知道串口即將有數據發送。那麼PC端等待多久開始接收數據呢。這就需要雙方在發送和接收前進行約定,這些約定就是串口波特率、數據位、停止位、奇偶校驗位等。發完起始位,開始發送8位的數據,例如A:0x41,剛好8bit,同時PC機接收到的就是0x41;發完數據後,至少拉高一個T的時間(停止位),這個T跟波特率有關。
如果在發送數據之前都要人工操作這些時序,估計會瘋掉。
2440中就有一個串口控制器,只要把串口的參數填寫好,將要發送的數據發送到對應的寄存器,控制器就會自動產生這些時序,將數據發送出去。
一般只需要三條線---發送線(TXD),接受線(RXD),地線(GND)
補充:
串口屬於串行異步通信,雙方時鐘不用一樣,只需要設置波特率等信息。適合單片機與單片機通信。但是串口通信慢,波特率9600bps,也就是說每秒只能傳輸9600bit,相當於每秒傳輸1.2KB。
Ⅲ、原理圖
串口有3根線,這三根線究竟分別接到soc上的哪些管腳?TXD0?有TXD1,當然有,爲什麼我選擇了TXD0,因爲我的板子有USB轉串口。這樣的話選擇這個穿褲作爲調試串口最適合不過了。
Ⅳ、芯片手冊
作爲串口,當然免不了幾個重要的參數:起始位、波特率、數據位、停止位、校驗位。當然波特率是由時鐘決定的,所以還要設置一下串口的運行時鐘。對接的引腳當然也要複用爲串口功能。
將GPH2、GPH3設置爲串口功能!!!
/* 設置引腳用於串口 */
/* GPH2,3用於TxD0, RxD0 */
GPHCON &= ~((3<<4) | (3<<6));
GPHCON |= ((2<<4) | (2<<6));
GPHUP &= ~((1<<2) | (1<<3)); /* 使能內部上拉 */
設置串口參數---數據格式
這是設置串口要不要採用分頻,這裏不採用分頻,我們直接採用PCLK即可,對於不同芯片可以不一樣。對於這個寄存器我們只需要設置最後4bit,接收發送模式。
這裏需要注意一點,設置波特率跟時鐘頻率有關,手冊還指明需要根據波特率設置UBRDIV0 寄存器
/* 設置波特率 */
/* UBRDIVn = (int)( UART clock / ( buad rate x 16) ) –1
* UART clock = 50M
* UBRDIVn = (int)( 50000000 / ( 115200 x 16) ) –1 = 26
*/
UCON0 = 0x00000005; /* PCLK,中斷/查詢模式 */
UBRDIV0 = 26;
/* 設置數據格式 */
ULCON0 = 0x00000003; /* 8n1: 8個數據位, 無較驗位, 1個停止位 */
?,參數都設置完畢!!!!
Ⅴ、發送與接收
串口配置完畢,剩下的就是如何發送和接收的問題。
又到了疑問時刻
接收:我怎麼知道有數據呢?我從哪裏拿數據?
發送:我能不能發送?我往哪裏發數據?
在芯片手冊中有這樣的描述:
發送接收狀態寄存器,咦,哈哈哈!!!
再來兩個,數據寄存器,發送時往UTXH0發送一個字符,在URXH0提取一個字符。四個問題解決了!!!
Ⅵ、串口編程
串口發送
/* UTRSTAT0 */
/* UTXH0 */
while (!(UTRSTAT0 & (1<<2)));
UTXH0 = (unsigned char)c;
串口接收
while (!(UTRSTAT0 & (1<<0)));
return URXH0;
完整代碼
#include "s3c2440_soc.h"
/* 115200,8n1 */
void uart0_init()
{
/* 設置引腳用於串口 */
/* GPH2,3用於TxD0, RxD0 */
GPHCON &= ~((3<<4) | (3<<6));
GPHCON |= ((2<<4) | (2<<6));
GPHUP &= ~((1<<2) | (1<<3)); /* 使能內部上拉 */
/* 設置波特率 */
/* UBRDIVn = (int)( UART clock / ( buad rate x 16) ) –1
* UART clock = 50M
* UBRDIVn = (int)( 50000000 / ( 115200 x 16) ) –1 = 26
*/
UCON0 = 0x00000005; /* PCLK,中斷/查詢模式 */
UBRDIV0 = 26;
/* 設置數據格式 */
ULCON0 = 0x00000003; /* 8n1: 8個數據位, 無較驗位, 1個停止位 */
/* */
}
int putchar(int c)
{
/* UTRSTAT0 */
/* UTXH0 */
while (!(UTRSTAT0 & (1<<2)));
UTXH0 = (unsigned char)c;
}
int getchar(void)
{
while (!(UTRSTAT0 & (1<<0)));
return URXH0;
}
int puts(const char *s)
{
while (*s)
{
putchar(*s);
s++;
}
}