exynos4412—UART裸板复习
我们通过RS232来做实验。
通过电平转换芯片,
连接至核心板:
即:GPA0_0 GPA0_1 配置引脚为串口专用模式:
然后看
ULCONn [31:0] 0x3
设置串口一帧传输数据的一帧对应的数据位为8倍,1位停止位,无奇偶校验位
UCONn [31:0] 0x5
选择串口收发的模式为polling模式
UFCONn [31:0] 0x0
选择传输的模式为非FIFO模式
UMCONn [31:0] 0x0
禁用硬件流控
UBRDIVn | Specifies baud rate divisor |
UFRACVALn | Specifies divisor fractional value |
用于控制波特率
目前采用的时钟源是100Mhz,一会再来验证。
UBRDIVn = (100000000 / 115200 / 16 - 1 ) = 53.253472222222222222222222222222 取整数
UFRACVALn = (53.2534722 - 53 )*16 = 4.05555 取整数
即配置为波特率为115200
UTRSTATn
从串口接收一个字节的数据:
读寄存器:
发送一个字节的数据,等待发送缓存寄存器无要发送的数据
写入寄存器:
1 #ifndef TINY4412_LIB_H_ 2 #define TINY4412_LIB_H_ 3 4 typedef unsigned int u32; 5 typedef unsigned short u16; 6 typedef unsigned char u8; 7 8 extern u32 read32(u32 reg); 9 extern u16 read16(u32 reg); 10 extern u8 read8(u32 reg); 11 extern void write8(u8 val, u32 reg); 12 extern void write16(u16 val, u32 reg); 13 extern void write32(u32 val, u32 reg); 14 15 #define udelay ((void (*)(int))0x43e26480) 16 #define printf(...) (((int (*)(const char *, ...))0x43e11a2c)(__VA_ARGS__)) 17 18 #endif
编写uart.c
1 #include <uart.h> 2 #include <stdarg.h> 3 4 /*串口0的初始化*/ 5 void uart0_init(void) 6 { 7 u32 val; 8 9 /*设置GPA0[0:1]引脚为串口0专用的收发引脚*/ 10 val = read32(GPA0CON); 11 val &= ~0xff; 12 val |= 0x22; 13 write32(val, GPA0CON); 14 15 /*设置串口传输数据的一帧对应的数据位为 16 8位,1位停止位,无奇偶校验位*/ 17 write32(0x3, ULCONn); 18 19 /*选择串口收发的模式为polling模式*/ 20 write32(0x5, UCONn); 21 22 /*选择传输的模式为非FIFO模式*/ 23 write32(0x0, UFCONn); 24 25 /*禁用硬件流控*/ 26 write32(0x0, UMCONn); 27 28 /*设置波特率为115200, 根据手册1399的公式推出*/ 29 write32(53, UBRDIVn); 30 write32(4, UFRACVALn); 31 32 /*时钟源的选择: MPLL_USER_T, MPLL*/ 33 val = read32(CLK_SRC_PERIL0); 34 val &= ~0xf; 35 val |= 0x6; 36 write32(val, CLK_SRC_PERIL0); 37 38 /*分频*/ 39 val = read32(CLK_DIV_PERIL0); 40 val &= ~0xf; 41 val |= 0x7; 42 write32(val, CLK_DIV_PERIL0); 43 } 44 45 void uputchar(int ch) 46 { 47 /*等待发送缓存寄存器无要发送的数据*/ 48 while (!(read32(UTRSTATn) & 0x2)) { 49 ; 50 } 51 52 write8(ch, UTXHn); 53 54 if (ch == '\n') { 55 uputchar('\r'); 56 } 57 } 58 59 /*从串口接收一个字节的数据*/ 60 int ugetchar(void) 61 { 62 int val; 63 64 /*等待串口控制器接收到有效数据*/ 65 while (!(read32(UTRSTATn) & 0x1)) { 66 ; 67 } 68 69 val = read8(URXHn); 70 if (val == '\r') { 71 val = '\n'; 72 } 73 74 uputchar(val); 75 76 return val; 77 } 78 79 80 char *ugets(char *buf) 81 { 82 int ch; 83 84 char *tmp = buf; 85 86 while ((ch = ugetchar()) != '\n') { 87 *tmp++ = ch; 88 } 89 90 *tmp = '\0'; 91 92 return buf; 93 } 94 95 void uputs(const char *buf) 96 { 97 while (*buf) { 98 uputchar(*buf); 99 buf++; 100 } 101 } 102 103 /*93 --> "5d"*/ 104 void xtoa(int n, char *buf) 105 { 106 int i; 107 if (n < 16) { 108 if (n < 10) { 109 buf[0] = '0' + n; 110 } else { 111 buf[0] = n - 10 + 'a'; 112 } 113 buf[1] = '\0'; 114 115 return; 116 } 117 118 xtoa(n/16, buf); 119 120 for (i = 0; buf[i] != '\0'; i++); 121 122 if ((n%16) < 10) { 123 buf[i] = (n%16) + '0'; 124 } else { 125 buf[i] = (n%16) - 10 + 'a'; 126 } 127 128 buf[i+1] = '\0'; 129 } 130 131 /*93 --> "93" */ 132 void itoa(int n, char *buf) 133 { 134 int i; 135 136 if (n < 10) { 137 buf[0] = n + '0'; 138 buf[1] = '\0'; 139 return; 140 } 141 142 itoa(n/10, buf); 143 144 for (i = 0; buf[i] != '\0'; i++) { 145 ; 146 } 147 148 buf[i] = (n%10) + '0'; 149 buf[i+1] = '\0'; 150 } 151 152 void uprintf(const char *fmt, ...) 153 { 154 int val; 155 va_list va; 156 char buf[32]; 157 158 va_start(va, fmt); 159 160 while (*fmt) { 161 if (*fmt == '%') { 162 fmt++; 163 switch (*fmt) { 164 case 'c': 165 uputchar(va_arg(va, int)); 166 break; 167 case 'd': 168 val = va_arg(va, int); 169 if (val < 0) { 170 uputchar('-'); 171 val = 0 - val; 172 } 173 itoa(val, buf); 174 uputs(buf); 175 break; 176 case 'x': 177 val = va_arg(va, int); 178 xtoa(val, buf); 179 uputs(buf); 180 break; 181 case 's': 182 uputs(va_arg(va, char *)); 183 break; 184 default: 185 break; 186 } 187 } else { 188 uputchar(*fmt); 189 } 190 191 fmt++; 192 } 193 }
测试用例就直接调用uprintf可以测试所有功能。