ARM7串口編程要點
U0LCR = 0x80; // DLAB位置1
bak = (Fpclk>>4)/baud;
U0DLM = bak>>8;
U0DLL = bak&0xff;
bak = set.datab-5; // 設置字長度
if(2==set.stopb)
{
bak |= 0x04; // 判斷是否為2位停止位
}
if(0!=set.parity)
{
set.parity = set.parity-1;
bak |= 0x08;
}
bak |= set.parity<<4; // 設置奇偶校驗
U0LCR = bak;
return(1);
}
2. 串口接收數據
用輪循方式接收數據
1>CPU通過串口接收數據時各個寄存器之間的關系

2>串口接受數據的流程:
l 循環檢測U0RBR是否有未讀取的數據。
l 如果有數據到來,則接收數據。
3>相關寄存器配置
(1) U0LSR(線狀態寄存器)
l 作用:只讀寄存器,它提供UART0發送和接收模塊的狀態信息。
l 長度:8位寄存器。
l 各位寄存器的含義:
A.0位:表示接收數據就緒
置0表示U0RBR為空
置1表示U0RBR包含有效數據
注:當U0RBR包含未讀的字符時,第0位被置位;當UART0的U0RBR或FIFO為空時,第0位置零。
B.第1位:溢出錯誤。
置0:溢出錯誤狀態未激活
置1:溢出錯誤狀態激活
注:溢出錯誤條件在錯誤發生后立即設置。對U0LSR讀操作將清零第1位。當UART0的RSR已經有新的字符就緒,而UART0 RBR或FIFO已滿時,第一位置1.此時的UART0 RBR或FIFO不會被覆蓋,UART0 的RSR中的字符將丟失。
C.第2位:奇偶錯誤。
置0:奇偶錯誤狀態未激活
置1:奇偶錯誤狀態激活
注:
² 當接收字符的奇偶位處于錯誤狀態時產生一個奇偶錯誤。對U0LSR讀操作清零該位。
² 奇偶錯誤檢測時間取決于U0FCR的bit0。奇偶錯誤與UART0 的RBR,FIFO中讀出的字符相關。
D.第3位:幀錯誤
置0:幀錯誤狀態未激活。
置1:幀錯誤狀態激活
注:
² 當接收字符的停止位為0時,產生幀錯誤。對讀操作U0LSR清零該位。
² 幀錯誤檢測時間取決于U0FCR的bit0.
² 幀錯誤與UART0的RBR,FIFO中讀出的字符相關。當檢測到一個幀錯誤時,Rx將嘗試與數據重新同步并假設錯誤的停止位實際是一個超前的起始位。但即使沒有出現幀錯誤,它也不能假設下一個接收到的字節是正確的。
E.第四位:間隔中斷
置0:間隔中斷狀態未激活
置1:間隔中斷狀態狀態激活
注:
² 在發送整個字符(起始位,數據,奇偶位和停止位)過程中RXD0如果都保持邏輯0,則產生間隔中斷。
² 當檢測到中斷條件時,接收器立即進入空閑狀態直到RXD0變為全1狀態。
² 讀操作U0LSR清零該狀態位。
² 間隔檢測的時間取決于U0FCR的bit0.
² 間隔中斷與UART0的RBR或FIFO中讀出的字符相關。
F.第五位:發送保持寄存器空
置0:表示U0THR包含有效數據
置1:表示U0THR空
注:
² 當檢測到UART0 的THR空時,THRE置位。
² 對U0THR寫操作清零該位。
G.第6位:表示發送器空
置0:U0THR和或U0TSR包含有效數據。
置1:U0THR和U0TSR空
注:
² 當U0THR和U0TSR都為空時,該位置1
² 當U0TSR或U0THR包含有效數據時,該位清零。
H第7位:表示Rx FIFO 錯誤。
置0:U0RBR中沒有UART0 Rx錯誤,或U0FCR的bit為0.
置1:U0RBR包含至少一個UART0 Rx錯誤。
注:
² 當一個帶有Rx錯誤(例如幀錯誤,奇偶錯誤或間隔中斷)的字符裝入U0RBR時,該位置1.
² 當讀取U0LSR寄存器并且UART0的FIFO中不再有錯誤時,該位置零。
(2) U0RBR(接收器緩沖寄存器)
l 作用:只讀寄存器,是UART0 Rx FIFO的最高字節。它包含了最早接收到的字符,可通過總線接口讀出。串口接收數據時低位在先,即U0RBR的bit0為最早接收到的數據位。如果接收到的數據小于8位,未使用的MSB填充為0.
l 長度:8位寄存器。
4>串口接收數據程序
uint8 UART0_RcvByte(void)
{
uint8 rcv_data ;
while((U0LSR&0X01)==0); //等待數據到達
rcv_data = U0RBR; //從U0RBR中讀出接收到的數據
return rcv_data; //返回接收到的數據
}
3. 串口發送數據
1> 用CPU通過串口發送數據時,各寄存器之間的關系

