一、printf重定向串口显示
1、STM32CubeMX配置
系统内核配置
Debug模式选择Serial Wire
时钟选择外部晶振
时钟树配置
直接拉满,使其工作在最大频率
串口配置
选择异步模式Asynchronous,不使能硬件流控制,具体参数默认
配置好工程后,生成函数。
2.重写fputc函数
在任意需要使用printf函数打印的C文件中,都需要引用#include <stdio.h>头文件
在usart.c和main.c文件中添加
#include <stdio.h>
在usart.c文件中重写fputc函数
int fputc(int ch , FILE *f)
{
while((USART2->SR&0X40)==0);//循环发送,直到发送完毕
USART2->DR = (uint8_t) ch;
return ch;
}
解释:USART2->SR&0X40 即访问USART状态寄存器的TXE
当TXE为0时,数据还没有被转移至移位寄存器;当TXE为1时,数据被转移至移位寄存器
数据发送完成时,TXE为1,跳出while循环。
二、ADC多通道(DMA)
1.ADC与DMA配置
在本文中,使用ADC多通道(DMA)实验检验printf重定向串口功能
ADC的简介以及多通道的间断模式可见:
STM32CubeMX | HAL库的ADC多通道数据采集(间断模式)-CSDN博客
通过DMA实现多通道数据采集,要将连续模式和间断模式关闭!
如果连续模式开启,那么通过DMA传输到的数组中,每个通道所采集到的值对应数组中的一个位置就是不固定的。
例如你开启了IN0~IN3这四个通道,并通过DMA将这四个通道的数据放到ADC_Value这个大小为4的u16类型数组,
你在第一次采集的时候IN0通道的数值通过DMA被放在ADC_Value[0],
第二次采集的时候IN0采集到的数值就可能被放到了ADC_Value[1],
这样的话就极不方便我们对每个通道的数据进行分析和提取。
最后开启ADC的DMA通道,将DMA的模式配置为周期模式。
(IN9接光敏传感器,IN8接对射式红外传感器)
实验代码如下:
#include "main.h"
#include "adc.h"
#include "dma.h"
#include "usart.h"
#include "gpio.h"
#include <stdio.h>
void SystemClock_Config(void);
uint16_t AD_Value[2];
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance == ADC1)
{
printf("%d %d \n",AD_Value[0],AD_Value[1]);
}
}
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_DMA_Init();
MX_ADC1_Init();
MX_USART2_UART_Init();
while (1)
{
HAL_ADC_Start_DMA(&hadc1,(uint32_t*)AD_Value,sizeof(AD_Value)/sizeof(AD_Value[0]));
HAL_Delay(500);
}
}
运行结果如下:
后续也会分享自己学习STM32CubeMX--HAL库的一些内容,或者一些课程设计的内容(模/数电,单片机,protel)。感谢点赞与关注。