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的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/252941

相关文章

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

Nn criterions don’t compute the gradient w.r.t. targets error「pytorch」 (debug笔记)

Nn criterions don’t compute the gradient w.r.t. targets error「pytorch」 ##一、 缘由及解决方法 把这个pytorch-ddpg|github搬到jupyter notebook上运行时,出现错误Nn criterions don’t compute the gradient w.r.t. targets error。注:我用

电脑驱动分类

电脑驱动程序(驱动程序)是操作系统与硬件设备之间的桥梁,用于使操作系统能够识别并与硬件设备进行通信。以下是常见的驱动分类: 1. 设备驱动程序 显示驱动程序:控制显卡和显示器的显示功能,负责图形渲染和屏幕显示。 示例:NVIDIA、AMD 显示驱动程序。打印机驱动程序:允许操作系统与打印机通信,控制打印任务。 示例:HP、Canon 打印机驱动程序。声卡驱动程序:管理音频输入和输出,与声卡硬件

麒麟系统安装GPU驱动

1.nvidia 1.1显卡驱动 本机显卡型号:nvidia rtx 3090 1.1.1下载驱动 打开 https://www.nvidia.cn/geforce/drivers/ 也可以直接使用下面这个地址下载 https://www.nvidia.com/download/driverResults.aspx/205464/en-us/ 1.1.3安装驱动 右击,

idea 怎么调试debug

1、这里以一个web工程为例,点击图中按钮开始运行web工程。 2、设置断点 3、使用postman发送http请求 4、请求发送之后会自动跳到断点处,并且在断点之前会有数据结果显示 5、按F8 在 Debug 模式下,进入下一步,如果当前行断点是一个方法,则不进入当前方法体内,跳到下一条执行语句。 6、按F7在 Debug 模式下,进入下一步,如果当

windows10 卸载网络驱动以及重新安装

右键桌面此电脑的图标,点击管理,设备管理器—网络适配器,找到下图中的驱动(不同的系统或者显卡会导致网卡驱动名称与下图不一样,多为Realtek开头),右键选择卸载设备,然后重启电脑,系统会自动重新安装驱动 新电脑首次安装驱动: 根据主板厂家,比如华硕,进入华硕官网,点击服务支持,点击下载中心,选择型号,点击右侧驱动程序和工具软件,选择windows版本,下载相应的驱动,下载完之后在对应文件中找

笔记整理—内核!启动!—kernel部分(1)驱动与内核的关系

首先,恭喜完成了uboot部分的内容整理,其次补充一点,uboot第一部分和第二部分的工作不是一定的,在不同的版本中,可能这个初始化早一点,那个的又放在了第二部分,版本不同,造成的工作顺序不同,但终归是要完成基本内容初始化并传参给kernel的。         那么至于驱动与内核的关系,用一张图来说明最适合不过:         驱动位于OS层的中下层与硬件相接。驱动是内