先說明一下為什么做了點燈我就做串口了,原因是我覺得串口調(diào)試通了在做以后的會更加容易,因為有些東西可以通過串口進行打印出來,這樣就可以看到自己那里出錯了,對于LED程序當(dāng)然是第一需要做的。因為在中斷中是不允許進行打印輸出的,所以到時候調(diào)試中斷就需要用點燈的方式來進行調(diào)試。
因此整個流程的實現(xiàn):先搭建開發(fā)環(huán)境---------->再進行一些初始程序的編寫(LED與Uart便于以后調(diào)試)------------>各個模塊的裸機程序的編寫---------------------->以一個小型項目的形式把所用到的模塊都結(jié)合起來。
串口的編寫:
最最要注意的就是時鐘的配置,由于這個問題在我做串口的過程中糾結(jié)的時間真的很長,而且沒有使用示波器,問題真的有點難找??梢钥纯催@篇文章提到的東西
ARM系列之時鐘的配置
一、配置時鐘
在配置串口的時候要注意時鐘配置,如果不想自己進行配置,想用系統(tǒng)默認(rèn)的配置,可以在初始化代碼中進行查詢,因為如果沒有弄清楚時鐘頻率,后面對于波特率的配置肯定不能夠?qū)崿F(xiàn)。寄存器的使用在上一篇文章中已經(jīng)介紹,這里就直接貼出我自己的時鐘配置代碼
//時鐘的配置
voidCLK_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=48MPCLK=24M;
rCLKDIVN=0;
rCLKDIVN|=0x1;
}
二、對串口0進行一些初始化操作
對于我的硬件平臺MINI2440中,串口使用了GPH這個I/O,因此需要配置GPHCON控制寄存器,把對應(yīng)的端口配置成為串口功能,這個控制寄存器簡單,就不多介紹。
ULCON0:串口線性控制寄存器,
ULCON0[1,0]——數(shù)據(jù)位數(shù)(5,6,7,8)位
ULCON0[2]——停止位數(shù)(1,2)位
ULCON0[5:3]——奇偶校驗(奇校驗,偶校驗,不校驗,強制校驗)
ULCON0[6]——普通模式還是紅外模式
UCON0:串口控制寄存器,相關(guān)可以控制的有以下一些
接收與發(fā)送的模式(禁止,中斷和流模式,DMA模式)
自環(huán)檢測模式,檢驗到錯誤后,是否發(fā)生中斷,接收與發(fā)送如果是發(fā)送模式時,中斷信號請求類型,是脈沖還是低電平,以及時鐘的選擇,對照datasheet可以一步一步配置出來。
UFCON0:是對UART中的FIFO(先進先出緩沖區(qū))的配置,主要是避免串口要傳輸?shù)臄?shù)據(jù)太多過分頻繁中斷CPU導(dǎo)致CPU效率太低的一個緩沖功能,在我們的程序中,沒有使用,一般也不用使用,我認(rèn)為如果數(shù)據(jù)量太多可以通過以太網(wǎng),或者其他方式進行,不需要通過UART進行。如果想深入了解請參看
http://hi.baidu.com/611bob/item/7d14e3312e70dab3623aff24
具體Uart初始化代碼如下
//Uart0的初始化配置
voidMy_Uart_Init(void)
{
//GPH0-3配置為Uart功能
rGPHCON&=~(0xFF);
rGPHCON|=(1<<1)|(1<<3)|(1<<5)|(1<<7);
//正常傳輸,奇偶校驗,一位停止位,八位數(shù)據(jù)位
rULCON0|=0x3;
//默認(rèn)配置,無中斷,無DMA,時鐘為PCLK
rUCON0|=(1<<2)|(1);
rUFCON0=0;//FIFO緩沖不使用
}
波特率配置
計算公式如下
UBRDIVn = (int)(UART clock/(baud rate * 16))-1;
因此在配置好時鐘頻后,根據(jù)自己想要的波特率計算出UBRDIVn的值即可完成配置
代碼如下:
//波特率的設(shè)置
voidSet_Baud(unsignedintbaud)
{
rUBRDIV0=((int)(24000000/(baud*16))-1);
}
下面是在程序中幾個簡單的封裝函數(shù),包括單個字符發(fā)送,字符串發(fā)送,以及接收字符與字符串。
//單個字符的發(fā)送
voidMy_Uart_Send(unsignedcharletter)
{
while(!(rUTRSTAT0&0x02));//等待發(fā)送緩存空
rUTXH0=letter;
}
//字符串的發(fā)送
voidMy_Uart_SendString(unsignedchar*str)
{
unsignedchar*temp;
temp=str;
while('