Linux 硬件uart通信

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.实现结果 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值