STM32使用HAL库,模拟UART输出字符串

测试芯片是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);
  }
}

输出效果:

相关推荐
代码游侠9 小时前
学习笔记——设备树基础
linux·运维·开发语言·单片机·算法
xuxg200511 小时前
4G 模组 AT 命令解析框架课程正式发布
stm32·嵌入式·at命令解析框架
CODECOLLECT12 小时前
京元 I62D Windows PDA 技术拆解:Windows 10 IoT 兼容 + 硬解码模块,如何降低工业软件迁移成本?
stm32·单片机·嵌入式硬件
BackCatK Chen13 小时前
STM32+FreeRTOS:嵌入式开发的黄金搭档,未来十年就靠它了!
stm32·单片机·嵌入式硬件·freertos·低功耗·rtdbs·工业控制
全栈游侠16 小时前
STM32F103XX 02-电源与备份寄存器
stm32·单片机·嵌入式硬件
Lsir10110_16 小时前
【Linux】中断 —— 操作系统的运行基石
linux·运维·嵌入式硬件
深圳市九鼎创展科技18 小时前
瑞芯微 RK3399 开发板 X3399 评测:高性能 ARM 平台的多面手
linux·arm开发·人工智能·单片机·嵌入式硬件·边缘计算
辰哥单片机设计18 小时前
STM32项目分享:车辆防盗报警系统
stm32·单片机·嵌入式硬件
風清掦19 小时前
【江科大STM32学习笔记-05】EXTI外部中断11
笔记·stm32·学习
小龙报19 小时前
【51单片机】从 0 到 1 玩转 51 蜂鸣器:分清有源无源,轻松驱动它奏响新年旋律
c语言·数据结构·c++·stm32·单片机·嵌入式硬件·51单片机