智芯Z20K11x系列是基于ARM CORTEX M0+的中低端微控制器,高达256K P FLASH + 128K D FLASH,2路CANFD接口,4路UART/LIN接口,多种封装类型,适用于车身控制、空调控制、照明控制、中小功率电机控制等各种应用。更多详细的信息可以到智芯官网查看。
智芯官网地址:https://www.zhixin-semi.com
最近用到这个MCU做项目,发现官方的SDK里面有串口的demo但没有串口printf的用法,这对于用串口debug来说没有那么方便,所以我就自己做了。
1 串口代码编写
1、串口初始化
Z20K11x有几组串口,我这里以UART0的PTA11和PTA12为例。
void uart_init(void)
{
/*Uart config struct*/
static const UART_Config_t uartCfg =
{
115200,
UART_DATABITS_8,
UART_PARITY_NONE,
UART_STOPBITS_1,
DISABLE,
40000000,
};
/*Config UART0 clock, enable UART0 module*/
CLK_ModuleSrc(CLK_UART0, CLK_SRC_OSC40M);
CLK_SetClkDivider(CLK_UART0, CLK_DIV_1);
SYSCTRL_EnableModule(SYSCTRL_UART0);
/*Config PortA clock, enable PortE module*/
CLK_ModuleSrc(CLK_PORTA, CLK_SRC_OSC40M);
SYSCTRL_EnableModule(SYSCTRL_PORTA);
/* Inital UART0 */
UART_Init(UART0_ID, &uartCfg);
/*Config UART0 pinmux*/
PORT_PinmuxConfig(PORT_A, GPIO_11, PTA11_UART0_TX);
PORT_PinmuxConfig(PORT_A, GPIO_12, PTA12_UART0_RX);
/*When UART re-open after close, need to check and clear busy status*/
while(ERR == UART_WaitBusyClear(UART0_ID, 7000))
{
(void)UART_ReceiveByte(UART0_ID);
}
}
2、fputc函数重定向
我们常用的printf()
函数在c标准库函数实质是一个宏,它其实调用的是fputc()
函数,而fputc()函数在<stdio.h>
里面是有定义的,但它默认不是指向串口。
如果需要printf()
函数指定到串口上就需要重写fputc()
函数,原理是链接器检查到用户编写了与C库函数相同名字的函数时,优先调用用户编写函数,这样就可实现重定向。
下面以串口0为例重写fputc()
函数。
int fputc(int ch, FILE *f)
{
(void) f;
/* Wait untill FIFO is empty */
while(RESET == UART_GetLineStatus(UART0_ID, UART_LINESTA_TEMT))
{
}
/* Send data */
UART_SendByte(UART0_ID, (uint8_t)ch);
return ch;
}
2 Keil勾选MicroLIB库
除了上述的代码编写,我们还需要在keil上面把MicroLIB库(微库)勾选上,具体原理其实我也不是很懂。
关于MicroLIB库的介绍,官方的解释是:MicroLib 是一个高度优化的库,适用于用 C 编写的基于 ARM 的嵌入式应用程序。与 ARM 编译器工具链中包含的标准 C 库相比,MicroLib 提供了许多嵌入式系统所需的显着代码大小优势。
看了这解释,我好像懂了又好像没有,不过这不重要,反正我知道不勾这个库就用不了printf()函数,那咱勾上就好了。
打开Options for Target
,勾选Use MicroLIB
即可。
结束语
上面的步骤都做完以后就可以使用串口printf()打印数据了,具体的用法和测试图这里就不放了,大家都懂的。
步骤也简单,和stm32的串口重定向原理都一样,用过的同学应该都知道。
好了,关于智芯Z20K11x串口printf重定向的介绍就到这里,如果还有什么问题,欢迎评论区留言或者私信,谢谢。