中科蓝讯530X、532X模块之硬件UART
2024-10-09 13:16:27
文章转载请注明来源 作者:Zeroer
一、选择IO
想要使用硬件的UART必须先确定要mapping的pin脚
注意:用作TX的脚位可以分时复用成单线双工
因为芯片默认的调试串口用的是UART0,所以我们在做功能的时候使用UART1和UART2可以不用重新banding我们的调试接口
首先选择好我们的脚位后,对我们的IO进行初始化,我们以UART2的PB1、PB2为例
GPIOBDE |= (BIT(2) | BIT(1)); //As Digital IO
GPIOBPU |= (BIT(2) | BIT(1)); //pull-up 10K
GPIOBDIR &= ~BIT(2); //output
GPIOBDIR |= BIT(1); //input
GPIOBFEN |= (BIT(2) | BIT(1)); //set function io
因为UART是属于我们的功能io,所以在初始化的时候需要将io配置为功能io,且一个脚同时只能有一个功能
二、配置IO映射
接下来对我们的IO映射到我们的UART功能上
FUNCMCON1 = (0xff<<4); //Clear mapping
//two line mode
FUNCMCON1 = ((0x2<<4)|(0x2<<8)); //Map to Group 2
//single mode
FUNCMCON1 = ((0x2<<4)|(0x3<<8)); //Map to Group 2 and map RX pin by TX pin
↑↑↑这个是UART2的map寄存器以及占位
FUNCMCON0 = (0xff<<24); //Clear mapping
//two line mode
FUNCMCON0 = ((0x2<<24)|(0x2<<28)); //Map to Group 2
//single mode
FUNCMCON0 = ((0x2<<24)|(0x3<<28)); //Map to Group 2 and map RX pin by TX pin
↑↑↑这个是UART1的map寄存器以及占位
FUNCMCON0 = (0xff<<8); //Clear mapping
//two line mode
FUNCMCON0 = ((0x2<<8)|(0x2<<12)); //Map to Group 2
//single mode
FUNCMCON0 = ((0x2<<8)|(0x3<<12)); //Map to Group 2 and map RX pin by TX pin
↑↑↑这个是UART0的map寄存器以及占位
选择我们使用的寄存器通道以及单线或者双线模式
三、UART参数配置
继续对UART功能进行配置,先对我们UART的参数进行设置
UART2CON = 0;
UART2CON |= (BIT(5)|BIT(7)|BIT(2));
我们选择打开了Rx的中断接收,然后将时钟源切换到uart的独立时钟,然后我们对时钟进行设置
CLKCON1 |= BIT(14); //select 26M div2
CLKGAT1 |= BIT(11); //clk enble
u32 baud = (26000000 / 2 + 115200 / 2) / 115200 - 1; //baud: 115200
UART2BAUD = ((baud<<16) | baud);
最后配置完所有的东西后,我们打开我们的UART,然后注册我们的中断函数
UART2CON |= BIT(0);
sys_irq_init(IRQ_UART_VECTOR, 0, uart2_isr_func);
这时候我们需要提供一个名为uart2_isr_func(也可以任意命名)的函数处理中断
u8 data = 0; AT(.com_text.isr)
void uart2_isr_func(void)
{
if (UART2CON & BIT(9)){
UART2CPND |= BIT(9);
data = UART2DATA;
}
}
中断函数必须要用AT宏放到ram区域去,接下来我们写一个发送函数就完成了
void uart2_send(char *data, u8 len)
{
for(int i=0; i<len; i++)
{
while(!(UART2CON & BIT(8)));
UART2DATA = data[i];
}
}
四、总结
如果我们需要使用到UART0,我们就需要给调试接口重新写一个UART然后通过binding将print通过UART输出。
void my_printf_init(void (*putchar)(char));
最后我将完整的代码贴在后面提供给大家测试调试,会和前面的代码有一些差异,但是功能是一样的
char recv_buf[128];
u8 recv_len = 0;
AT(.com_rodata.isr)
const char ptr_t3[] = "RX:%lx\n";
AT(.com_rodata.isr)
const char ptr_r3[] = "TX:%lx\n";
AT(.com_text.isr)
void uart2_isr_func(void) //FIQ
{
if (UART2CON & BIT(9)){
UART2CPND |= BIT(9);
if (recv_len < 128) {
recv_buf[recv_len] = UART2DATA;
recv_len++;
} else {
memset(recv_buf, 0, sizeof(recv_buf));
recv_len = 0;
}
}
} void uart2_send(char *data, u8 len)
{
printf(ptr_r3,data[0]);
for(int i=0; i<len; i++)
{
while(!(UART2CON & BIT(8)));
UART2DATA = data[i];
}
}
#define BAUD_UART2 ((26000000/2+2000000/2)/2000000-1)
void uart2_init(void)
{
printf("%s\n",__func__); GPIOBDE |= (BIT(2) | BIT(1));
GPIOBPU |= (BIT(2) | BIT(1));
GPIOBDIR &= ~BIT(2);
GPIOBDIR |= BIT(1);
GPIOBFEN |= (BIT(2) | BIT(1)); FUNCMCON1 = (0xff<<4);
FUNCMCON1 = ((0x02<<4)|(0x02<<8)); UART2CON = 0;
UART2CON |= (BIT(5)|BIT(7)|BIT(2)); CLKCON1 |= BIT(14);
CLKGAT1 |= BIT(11); UART2BAUD = ((BAUD_UART2<<16) | BAUD_UART2); UART2CON |= BIT(0);
sys_irq_init(IRQ_UART_VECTOR, 0, uart2_isr_func);
}
最新文章
- java 利用ManagementFactory获取jvm,os的一些信息--转
- 调用altera IP核的仿真流程—下
- Android MediaMetadataRetriever 读取多媒体文件信息,元数据(MetaData)
- APICloud开发App总结(一)
- DevExpress应用案例--语音识别器Dual Writer
- 阿里巴巴集团2016校园招聘-Python工程师笔试题(附加题+部分答案)
- What is /proc/slabinfo?
- 支付宝Wap支付你了解多少?
- 对称加密DES和TripleDES
- BZOJ 1036 树的统计-树链剖分
- list 容器 排序函数.xml
- SQL 教程学习进度备忘
- [Everyday Mathematics]20150112
- MVC客户端验证的小示例
- 系统ls命令出现1;2cl;2cl;2cl;2c(转)
- [转]Breaking Bad With DTrace
- js基础整理总结
- PMP(第六版)十大知识领域、五大项目管理过程组、49个过程矩阵
- springboot整合redis(简单整理)
- golang 打包,交叉编译,压缩