测试芯片是STM32F103C8T6,直接封装好了,波特率是 9600
MyDbg.h
cpp
#ifndef __MYDBG_H
#define __MYDBG_H
#include "stm32f1xx_hal.h"
#include <stdio.h>
#include <stdarg.h>
/*
使用GPIO口 模拟 UART 输出字符串
*/
//初始化调试接口
void InitDbg(GPIO_TypeDef *pGPIO ,uint16_t uPin);
//调试 输出
void DbgPrintf(char *pFmt,...);
#endif
MyDbg.c
cpp
#include "MyDbg.h"
char g_DbgContent[100];
uint32_t g_Freq = 0;
GPIO_TypeDef *g_DBG_GPIO;
uint16_t g_Pin;
void Delay_us(uint32_t us) {
uint32_t uTickCount = 0;
//重载时间戳
uint32_t uReloadTick = SysTick->LOAD;
//转化
uint32_t uTicks = us * g_Freq;
uint32_t uLastTick = SysTick->VAL;
while(1){
//获取当前时间戳
uint32_t uNowTick = SysTick->VAL;
if(uNowTick != uLastTick){
if (uNowTick < uLastTick) {
uTickCount += uLastTick - uNowTick;
}else {
uTickCount += uReloadTick - uNowTick + uLastTick;
}
//更新时间戳
uLastTick = uNowTick;
//判断是否到时间了
if (uTickCount >= uTicks){
break;
}
}
};
}
void UART_SendChar(char ch) {
uint8_t data = (uint8_t)ch;
HAL_GPIO_WritePin(g_DBG_GPIO, g_Pin, GPIO_PIN_RESET);
Delay_us(100);
for (int i = 0; i < 8; i++) { // 8位数据
if (data & 0x01) {
HAL_GPIO_WritePin(g_DBG_GPIO, g_Pin, GPIO_PIN_SET); // 设置高电平
} else {
HAL_GPIO_WritePin(g_DBG_GPIO, g_Pin, GPIO_PIN_RESET); // 设置低电平
}
Delay_us(100); // 延时1微秒(根据实际情况调整)
data >>= 1; // 移位到下一个位
}
// 发送停止位(通常一个高电平位)
HAL_GPIO_WritePin(g_DBG_GPIO, g_Pin, GPIO_PIN_SET); // 高电平停止位
Delay_us(100);
}
void DbgPrintf(char *pFmt,...) {
va_list ap;
va_start(ap,pFmt);
int n = vsprintf(g_DbgContent,pFmt,ap);
va_end(ap);
char *pStr = (char*)&g_DbgContent;
while (*pStr != 0){
UART_SendChar(*pStr++); // 逐个字符发送
}
}
void InitDbg(GPIO_TypeDef *pGPIO ,uint16_t uPin){
g_DBG_GPIO = pGPIO;
g_Pin = uPin;
g_Freq = SystemCoreClock / 1000000;
}
难点在于实现微秒级的延迟。
测试代码使用了GPIOA的PIN_1
cpp
int main(void){
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_I2C1_Init();
//初始化
InitDbg(GPIOA,GPIO_PIN_1);
int Count = 0;
while (1){
DbgPrintf("Count:%d##",Count);
Count++;
HAL_Delay(1000);
}
}
输出效果:
