SYD8810外设驱动篇——UART0 Debug Printf

2023-10-21 07:40

本文主要是介绍SYD8810外设驱动篇——UART0 Debug Printf,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

SYD8810是一款QFN32封装,低功耗BLE 5.0 SOC,集成了高性能2.4GHz射频收发机、32位ARM Cortex-M0内核,512KB flash,32KB RAM以及丰富的数字接口,另外片内还集成了Balun无需阻抗匹配网络、高效率DCDC降压转换器,适合用于可穿戴、物联网设备等。

本篇主要介绍如何进行SYD8810的UART0配置以及打印测试。

一、串口知识

USART的全称是Universal synchronous asynchronous receiver transmitter,中文名为通用同步异步收发器。SYD8810的串口属于异步串口,简称UART。

SYD8810 有两组UART,分别是UART0和UART1,UART0除了正常异步串口通讯功能,还兼具下载以及调试DTM的功能,本文先介绍异步串口通讯。

SYD8810的UART0包含两个寄存器,分别是UART_SET和DATA_RX。我们先来看UART_SET寄存器,在这里插入图片描述

其中0:3位是设置通讯波特率,第4位是可接收标识位,第5位是可发送标志位,第6是接收中端屏蔽位,第7位是流控使能位,第8~15是8位发送缓存区;第17位是奇偶校验失败的标志;第18位是奇偶校验失败中断屏蔽位;第19位是UART0使能位,在初始化完成,须使能该位才能使用;第20位是接收检验检测使能;第21位是接收检验方式配置,置1即为偶检验,置0位奇校验;第22位是发送检验检测使能,第23位是发送检验方式配置,置1即为偶检验,置0位奇校验;第24位是接收fifo是否为空的标志;第25位是发送fifo是否满的标志;第28位是发送中断屏蔽位,第29位是置1使接收fifo清空,硬件自动完成。
另外一个是接收数据缓冲寄存器。 在这里插入图片描述

此寄存器主要用于存放接收到8位数据。

二、测试硬件准备

本次验证测试使用的是SYD8810 miniEVK验证板,板上集成了芯科的CP2104 USB-TTL,通过Micro USB线接到PC端,方便用户即可用串口助手打印串口数据。

在这里插入图片描述

SYD8810 miniEVK的功能框图如下,在这里插入图片描述
验证板的UART0使用的引脚为P0.12(RXD)和P0.14(TXD),如果要用板载的USB-TLL,须按下图插上跳线帽。如另外接到别的设备,需要注意将两个设备的TXD和RXD交叉连接。
在这里插入图片描述
将Micro USB线插到板上USB插座,并USB线的另一头插到PC机的USB口。
在这里插入图片描述
板上有一个SWD接口,用户需将此接口的3.3V,SWDIO,SWDCLK,GND分别接到JLINK对应的针脚,也可以使用XH2.54-4P连接线来连接JLINK转接板上的4PIN插座。
在这里插入图片描述
SWD插座上对应引脚名称在板子背面。
在这里插入图片描述

三、驱动代码分析

1. UART0初始化及读写函数如下。

