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

输出效果:

相关推荐
richxu202510016 小时前
学完了江科大STM32,下一步该怎么学?
stm32·单片机·嵌入式硬件·学习
Deitymoon6 小时前
STM32——SPI通信
stm32·单片机·嵌入式硬件
2035去旅行7 小时前
WIFI传输带宽
arm开发·嵌入式硬件
linbaiwan6667 小时前
内置VDD稳压管减少外围元件的三款LED驱动芯片集成度
单片机·嵌入式硬件
三品吉他手会点灯8 小时前
STM32F103 学习笔记-21-串口通信(第6节)-串口发送命令控制RGB灯
笔记·stm32·单片机·嵌入式硬件·学习
yongui478349 小时前
水表集中抄表器单片机实现方案
单片机·嵌入式硬件
iCxhust12 小时前
8086 Proteus 8253制作跑表
单片机·嵌入式硬件·proteus·微机原理·8088单板机
xiangw@GZ12 小时前
HDI 高密度互连板阶数的深度理解
服务器·单片机·嵌入式硬件
@残梦13 小时前
200、stm32定义缓冲区用在DMA上时,需要谨记4字节地址对齐规则
stm32·单片机·嵌入式硬件
深圳市尚想信息技术有限公司14 小时前
HTW1000 烧录器/仿真器 TENX(十速)/海速芯 MCU在线/串联烧录器 单片机开发 嵌入式系统应用
单片机·烧录器·单片机开发·tenx·十速·海速芯