STM32学习-11-[串口]格式化打印字符串

格式化字符串的编程原理

image
以上是c语言的打印字符串
我们要做的就是重写这个被调用的函数,根据编译平台不同这个函数也是不一样的

重写fputc函数

int fputc(int ch, FILE *f){
	// #1。等待发送数据寄存器为空
	while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
	// #2。写入发数据寄存器当中
	USART_SendData(USART1,(uint8_t)ch);
	return ch;
}

记得包含头文件stdio.h
还有勾选微库的选项

将单片机的格式化时间打印出来

void printCurTime(){
	uint32_t currentTick = GetTick(); // 获取当前的时间
	uint32_t miliseconds = currentTick % 1000; 
	currentTick/=1000;
	uint32_t seconds = currentTick % 60;
	currentTick/=60;
	uint32_t minute = currentTick % 60;
	currentTick/=60;
	uint32_t hour  = currentTick;
	printf("%02u:%02u:%02u.%03u\r\n", hour, minute, seconds, miliseconds);
}

其中GetTick是封装的函数
具体内容参考如下代码,包含时间初始化,延时和获取时间

/**
  ******************************************************************************
  * @file    delay.c
  * @author  lykf
  * @version V 1.0.0
  * @date    2026年8月30日
  * @brief   延迟函数源文件
  ******************************************************************************
  */

#include "delay.h"

__IO uint32_t ulTicks;

static uint8_t delay_initialized_flag = 0;
static float us_per_mini_tick;


//
// @简介:初始化延迟函数
// @返回值:无
//
void Delay_Init(void)
{
	if(!delay_initialized_flag)
	{
		delay_initialized_flag = 1;
		
		RCC_ClocksTypeDef clockinfo = {0};
		uint32_t tmp;
		
		SysTick->CTRL &= ~SysTick_CTRL_ENABLE; // 禁止SYSTICK

		ulTicks = 0;

		RCC_GetClocksFreq(&clockinfo);

		SysTick->CTRL |= SysTick_CTRL_TICKINT; // 开启中断

		// 设置中断优先级为0
		SCB->SHP[7] = 0;

		// 设置自动重装值以保证1ms的时钟
		tmp =  clockinfo.HCLK_Frequency / 1000;
		if(tmp > 0x00ffffff)
		{
			tmp = tmp / 8;
			SysTick->CTRL &= ~SysTick_CTRL_CLKSOURCE; 
		}
		else
		{
			SysTick->CTRL |= SysTick_CTRL_CLKSOURCE; 
		}
		SysTick->LOAD = tmp - 1;

		SysTick->CTRL |= SysTick_CTRL_ENABLE; 
		
		us_per_mini_tick = 1000.0 / ((SysTick->LOAD & 0x00ffffff) + 1);
	}
}

//
// @简介:毫秒级延迟
// @参数:Delay - 延迟时长,以毫秒为单位(千分之一秒)
// @返回值:无
// @注意:不允许在中断响应函数中调用此方法
//
void Delay(uint32_t Delay)
{
	Delay_Init();
	
	uint64_t expiredTime = ulTicks + Delay;

	while(ulTicks <  expiredTime){}
}

//
// @简介:获取当前时间,以毫秒(千分之一秒)为单位
// @参数:无
// @返回值:当前时间,单位为毫秒(千分之一秒)
//
uint32_t GetTick(void)
{
	Delay_Init();
	
	return ulTicks;
}

//
// @简介:获取当前的微秒级时间
// @返回值:当前的微秒级时间
//
uint64_t GetUs(void)
{
	Delay_Init();
	
	uint64_t tick;
	uint32_t mini_tick;
	
	SysTick->CTRL &= ~SysTick_CTRL_COUNTFLAG; // 清除COUNTFLAG
	
	tick = ulTicks; // 读取毫秒值
	mini_tick = SysTick->VAL; // 读取SYSTICK的值
	
	// 直到无溢出标志
	// 读取COUNTERFLAG也会清除它的值
	while(SysTick->CTRL & SysTick_CTRL_COUNTFLAG) 
	{
		mini_tick = SysTick->VAL;
		tick = ulTicks;
	}
	
	// 换算成微秒
	tick *= 1000; // 毫秒部分乘以1000
	tick += (uint32_t)((SysTick->LOAD - mini_tick) * us_per_mini_tick); // 小数部分折算成微秒
	
	return tick;
}

//
// @简介:微秒级延迟
// @参数:us - 要延迟的时间,单位是微秒
//
void DelayUs(uint32_t us)
{
	Delay_Init();
	
	uint64_t expiredTime = GetUs() + us + 1;
	
	while(GetUs() < expiredTime);
}

posted @ 2026-08-31 11:11  灵垚克府  阅读(8)  评论(0)    收藏  举报