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 Flag
	UART_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时钟,必须要加delay
	
	while(!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 1
	if ((UART_0_CTRL->TI) == 1)
	{
		UART_0_CTRL->TI = 0;
	}
#endif

	if((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函数在后续的例程中都会用得到。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值