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

输出效果:

相关推荐
DebugKitty18 小时前
硬件开发1-51单片机4-DS18B20
单片机·嵌入式硬件·51单片机·ds18b20
Hello_Embed18 小时前
STM32HAL 快速入门(十九):UART 编程(二)—— 中断方式实现收发及局限分析
笔记·stm32·单片机·嵌入式硬件·学习
沐欣工作室_lvyiyi18 小时前
基于单片机的可燃性气体泄漏智能报警系统
stm32·单片机·嵌入式硬件·毕业设计
hazy1k18 小时前
STM32H750 RTC介绍及应用
网络·stm32·实时音视频
殷忆枫19 小时前
基于STM32物联网冻保鲜运输智能控制系统
stm32·嵌入式硬件·物联网
武文斌7719 小时前
单片机:DS18B20测温度、74HC595扩展芯片、8*8LED矩阵
运维·服务器·单片机·嵌入式硬件
hardStudy_h21 小时前
GPIO介绍
单片机·嵌入式硬件
xyx-3v21 小时前
STM32的USART的数据寄存器只有一个吗?
stm32·单片机·嵌入式硬件
古译汉书21 小时前
嵌入式铁头山羊stm32-ADC实现定时器触发的注入序列的单通道转换-Day26
开发语言·数据结构·stm32·单片机·嵌入式硬件·算法
KFCcrazy41 天前
嵌入式学习日记(39)51单片机
嵌入式硬件·学习·51单片机