static UART_CTRL_TYPE * UART_0_CTRL = ((UART_CTRL_TYPE *) UART_0_CTRL_BASE);//-------------------------------------------------------------------------------------------------
void uart_0_init(void)
{PIN_CONFIG->PIN_12_SEL = PIN_SEL_UART_RXD0;PIN_CONFIG->PIN_14_SEL = PIN_SEL_UART_TXD0; PIN_CONFIG->PAD_18_INPUT_PULL_UP = 0;PIN_CONFIG->PAD_19_INPUT_PULL_UP = 0;UART_0_CTRL->CLK_SEL = 0;		/* 1=32M, 0=16M */UART_0_CTRL->BAUDSEL = UART_BAUD_115200;UART_0_CTRL->FLOW_EN = UART_RTS_CTS_DISABLE;UART_0_CTRL->RX_INT_MASK = 1;	/* 1=MASK */UART_0_CTRL->TX_INT_MASK = 1;	/* 1=MASK */UART_0_CTRL->PAR_FAIL_INT_MASK = 1; /* 1=MASK */UART_0_CTRL->par_rx_even = 0;	/* 1=Even, 0=Odd */UART_0_CTRL->par_rx_en = 0;		/* 1=Rx Parity check enable */UART_0_CTRL->par_tx_even = 0;	/* 1=Even, 0=Odd */UART_0_CTRL->par_tx_en = 0;		/* 1=Tx Parity check enable *///clr Int FlagUART_0_CTRL->RI = 0;UART_0_CTRL->TI = 0;UART_0_CTRL->PAR_FAIL = 1;UART_0_CTRL->RX_FLUSH = 1;		/* clr rx fifo and set RX_FIFO_EMPTY */NVIC_EnableIRQ(UART0_IRQn);UART_0_CTRL->UART_EN = 1;
}/****************************************************************************
UART0串口写函数
参数: uint8_t data 要发送的数据
注意: 使用这个函数不可使能Tx中断
*****************************************************************************/
void uart_0_write(uint8_t data)
{UART_0_CTRL->TX_DATA = data;while(UART_0_CTRL->TI == 0);UART_0_CTRL->TI = 0;
}/****************************************************************************
UART0串口读Rx FIFO函数
参数:pcnt - 返回读到的字节数pbuf - 指向数据存放的buf
注意: FIFO长度为4,要求接收buf大小至少为4字节
****************************************************************************/
void uart_0_read(uint8_t *pcnt, uint8_t *pbuf)
{uint8_t i = 0;volatile uint8_t dly = 0;		//如果用64M时钟,必须要加delaywhile(!UART_0_CTRL->RX_FIFO_EMPTY){*(pbuf+i) = UART_0_CTRL->RX_DATA;i++;//延时400ns以上dly++;dly++;dly++;		}*pcnt = i;
}void uart_0_close(void)
{UART_0_CTRL->UART_EN = 0;NVIC_DisableIRQ(UART0_IRQn);
}/*****************************************************************************
UART0串口中断函数
注意:RX_FLUSH只能置位RX_FIFO_EMPTY,不能清除RI
*****************************************************************************/
void UART0_IRQHandler(void)
{if ((UART_0_CTRL->RI) == 1){//读数据到buf[]中uint8_t len, buf[4];UART_0_CTRL->RI = 0;		//先清标志,再读数据			uart_0_read(&len, buf);}#if 1if ((UART_0_CTRL->TI) == 1){UART_0_CTRL->TI = 0;}
#endifif((UART_0_CTRL->PAR_FAIL) == 1){UART_0_CTRL->PAR_FAIL = 1;}
}

uart_0_init函数根据寄存器表对个寄存器参数进行配置,波特率为11520,不使用流控。
uart_0_write函数进行发送一个字节操作。
uart_0_read函数进行接收串口数据。
在初始化函数中使能了UART0接收中断,UART0_IRQHandler函数就在数据到来时调用uart_0_read函数接收数据。

2、在debug.c文件中debug printf函数初始化及打印格式配置。

#define MAX_FORMAT_BUFFER_SIZE	(128)
static uint8_t s_formatBuffer[MAX_FORMAT_BUFFER_SIZE];void dbg_init(void)
{uart_0_init();
}void dbg_printf(char *format,...)
{uint8_t iWriteNum = 0,i=0;	va_list  ap;if(!format)return;va_start(ap,format);iWriteNum = vsprintf((char *)s_formatBuffer,format,ap);va_end(ap);if(iWriteNum > MAX_FORMAT_BUFFER_SIZE)iWriteNum = MAX_FORMAT_BUFFER_SIZE;for(i=0;i<iWriteNum;i++){uart_0_write(s_formatBuffer[i]);}
}void dbg_hexdump(char *title, uint8_t *buf, uint16_t sz)
{int i = 0;if (title)dbg_printf((title));for(i = 0; i < sz; i++) {dbg_printf("%02x ",(uint16_t)buf[i]);}dbg_printf("\r\n");
}

在文件开头定义了debug printf函数缓存为128个字节,初始化时调用UART0的初始函数,dbg_printf函数调用了uart_0_write函数进行串口数据发送。

3、主函数

#include "ARMCM0.h"
#include "gpio.h"
#include "debug.h"
#include "lib.h"
#include <string.h>
#include "delay.h"
#include "config.h"uint8_t k;int main()
{	__disable_irq();MCUClockSwitch(SYSTEM_CLOCK_64M_RCOSC);RCOSCCalibration();dbg_init();UartEn(true);dbg_printf("SYD8810 UART0 debug printf demo %s:%s\r\n",__DATE__ ,__TIME__);__enable_irq();	while(1){				dbg_printf("UART0 debug printf times = %d\r\n",k);			k++;delay_ms(1000);	}	
}

例程使用的MDK5进行编译,编译后即可下载看打印效果,具体如下,
在这里插入图片描述

总结,本文的例程是SYD8810的UART0配置115200波特率并循环1秒打印,这个debug printf函数在后续的例程中都会用得到。

这篇关于SYD8810外设驱动篇——UART0 Debug Printf的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:https://blog.csdn.net/fssiot/article/details/108281162
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/252941

相关文章

如何在Ubuntu上安装NVIDIA显卡驱动? Ubuntu安装英伟达显卡驱动教程

《如何在Ubuntu上安装NVIDIA显卡驱动?Ubuntu安装英伟达显卡驱动教程》Windows系统不同,Linux系统通常不会自动安装专有显卡驱动,今天我们就来看看Ubuntu系统安装英伟达显卡... 对于使用NVIDIA显卡的Ubuntu用户来说,正确安装显卡驱动是获得最佳图形性能的关键。与Windo

嵌入式Linux之使用设备树驱动GPIO的实现方式

《嵌入式Linux之使用设备树驱动GPIO的实现方式》:本文主要介绍嵌入式Linux之使用设备树驱动GPIO的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录一、设备树配置1.1 添加 pinctrl 节点1.2 添加 LED 设备节点二、编写驱动程序2.1

嵌入式Linux驱动中的异步通知机制详解

《嵌入式Linux驱动中的异步通知机制详解》:本文主要介绍嵌入式Linux驱动中的异步通知机制,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言一、异步通知的核心概念1. 什么是异步通知2. 异步通知的关键组件二、异步通知的实现原理三、代码示例分析1. 设备结构

usb接口驱动异常问题常用解决方案

《usb接口驱动异常问题常用解决方案》当遇到USB接口驱动异常时,可以通过多种方法来解决,其中主要就包括重装USB控制器、禁用USB选择性暂停设置、更新或安装新的主板驱动等... usb接口驱动异常怎么办,USB接口驱动异常是常见问题,通常由驱动损坏、系统更新冲突、硬件故障或电源管理设置导致。以下是常用解决

C++使用printf语句实现进制转换的示例代码

《C++使用printf语句实现进制转换的示例代码》在C语言中,printf函数可以直接实现部分进制转换功能,通过格式说明符(formatspecifier)快速输出不同进制的数值,下面给大家分享C+... 目录一、printf 原生支持的进制转换1. 十进制、八进制、十六进制转换2. 显示进制前缀3. 指

Goland debug失效详细解决步骤(合集)

《Golanddebug失效详细解决步骤(合集)》今天用Goland开发时,打断点,以debug方式运行,发现程序并没有断住,程序跳过了断点,直接运行结束,网上搜寻了大量文章,最后得以解决,特此在这... 目录Bug:Goland debug失效详细解决步骤【合集】情况一:Go或Goland架构不对情况二:

Linux_kernel驱动开发11

一、改回nfs方式挂载根文件系统         在产品将要上线之前,需要制作不同类型格式的根文件系统         在产品研发阶段,我们还是需要使用nfs的方式挂载根文件系统         优点:可以直接在上位机中修改文件系统内容,延长EMMC的寿命         【1】重启上位机nfs服务         sudo service nfs-kernel-server resta

驱动(RK3588S)第七课时:单节点设备树

目录 需求一、设备树的概念1、设备树的后缀名:2、设备树的语法格式3、设备树的属性(重要)4、设备树格式举例 二、设备树所用函数1、如何在内核层种获取设备树节点:2、从设备树上获取 gpio 口的属性3、获取节点上的属性只针对于字符串属性的4、函数读取 np 结点中的 propname 属性的值,并将读取到的 u32 类型的值保存在 out_value 指向的内存中,函数的返回值表示读取到的

驱动安装注册表指令

HKCR: HKEY_CLASSES_ROOT HKCU: HKEY_CURRENT_USER HKLM: HKEY_LOCAL_MACHINE HKU: HEKY_USER HER: 相对根键

UMDF驱动安装

VS2013 + WDF8.1,UMDF驱动选择User Mode Driver,不要选User Mode Driver 2.0,否则Win7安装有问题,如图 另外,在驱动安装时不要忘记WUDFUpdate_<主版本号><次版本号>.dll文件,具体文件名在INF中查找。此文件可在WDF的安装目录中找到。注意:在WDF的安装目录中会有3个WUDFUpdate_xxx.dll文件,x86,x6