2> 串口發送數據時的流程
l 將要發送的一字節數據寫入U0THR
l 等待數據發送完畢
3> 相關寄存器配置
(1)U0THR(發送保持寄存器)
l 最用:只寫寄存器。U0THR是UART0 Tx FIFO的最高字節。它包含了Tx FIFO 中最新的字符,可通過總線接口寫入。串口發送數據時,低位在先,bit0代表最先發送的位。
l 長度:8位寄存器
(2)U0LSR(線狀態寄存器)
在上面已經介紹,在此步再涉及。
4> 串口發送數據程序
void UART0_SendByte(uint8 data)
{
U0THR = data;
while(0 == (U0LSR & 0x40));
}
4. 完整的程序事例:
用輪訓方式實現接收上位機數據,并把數據再發送給上位機。
[c-sharp] view plaincopyprint?
- #include "config.h"
- void DelayNS(uint32 dly)
- {
- uint32 i;
- for(; dly>0; dly--)
- {
- for(i=0; i<5000; i++);
- }
- }
- void UART0_Init(uint32 bps)
- {
- uint16 Fdiv;
- PINSEL0 = 0x00000005; //設置串口引腳
- U0LCR = 0x83; //置為除數鎖存位,進行配置
- Fdiv = (Fpclk >> 4) / bps; // 設置波特率
- U0DLM = Fdiv >> 8;
- U0DLL = Fdiv & 0xff;
- U0LCR = 0x03; //清除除數鎖存位,并設置工作模式
- }
- uint8 UART0_RcvByte(void)
- {
- uint8 rcv_data ;
- while((U0LSR&0X01)==0); //等待數據到達
- rcv_data = U0RBR; //從U0RBR中讀出接收到的數據
- return rcv_data; //返回接收到的數據
- }
- void UART0_SendByte(uint8 data)
- {
- U0THR = data;
- while(0 == (U0LSR & 0x40));
- }
- void UART0_RecBuf (uint8 *buffer)
- {
- uint8 *pbuffer;
- uint8 i;
- for(pbuffer = buffer, i = 0;i < 8; i++)
- {
- *(pbuffer++) = UART0_RcvByte();
- }
- }
- void UART0_SendBuf(uint8 *buffer)
- {
- uint8 *pbuffer;
- uint8 i;
- for(pbuffer = buffer,i=0;i < 8; i++)
- UART0_SendByte(*(pbuffer++));
- }
- int main (void)
- {
- uint8 recver_buffer[8]; //定義接收幀緩沖區
- uint8 send_buffer[8] ={0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27}; //定義發送幀緩沖區
- UART0_Init(115200);
- while(1)
- {
- UART0_RecBuf(recver_buffer);
- DelayNS(10);
- if(0x10 ==recver_buffer[0] && 0x11 == recver_buffer[1])
- UART0_SendBuf(recver_buffer);
- else
- UART0_SendBuf(send_buffer);
- }
- return 0;
- }
評論