串口发送数据的原理
CPU-----(数据写入)-----FIFO----(UART自动复制)------发送移位器----(一位一位发送到)------TxDn
串口接受数据的原理
RxDn-----(一位一位接收到)-----接受移位器-----(复制到)-----FIFO-----(读取数据)------CPU
初始化:
1.波特率、传输格式(多少个数据,是否使用校验位,是奇校验还是偶校验,有多少个停止位,是否使用流量控制)
2.选择设计管脚的UART功能,选择UART通道工作模式为中断模式或者DMA模式
#define PCLK 50000000 // init.c中的clock_init函数设置PCLK为50MHz
#define UART_CLK PCLK // UART0的时钟源设为PCLK
#define UART_BAUD_RATE 115200 // 波特率
#define UART_BRD ((UART_CLK / (UART_BAUD_RATE * 16)) - 1)
/*
* 初始化UART0
* 115200,8N1,无流控
*/
void uart0_init(void)
{
GPHCON |= 0xa0; // GPH2,GPH3用作TXD0,RXD0
GPHUP = 0x0c; // GPH2,GPH3内部上拉
ULCON0 = 0x03; // 8N1(8个数据位,无较验,1个停止位)
UCON0 = 0x05; // 查询方式,UART时钟源为PCLK
UFCON0 = 0x00; // 不使用FIFO
UMCON0 = 0x00; // 不使用流控
UBRDIV0 = UART_BRD; // 波特率为115200
}
设置好之后,往某个寄存器之中写入数据即可发送,读取某个寄存器即可收到数据,可以通过查询状态寄存器或者中断查询情况
#define TXD0READY (1<<2)
#define RXD0READY (1)
void putc(unsigned char c)
{
/* 等待,直到发送缓冲区中的数据已经全部发送出去 */
while (!(UTRSTAT0 & TXD0R EADY));
/* 向UTXH0寄存器中写入数据,UART即自动将它发送出去 */
UTXH0 = c;
}
/*
* 接收字符
*/
unsigned char getc(void)
{
/* 等待,直到接收缓冲区中的有数据 */
while (!(UTRSTAT0 & RXD0READY));
/* 直接读取URXH0寄存器,即可获得接收到的数据 */
return URXH0;
}
各种寄存器的作用
UBRDIVn 设置波特率
ULCONn 设置传输格式
UCONn 选择UART时钟源,设置UART中断方式
UFCONn 设置是否使用FIFO
UFSTATn 各个FIFO是否已满
#include "serial.h"
int main()
{
unsigned char c;
uart0_init(); // 波特率115200,8N1(8个数据位,无校验位,1个停止位)
while(1)
{
// 从串口接收数据后,判断其是否数字或子母,若是则加1后输出
c = getc();
if (isDigit(c) || isLetter(c))
putc(c+1);
}
return 0;
}