1.先学习uart原理
2.此次uart选择使用主频fclk,需要先配置分频,此次不过多赘述,配置分频在前面我发的蜂鸣器章节,直接默认配置好,开启此次uart。先配置uart线路控制器,选择红外中的普通模式,无奇偶校验,一位停止位,八位数据。
3.选择时钟FCLK/n,配置分频,此次使用40分频,即赋为4即可,4+36 =40,设置使能。
如果不想这莫麻烦直接选择pclk,这里的其他就都不用设置,当然后面的设置有细微改变。
发送接收选择轮询模式
4.此次设置波特率为9600, uart时钟为fclk(400)/40 = 10,根据公式算出波特率分频约为64,设置寄存器
5.设置fifo(数据缓存器),使能fifo,复位发送接收 tx rx fifo
也可以不选择fifo,就可以不用设置,后面5,6,7步可以不用设置。
6.配置此次urat可以中断irq触发,ufcon0四五位先清零,第四位设置为1(rxfifo为8字节深度),ucon0第七位设置为1超时使能,根据手册找出db0端口引脚,然后根据其可以使能INT_UART0第28位,使能INT_RXD0第0位。
7.此次不重点写中断配置,可以参考以前的文章,此次仅写中断的处理,其他细节不写。
当subsrcpnd寄存器第0位请求时,进行处理,可以接收数据,再把接收到的发回去,此文章大概写流程,也可以在此框架上加其他应用场合。
8.进行接收函数,形参是字符数组的地址,期待接收数据大小,通过UFSTAT0 & 0x3f可以获得寄存器中数据大小,根据期待大小和数据大小对比来接收数据,在urxh0里接收数据
当然如果前面未选择fifo,可以不用这个,使用下面这个缓存,包括收发,此次我不描述,可以自己试。
9.写发送函数,往发送寄存器放数据
10.大概流程完成,来实现代码。
初始化uart
void uart0_init(void)
{
//uart0 9600 8 n 1
//配置GPH2/3功能为uart0 rxd/txd
GPHCON &= ~(0xf << 4);
GPHCON |= (0xa << 4);
ULCON0 &= ~(1 << 6); //普通模式
ULCON0 &= ~(0x7 << 3); //无校验
ULCON0 &= ~(1 << 2); //1位停止位
ULCON0 |= (0x3 << 0); //8位数据位
UCON2 &= ~(0x7 << 12);
UCON2 |= (0x4 << 12); //分频系数为40(4 + 36)
//UCON0\1[15:12]必须为0,此处默认为0
UCON2 |= (1 << 15); //使能FCLK/n
UCON0 |= (0x3 << 10); //uart时钟选择FCLK/n
UCON0 &= ~(0xf << 0);
UCON0 |= (0x5 << 0); //中断或轮询模式
UBRDIV0 = 64;
//fifo
UFCON0 |= (1 << 0); //使能fifo
UFCON0 |= (0x3 << 1); //复位fifo(r\t)
// irq
UFCON0 &= ~(0x3 << 4);
UFCON0 |= (0x1 << 4); //触发深度8字节
UCON0 |= (1 << 7); //RX超时使能
INTMSK &= ~(1 << 28); //使能INT_UART0
INTSUBMSK &= ~(1 << 0); //使能INT_RXD0
}
中断处理
void uart0_handle(void)
{
if(SUBSRCPND & (1 << 0))
{
unsigned char data[64] = {0};
unsigned char num = 0;
num = uart0_recv(data, sizeof data);
uart0_send(data, num);
SUBSRCPND |= (1 << 0);
}
}
接收代码
unsigned char uart0_recv(unsigned char * data, unsigned char len)
{
int i = 0;
unsigned char num = UFSTAT0 & 0x3f;
unsigned char r_num = (num < len) ? num : len;
for(i = 0; i < r_num; i++)
{
data[i] = URXH0;
}
return i;
}
发送代码
int uart0_send(unsigned char * data, unsigned char len)
{
int i = 0;
for(i = 0; i < len; i++)
{
while(!(UTRSTAT0 & (1 << 2)));
UTXH0 = data[i];
}
return i;
}
代码仅供参考,个人需求不同,代码不同。
11.实现结果