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