stm32添加串口调试
时间:2022-07-24
本文章向大家介绍stm32添加串口调试,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
MCU为stm32F103,选择usart3作为输出调试口。
有三种实现方法:
//
方法一:
1、usart3.c
#if 1
#pragma import(__use_no_semihosting)
//标准库需要的支持函数
struct __FILE
{
int handle;
};
typedef struct __FILE FILE;
FILE __stdout;
//定义_sys_exit()以避免使用半主机模式
void _sys_exit(int x)
{
x = x;
}
//重定义fputc函数
int fputc(int ch, FILE *f)
{
while ((USART3->SR & USART_FLAG_TC) == 0); //循环发送,直到发送完毕: USART_FLAG_TC=0x40
USART3->DR = (u8) ch;
return ch;
}
#endif
void Init_USART3(void)
{
u32 baud = USART_BAUDRATE;
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1ENR_USART3EN | RCC_APB1Periph_USART3, ENABLE);
GPIO_PinRemapConfig(GPIO_PartialRemap_USART3, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //输入脚
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOC, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = baud;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART3, &USART_InitStructure);
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
USART_Cmd(USART3, ENABLE);
}
2、define.h 里面进行宏定义:
#define DEBUG_OUT //开启串口调试
#ifdef DEBUG_OUT
#define _MSG_DBG(...) printf(__VA_ARGS__)
#else
#define _MSG_DBG(...)
#endif
3、main里面进行串口初始化和调用:
int main(void)
{
Init_USART3();
_MSG_DBG("init ok rn");
while(1) {}
}
//
方法二:
和方法1 一样,同样调用void Init_USART3(void)和在define.h 里面进行宏定义,
不同在于要配置:“魔术棒”=》“Target”=>"MicroLib"。
///重定向c库函数printf到串口,重定向后可使用printf函数
int fputc(int ch, FILE *f)
{
/* 发送一个字节数据到串口 */
USART_SendData(DEBUG_USARTx, (uint8_t) ch);
/* 等待发送完毕 */
while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_TXE) == RESET);
return (ch);
}
///重定向c库函数scanf到串口,重写向后可使用scanf、getchar等函数
int fgetc(FILE *f)
{
/* 等待串口输入数据 */
while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_RXNE) == RESET);
return (int)USART_ReceiveData(DEBUG_USARTx);
}
//
方法三:
1、usart3.c
只需要上面的 void Init_USART3(void)部分的代码,再加上:
void USART3_PutChar(char ch)
{
while ((USART3->SR & USART_FLAG_TC) == 0); //循环发送,直到发送完毕
USART3->DR = (u8) ch;
}
2、Retarget.c
#if defined(DEBUG_ENABLE)
#if DEBUG_OUTPUT==DEBUG_UART1
void USART1_PutChar(char ch);
#define PUT_CHART(c) USART1_PutChar(c)
#elif DEBUG_OUTPUT==DEBUG_UART2
void USART2_PutChar(char ch);
#define PUT_CHART(c) USART2_PutChar(c)
#elif DEBUG_OUTPUT==DEBUG_UART3
void USART3_PutChar(char ch);
#define PUT_CHART(c) USART3_PutChar(c)
#endif
static inline void BoardOutChar(char ch)
{
PUT_CHART(ch);
}
int fputc(int c, FILE *f)
{
#if defined(DEBUG_ENABLE)
BoardOutChar((char) c);
#endif
return 0;
}
3、define.h 里面进行宏定义:
#define NO_DEBUG 0
#define DEBUG_UART1 1
#define DEBUG_UART2 2
#define DEBUG_UART3 3
#define DEBUG_ENABLE
#define DEBUG_OUTPUT DEBUG_UART3
#if DEBUG_OUTPUT!=NO_DEBUG && DEBUG_ENABLE
#define _MSG_DBG(...) printf(__VA_ARGS__)
#else
#define _MSG_DBG(...)
#endif
- docker学习(4) 一些常用操作
- Java多线程之细说线程池
- Windows8异步编程的注意事项
- Spring(一)Spring的第一滴血
- Flume(一)Flume原理解析
- 我所理解的Remoting (2) :远程对象的生命周期管理[下篇]
- struts2(六)之ognl表达式与ActionContext、ValueStack
- Windows8异步编程的注意事项
- CSS魔法堂:深入理解line-height和vertical-align
- Gradle 10分钟上手指南
- gradle项目中profile的实现
- 欧盟推出“数字经济税收制度”优化了税收制度,却影响区块链行业
- CSS魔法堂:你一定误解过的Normal flow
- ASP.NET输出JSON格式数据
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法