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