(三) UART 串口通讯
UART : university asynchronous receiver and transmitter UART // 通用异步接收器和发送器
为什么要有串口:因为许多嵌入式设备没有显示屏,无法获得设备的实事数据信息,所以可以通过 UART 串口和超级终端相连,打印嵌入式设备输出信息。也可以通过串口跟踪和调试。
比如设备: 网络路由器、交换机通过串口配置, GPS接收器通过串口输出GPS接收的数据。
1、异步通信技术:发送和接收方没有同步时钟,只有数据线,但是协商好了协议,(固定频率)进行数据采样。 即 波特率 bit per second 保证正确性
2、传输模式: 轮询模式、中断模式、DMA模式
3、S3C2440 UART 控制器 :
UART 接收装置和发送装置 包含一个 64Bytes 的缓冲器(所以分为 缓冲模式 和 非缓冲模式)
4、数据帧: 是 uart 最基本的通信单元,包含 开始位、数据位、校验位、停止位(双方约定好数据帧,指定同一波特率,确保数据传输同步)
具体还是要看芯片手册相关寄存器,不是很难。
——————————————————————————————————————————————————————————————————————————
F:\ARM+LINUX\深入浅出底层嵌入式开发\work\armarch\uart_init
启动代码:
; ; UART串口实验 ; GPBCON EQU 0x56000010 GPBDAT EQU 0x56000014 AREA Init, CODE, READONLY ENTRY start ; close watchdog ldr r0, = 0x53000000 ; 将看门狗控制寄存器地址放入r0 mov r1, #0 str r1, [r0] ; 设置看门狗控制寄存器的值为0 bl initmem ; 跳转到initmem代码段,初始化内存 IMPORT xmain ; 引入main.c中的xmain函数 ldr sp, =0x34000000 ; 调用C程序之前先初始化栈指针 ldr lr, =loop ; 设置xmain函数的返回地址 ldr pc, =xmain ; 跳转到C程序中的xmain函数的入口处执行 loop b loop ; 死循环 initmem ; 内存初始化 ldr r0, =0x48000000 ; 加载内存相关寄存器首地址r0 ldr r1, =0x48000034 ; 加载内存相关寄存器尾地址到r1 adr r2, memdata ; 将寄存器配置数据地址段首地址加载到r2 initmemloop ldr r3, [r2], #4 ; 循环设置存寄存器 str r3, [r0], #4 teq r0, r1 bne initmemloop ; 循环到最后一个寄存器时退出函数 bx lr memdata DCD 0x22000000 ;BWSCON DCD 0x00000700 ;BANKCON0 DCD 0x00000700 ;BANKCON1 DCD 0x00000700 ;BANKCON2 DCD 0x00000700 ;BANKCON3 DCD 0x00000700 ;BANKCON4 DCD 0x00000700 ;BANKCON5 DCD 0x00018005 ;BANKCON6 DCD 0x00018005 ;BANKCON7 DCD 0x008e07a3 ;REFRESH DCD 0x000000b1 ;BANKSIZE DCD 0x00000030 ;MRSRB6 DCD 0x00000030 ;MRSRB7 END
xmain 函数
1 /* xmain.c */ 2 3 /* GPIO registers */ 4 #define GPHCON (*(volatile unsigned long *)0x56000070) 5 #define GPHDAT (*(volatile unsigned long *)0x56000074) 6 #define GPHUP (*(volatile unsigned long *)0x56000078) 7 8 /*UART registers*/ 9 #define ULCON0 (*(volatile unsigned long *)0x50000000) 10 #define UCON0 (*(volatile unsigned long *)0x50000004) 11 #define UFCON0 (*(volatile unsigned long *)0x50000008) 12 #define UMCON0 (*(volatile unsigned long *)0x5000000c) 13 #define UTRSTAT0 (*(volatile unsigned long *)0x50000010) 14 #define UTXH0 (*(volatile unsigned char *)0x50000020) 15 #define URXH0 (*(volatile unsigned char *)0x50000024) 16 #define UBRDIV0 (*(volatile unsigned long *)0x50000028) 17 18 #define TXD0READY (1<<2) //发送数据状态OK 19 #define RXD0READY (1) //接收数据状态OK 20 21 /* UART串口初始化 */ 22 void uart_init( ) 23 { 24 GPHCON |= 0xa0; //GPH2,GPH3 used as TXD0,RXD0 25 GPHUP = 0x0; //GPH2,GPH3内部上拉 26 ULCON0 = 0x03; //8N1 27 UCON0 = 0x05; //查询方式为轮询或中断;时钟选择为PCLK 28 UFCON0 = 0x00; //不使用FIFO 29 UMCON0 = 0x00; //不使用流控 30 UBRDIV0 = 12; //波特率为57600,PCLK=12Mhz 31 } 32 33 /* UART串口单个字符打印函数 */ 34 extern void putc(unsigned char c) 35 { 36 while( ! (UTRSTAT0 & TXD0READY) ); 37 UTXH0 = c; 38 } 39 40 /* UART串口接受单个字符函数 */ 41 extern unsigned char getc(void) 42 { 43 while( ! (UTRSTAT0 & RXD0READY) ); 44 return URXH0; 45 } 46 47 /* UART串口字符串打印函数 */ 48 extern int printk(const char* str) 49 { 50 int i = 0; 51 while( str[i] ){ 52 putc( (unsigned char) str[i++] ); 53 } 54 return i; 55 } 56 57 __inline void delay(int msec) 58 { 59 int i, j; 60 for(i = 1000; i > 0; i--) 61 for(j = msec*10; j > 0; j--) 62 /* do nothing */; 63 } 64 65 /* xmain 通过UART串口打印字符串 */ 66 int xmain() 67 { 68 uart_init(); 69 while(1) 70 { 71 delay(10); 72 printk("Uart串口打印试验\r\n"); 73 } 74 // return 0; 这句省去,这样 就不会出现 statement is unreachable 75 }
烧到nor flash ,自己到超级终端自己摸索!!!!(参考:杨铸 P151 页)