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);
  }
}

输出效果:

相关推荐
_Ningye6 小时前
STM32 — 6.1 TIM定时中断
stm32·单片机·嵌入式硬件
小白学电子_6 小时前
proteus仿真51单片机通过矩阵按键和数码管制作简单计算器
嵌入式硬件·51单片机·proteus
非鱼䲆鱻䲜8 小时前
vscode开发stm32添加新的头文件路径和包含源文件
ide·vscode·stm32·cmake·包含头文件·包含源文件
FreakStudio8 小时前
把 Flask 搬进 ESP32,高中生自研嵌入式 Web 框架 MicroFlask !
python·单片机·嵌入式·cortex-m3·异步编程·电子diy
AnalogElectronic9 小时前
RP2040 pico 实验6,光敏电阻传感器模块(LM393 比较器版)
单片机
17(无规则自律)9 小时前
【Linux驱动实战】:字符设备之ioctl与mutex全解析
linux·c语言·驱动开发·嵌入式硬件
电子工程师成长日记-C519 小时前
51单片机4乘4计算器
单片机·嵌入式硬件·51单片机
梅尔文.古9 小时前
ADCU-Ethernet-以太网在AUTOSAR与Linux架构下对比
arm开发·单片机·汽车
没有医保李先生9 小时前
esp32和stm32的工程宏定义
stm32·单片机·嵌入式硬件
炸膛坦客10 小时前
单片机/C/C++八股:(十五)内存对齐、结构体内存对齐
c语言·开发语言·单片机