实现printf重定向和delay_ms对于MCU开发来说非常基本又十分重要,可以为项目的开发提供调试和基本的延时功能。
一、printf重定向
1、UART引脚初始化
<pre> //init UART pin
PA2_INIT(PA2_UART1_TX);
PA3_INIT(PA3_UART1_RX);</pre>
复制代码2、UART初始化及RX中断使能
UART_Open(UART1,115200,UART_NO_PARITY,UART_TRIGGER_LEVEL_1_BYTE);
3、发送一个字节
<pre>#define DATA 0x5A
//send a test data
if (UART1->LSR_b.THRE) //Transmitter Holding Register Empty
UART1->THR=DATA; // THR:Transmit Holding Register</pre>
复制代码4、实现printf重定向
将me32g03xxxxx lib 20240710\cmsis\Device\ARM\ME32G030\Source\retarget.c加入工程
修改SendChar_ToUART函数,将UART0修改为UART1,因为开发板上使用的是UART1。
<pre>void SendChar_ToUART(int ch)
{
while(UART1->LSR_b.THRE==0);
UART1->THR= ch;
if(ch == '\n')
{
while(UART1->LSR_b.THRE==0);
UART1->THR= '\r';
}
}
</pre>
复制代码5、RX接收中断处理
接收到数据,TX回显
<pre>void UART1_IRQHandler(void)
{
uint8_t byte_data;
if (UART1->LSR_b.RDR) //RDR:Receiver Data Ready
{
if((UART1->LSR_b.THRE)) //THRE:Transmitter Holding Register Empty
{
byte_data = UART1->RBR; //RBR:Receiver Buffer Register
UART1->THR= byte_data; //THR: Transmit Holding Register
}
}
</pre>
复制代码6、可以使用printf了
<pre> //Loop forever
while(1)
{
printf("【ME32G030 评测】1、printf重定向\r\n");
//SYS_Delay(65535);
//SYS_Delay(65535);
//SYS_Delay(65535);
delay_ms(1000);
}</pre>
复制代码SYS_Delay延时很不准确,所以要实现一个delay_ms函数
二、SysTick延时
1、初始化SysTick定时器
<pre>extern uint32_t SystemCoreClock;
// 初始化SysTick定时器
void SysTick_Init(void)
{
SysTick->CTRL = 0; // 先关闭 SysTick
SysTick->LOAD = SystemCoreClock / 1000 - 1; // 1ms 重载值
SysTick->VAL = 0; // 清空计数器
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk // 使用 CPU 时钟
| SysTick_CTRL_ENABLE_Msk; // 启用 SysTick(但不启用中断)
}</pre>
复制代码2、delay_ms
<pre>// 毫秒级延时
void delay_ms(uint32_t ms)
{
uint32_t i;
for(i=0;i<ms;i++)
{
SysTick->VAL = 0; // 清空计数器
while (!(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk)); // 等待 1ms 到达
}
}</pre>
复制代码