人機交互(串口通信)

可以說除了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++;
	}
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章