mini2440----keil for ARM系列之串口

先說明一下爲什麼做了點燈我就做串口了,原因是我覺得串口調試通了在做以後的會更加容易,因爲有些東西可以通過串口進行打印出來,這樣就可以看到自己那裏出錯了,對於LED程序當然是第一需要做的。因爲在中斷中是不允許進行打印輸出的,所以到時候調試中斷就需要用點燈的方式來進行調試。

因此整個流程的實現:先搭建開發環境---------->再進行一些初始程序的編寫(LED與Uart便於以後調試)------------>各個模塊的裸機程序的編寫---------------------->以一個小型項目的形式把所用到的模塊都結合起來。

 

串口的編寫:

最最要注意的就是時鐘的配置,由於這個問題在我做串口的過程中糾結的時間真的很長,而且沒有使用示波器,問題真的有點難找。可以看看這篇文章提到的東西

ARM系列之時鐘的配置

 

一、配置時鐘

在配置串口的時候要注意時鐘配置,如果不想自己進行配置,想用系統默認的配置,可以在初始化代碼中進行查詢,因爲如果沒有弄清楚時鐘頻率,後面對於波特率的配置肯定不能夠實現。寄存器的使用在上一篇文章中已經介紹,這裏就直接貼出我自己的時鐘配置代碼

//時鐘的配置
void CLK_Configure(void)
{
	rMPLLCON = 0;
	//MDIV = 0x38; PDIV = 0x2; SDIV = 0x2;
	//outfrequency = 48MHz;
	rMPLLCON |= (0x38<<12)|(0x2<<4)|(0x3);
	//HCLK = FCLK, PCLK = HCLK/2
	//FCLK = HCLK = 48M    PCLK = 24M;
	rCLKDIVN = 0;
	rCLKDIVN |=0x1;
}


二、對串口0進行一些初始化操作

對於我的硬件平臺MINI2440中,串口使用了GPH這個I/O,因此需要配置GPHCON控制寄存器,把對應的端口配置成爲串口功能,這個控制寄存器簡單,就不多介紹。

ULCON0 :串口線性控制寄存器,

ULCON0 [1,0]——數據位數(5,6,7,8)位

ULCON0 [2]——停止位數(1,2)位

ULCON0 [5:3]——奇偶校驗(奇校驗,偶校驗,不校驗,強制校驗)

ULCON0 [6]——普通模式還是紅外模式

UCON0:串口控制寄存器,相關可以控制的有以下一些

接收與發送的模式(禁止,中斷和流模式,DMA模式)

自環檢測模式,檢驗到錯誤後,是否發生中斷,接收與發送如果是發送模式時,中斷信號請求類型,是脈衝還是低電平,以及時鐘的選擇,對照datasheet可以一步一步配置出來。

UFCON0:是對UART中的FIFO(先進先出緩衝區)的配置,主要是避免串口要傳輸的數據太多過分頻繁中斷CPU導致CPU效率太低的一個緩衝功能,在我們的程序中,沒有使用,一般也不用使用,我認爲如果數據量太多可以通過以太網,或者其他方式進行,不需要通過UART進行。如果想深入瞭解請參看

http://hi.baidu.com/611bob/item/7d14e3312e70dab3623aff24

具體Uart初始化代碼如下

//Uart0的初始化配置
void My_Uart_Init(void)
{
	//GPH0-3配置爲Uart功能
	rGPHCON &= ~(0xFF);	
	rGPHCON |= (1<<1)|(1<<3)|(1<<5)|(1<<7);
	//正常傳輸,奇偶校驗,一位停止位,八位數據位
	rULCON0 |= 0x3;
	//默認配置,無中斷,無DMA,時鐘爲PCLK
	rUCON0 |= (1<<2)|(1);
	rUFCON0 = 0;//FIFO緩衝不使用
}


 

波特率配置

計算公式如下

UBRDIVn = (int)(UART clock/(baud rate * 16))-1;

因此在配置好時鐘頻後,根據自己想要的波特率計算出UBRDIVn的值即可完成配置

代碼如下:

//波特率的設置
void Set_Baud(unsigned int baud)
{
	rUBRDIV0 = ((int)(24000000/(baud*16))-1);
}

下面是在程序中幾個簡單的封裝函數,包括單個字符發送,字符串發送,以及接收字符與字符串。

//單個字符的發送
void My_Uart_Send(unsigned char letter)
{
	while(!(rUTRSTAT0&0x02));		//等待發送緩存空
	rUTXH0 = letter;
}
//字符串的發送
void My_Uart_SendString(unsigned char* str)
{
	unsigned char *temp;
	temp = str;
	while('\0'!=*temp)
	{
		My_Uart_Send(*temp);
		temp++;
	}
}

//從終端使用Uart0進行字符的接收
unsigned char My_Uart_Receive(void)
{
	while(!(rUTRSTAT0&0x01));		//等待接收緩存滿
	return rURXH0;
}

//從終端接收一串字符,沒有考慮刪除等特殊處理
void My_Uart_GetString(unsigned char *str)
{
	unsigned char letter;
	while('\r'!=(letter=My_Uart_Receive()))
	{
		*str = letter;
		str++;
		My_Uart_Send(letter);
	}
	*str='\0';
	My_Uart_Send('\n');
}



 

 

 

 

 

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