1、universal asynchronous reciver and transmitter 通用异步收发器
2、transmitter:由发送缓冲区和发送移位器构成。发送信息时,首先将信息编码(一般用ASCII码)成二进制流,然后将一帧数据(一般是8位)写入发送缓冲区,发送移位器会自动从发送缓冲区中读取一帧数据,然后自动移位将其发送到Tx通信线上。
receiver:由接收缓冲区和接收移位器构成。当通过串口线发送信息时,信息通过Rx通信线进入接收移位器,然后接收移位器自动移位将该二进制位保存入接收缓冲区,接收完一帧数据后receiver会产生一个中断给CPU,CPU收到中断后即可知道receiver接收满了一帧数据,就会来读取这帧数据。
发送移位器和接收移位器的工作都是自动的,不用编程控制,所以我们写串口的代码步骤:首先初始化(初始化的实质是读写寄存器)串口控制器(包括发送控制器和接收控制器),然后将要发送信息时直接写入发送缓冲区,要接收信息时直接去接收缓冲区读取即可。
3、DMA:direct memory access 直接内存访问 该模式适合大量数据迸发式的发送/接收
4、IrDA:红外通信
5、串口初始化步骤:
(1)初始化串口的Tx和Rx引脚所对应的GPIO(Tx和Rx分别对应GPA0_1和GPA0_0)
(2)GPA0CON(0xE0200000),bit[3:0] = 0b0010 bit[7:4] = 0b0010
(3)初始化关键寄存器 UCON0 ULCON0 UMCON0 UFCON0 UBRDIV0 UDIVSLOT0
6、实战例子
1 #define GPA0CON 0xE0200000 2 #define UCON0 0xE2900004 3 #define ULCON0 0xE2900000 4 #define UMCON0 0xE290000C 5 #define UFCON0 0xE2900008 6 #define UBRDIV0 0xE2900028 7 #define UDIVSLOT0 0xE290002C 8 #define UTRSTAT0 0xE2900010 9 #define UTXH0 0xE2900020 10 #define URXH0 0xE2900024 11 12 #define rGPA0CON (*(volatile unsigned int *)GPA0CON) 13 #define rUCON0 (*(volatile unsigned int *)UCON0) 14 #define rULCON0 (*(volatile unsigned int *)ULCON0) 15 #define rUMCON0 (*(volatile unsigned int *)UMCON0) 16 #define rUFCON0 (*(volatile unsigned int *)UFCON0) 17 #define rUBRDIV0 (*(volatile unsigned int *)UBRDIV0) 18 #define rUDIVSLOT0 (*(volatile unsigned int *)UDIVSLOT0) 19 #define rUTRSTAT0 (*(volatile unsigned int *)UTRSTAT0) 20 #define rUTXH0 (*(volatile unsigned int *)UTXH0) 21 #define rURXH0 (*(volatile unsigned int *)URXH0) 22 23 // 串口初始化程序 24 void uart_init(void) 25 { 26 // 初始化Tx Rx对应的GPIO引脚 27 rGPA0CON &= ~(0xff<<0); // 把寄存器的bit0~7全部清零 28 rGPA0CON |= 0x00000022; // 0b0010, Rx Tx 29 30 // 几个关键寄存器的设置 31 rULCON0 = 0x3; 32 rUCON0 = 0x5; 33 rUMCON0 = 0; 34 rUFCON0 = 0; 35 36 // 波特率设置 DIV_VAL = (PCLK / (bps x 16))-1 37 // PCLK_PSYS用66MHz算 余数0.8 38 //rUBRDIV0 = 34; 39 //rUDIVSLOT0 = 0xdfdd; 40 41 // PCLK_PSYS用66.7MHz算 余数0.18 42 // DIV_VAL = (66700000/(115200*16)-1) = 35.18 43 rUBRDIV0 = 35; 44 // (rUDIVSLOT中的1的个数)/16=上一步计算的余数=0.18 45 // (rUDIVSLOT中的1的个数 = 16*0.18= 2.88 = 3 46 rUDIVSLOT0 = 0x0888; // 3个1,查官方推荐表得到这个数字 47 } 48 49 50 // 串口发送程序,发送一个字节 51 void uart_putc(char c) 52 { 53 // 把一个字节丢到发送缓冲区中,串口开始发送字符 54 // 因为串口控制器发送1个字节的速度远远低于CPU的速度,所以CPU发送1个字节前必须确认串口控制器当前缓冲区是空的 55 // 如果缓冲区非空则位为0,此时应该循环,直到位为1 56 while (!(rUTRSTAT0 & (1<<1))); 57 rUTXH0 = c; 58 } 59 60 // 串口接收程序,轮询方式,接收一个字节 61 char uart_getc(void) 62 { 63 while (!(rUTRSTAT0 & (1<<0))); 64 return (rURXH0 & 0x0f); 65 }