一:tiny4412串口驅動編寫
1、串口通信簡介
串口通信指串口按位(bit)發送和接收字節,串口通信的概念非常簡單,串口按位(bit)發送和接收字節。盡管比按字節(byte)的並行通信慢,但是串口可以在使用一根線發送數據的同時用另一根線 接收數據。它很簡單並且能夠實現遠距離通信。比如IEEE488定義並行通行狀態時,規定設備線總長不得超過20米,並且任意兩個設備間的長度不得超過2 米;而對於串口而言,長度可達1200米。
串口通信所采用的通信協議為RS-232,RS-232通信方式允許簡單連接三線:Tx、Rx和地線。但是對於數據傳輸,雙方必須對數據定時采用使用相同的波特率。RS-232(ANSI/EIA-232標准)是IBM-PC及其兼容機上的串行連接標准。可用於許多用途,比如連接鼠標、打印機或者Modem,同時也 可以接工業儀器儀表。用於驅動和連線的改進,實際應用中RS-232的傳輸長度或者速度常常超過標准的值。RS-232只限於PC串口和設備間點對點的通信。
2、串口的通信基本模型如下圖所示:
TXD:發送數據
RXD:接收數據
GND:地線
串口驅動跟其他外設的驅動配置流程差不多,大概分為如下幾步:
(1)查看電路圖,配置相應的gpio功能引腳
(2)配置串口控制器的相應寄存器
(3)測試串口接收、發送
今天用的是第一個串口com0,下面是電路圖:
找到相應的gpio功能引腳
下面是串口工作的整個模式圖:
下面是串口控制器相應的寄存器:
今天我們實驗用到的幾個主要的寄存器是:
ULCON0:數據格式控制寄存器(配置數據位,停止位,校驗位等);
UCON0:串口控制開關
UTXH0:發送數據
URXH0:接收數據
UTRSTAT0:數據收發狀態寄存器
UBRDIV0,UFRACVAL0:配置波特率的
下面是uart所需要的工作得時鍾頻率,以及比特率計算公式:
經過計算uart所采用的SCLK_UART為100M
UBRDIV0=(100000000)/(115200 x16) - 1 = 53.3=53=0x35;
UFRACVAL0= 4;
下面具體測試代碼:
1 #ifndef __REGS_H 2 #define __REGS_H 3 4 #define gpa0base 0x11400000 5 #define GPA0CON (*(volatile unsigned long *)(gpa0base + 0x0000)) 6 7 #define uart0base 0x13800000 8 #define ULCON0 (*(volatile unsigned long *)(uart0base + 0x0000)) 9 #define UCON0 (*(volatile unsigned long *)(uart0base + 0x0004)) 10 #define UFCON0 (*(volatile unsigned long *)(uart0base + 0x0008)) 11 #define UMCON0 (*(volatile unsigned long *)(uart0base + 0x000C)) 12 #define UTRSTAT0 (*(volatile unsigned long *)(uart0base + 0x0010)) 13 #define UERSTAT0 (*(volatile unsigned long *)(uart0base + 0x0014)) 14 #define UFSTAT0 (*(volatile unsigned long *)(uart0base + 0x0018)) 15 #define UMSTAT0 (*(volatile unsigned long *)(uart0base + 0x001C)) 16 #define UTXH0 (*(volatile unsigned char *)(uart0base + 0x0020)) 17 #define URXH0 (*(volatile unsigned char *)(uart0base + 0x0024)) 18 #define UBRDIV0 (*(volatile unsigned long *)(uart0base + 0x0028)) 19 #define UFRACVAL0 (*(volatile unsigned long *)(uart0base + 0x002C)) 20 #define UINTP0 (*(volatile unsigned long *)(uart0base + 0x0030)) 21 #define UINTSP0 (*(volatile unsigned long *)(uart0base + 0x0034)) 22 #define UINTM0 (*(volatile unsigned long *)(uart0base + 0x0038)) 23 24 #define uart3base 0x13830000 25 #define ULCON3 (*(volatile unsigned long *)(uart3base + 0x0000)) 26 #define UCON3 (*(volatile unsigned long *)(uart3base + 0x0004)) 27 #define UFCON3 (*(volatile unsigned long *)(uart3base + 0x0008)) 28 #define UMCON3 (*(volatile unsigned long *)(uart3base + 0x000C)) 29 #define UTRSTAT3 (*(volatile unsigned long *)(uart3base + 0x0010)) 30 #define UERSTAT3 (*(volatile unsigned long *)(uart3base + 0x0014)) 31 #define UFSTAT3 (*(volatile unsigned long *)(uart3base + 0x0018)) 32 #define UMSTAT3 (*(volatile unsigned long *)(uart3base + 0x001C)) 33 #define UTXH3 (*(volatile unsigned char *)(uart3base + 0x0020)) 34 #define URXH3 (*(volatile unsigned char *)(uart3base + 0x0024)) 35 #define UBRDIV3 (*(volatile unsigned long *)(uart3base + 0x0028)) 36 #define UFRACVAL3 (*(volatile unsigned long *)(uart3base + 0x002C)) 37 #define UINTP3 (*(volatile unsigned long *)(uart3base + 0x0030)) 38 #define UINTSP3 (*(volatile unsigned long *)(uart3base + 0x0034)) 39 #define UINTM3 (*(volatile unsigned long *)(uart3base + 0x0038)) 40 41 #endif //__REGS_H
1 #ifndef __UART_H 2 #define __UART_H 3 4 void uart_init(); 5 void set_gpio(); 6 void show_serial(); 7 void myputc(unsigned char c); 8 unsigned char mygetc(void); 9 void myputs(unsigned char *str); 10 void mygets(unsigned char *str); 11 12 #endif //__UART_H
1 #include "regs.h" 2 #include "uart.h" 3 4 int main() 5 { 6 set_gpio(); 7 uart_init(); 8 show_serial(); 9 return 0; 10 } 11 12 void show_serial() 13 { 14 /*循環進行數據收發*/ 15 unsigned char cmd[512]; 16 while(1) { 17 myputs("[root@dream]#"); 18 mygets(cmd); 19 myputs(cmd); 20 myputs("\n"); 21 } 22 23 } 24 25 void myputc(unsigned char c) 26 { 27 while(!(UTRSTAT0 & (1 << 1)));//等待buffer為空,再發送字符 28 UTXH0 = c; 29 } 30 unsigned char mygetc(void) 31 { 32 unsigned char ch; 33 while(!(UTRSTAT0 & 1));//等待buffer不為空 34 ch = URXH0; 35 36 return ch; 37 } 38 39 void myputs(unsigned char *str) 40 { 41 while(*str) { 42 myputc(*str); 43 if(*str == '\n') 44 myputc('\r'); 45 str++; 46 } 47 } 48 49 void mygets(unsigned char *str) 50 { 51 unsigned char ch; 52 while(1) { 53 ch = mygetc();//獲取字符 54 myputc(ch); 55 if(ch == '\r') { 56 myputc('\n'); 57 break; 58 } 59 *str = ch; 60 str++; 61 } 62 *str = 0; 63 } 64 65 void set_gpio() 66 { 67 /*0x2 = UART_0_RXD 68 *0x2 = UART_0_TXD*/ 69 GPA0CON &= ~0xff; 70 GPA0CON |= 0x22; 71 } 72 73 void uart_init() 74 { 75 /*step 1:數據格式控制*/ 76 ULCON0 = 3; /*8bit data 1bit stop no parity*/ 77 /*step 2: uart 開關*/ 78 UCON0 = 1 | (1 << 2); 79 /*step 3: set Baud-rate*/ 80 UBRDIV0 = 0x35; 81 UFRACVAL0 = 0x4; 82 /*step 4: 數據收發緩存*/ 83 //UTXH0 84 //URXH0 85 /*step 5:數據收發狀態寄存器*/ 86 //UTRSTAT0 87 }