当前位置: 首页 > article >正文

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

 

 


http://www.kler.cn/a/297895.html

相关文章:

  • ML 系列:机器学习和深度学习的深层次总结(01)
  • 时不我待,与 AI 共舞的新时代已经来临!!!【附全套AI大模型学习资料】
  • Docker Compose version v2.29.2 提示 exited with code 0 解决方案
  • VUE3+Vite 环境变量配置
  • 网络底层协议(包括TR-069、IGMP、VOIP、DHCP、PPPoE、802.11)的分析
  • 11.Java基础概念-ArrayList
  • 电压跟随器的作用是什么?
  • 【redis】认识redis和分布式系统
  • EasyExcel的导入与导出及在实际项目生产场景的一下应用例子
  • 上交团队发布PathoDuet:面向HE和IHC病理切片的自监督学习基础模型|文献精析·24-09-09
  • AIGC 初识 GAN(Generative Adversarial Networks,生成对抗网络)是如何工作的,浅记。
  • 2414. Length of the Longest Alphabetical Continuous Substring
  • CTK框架(七):事件监听
  • STM32 HAL DMA 中断碰到的问题
  • OpenGL Texture C++ 预览Camera视频
  • HTML生日蛋糕
  • 数据分析-17-时间序列分析的平稳性检验
  • .NET 一款免安装运行Python的渗透工具
  • UE驻网失败问题(三)
  • 设计模式 20 状态模式