✨STM32CubeMX工程配置过程演示:


- 🌿传输方向; 外设到内存;内存到外设;内存到内存; 外设到外设
- 🌿DMA_Mode_Normal,正常模式,
🍁当一次DMA数据传输完后,停止DMA传送 ,也就是只传输一次
- 🌿DMA_Mode_Circular ,循环传输模式
🍁当传输结束时,硬件自动会将传输数据量寄存器进行重装,进行下一轮的数据传输。 也就是多次传输模式.
- 🌿Data Width :DMA内存地址自增,每次增加一个Byte(字节)
STM32CubeMX自动配置生成的,而是定义在main.c文件中,默认是勾选上的,如果没有取消勾选,生成代码后,会与stm32f1xx_it.c中生成相关的中断服务函数会与main.c中的USART1_IRQHandler函数重复冲突,导致编译报错。
#define UART_RX_LEN 1024 // 一次最大接收的数据量
uint8_t UART_RX_BUF[UART_RX_LEN]; // DMA数据接收缓存
__IO uint16_t UART_RX_STA = 0; // 第15bit表示一帧数据接收完成,第14~0位表示接收到的数据量
void USART1_IRQHandler(void)
{//串口中断函数
if(__HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE) != RESET) // 空闲中断标记被置位
{
__HAL_UART_CLEAR_IDLEFLAG(&huart1); // 清除中断标记
HAL_UART_DMAStop(&huart1); // 停止DMA接收
UART_RX_STA = UART_RX_LEN - __HAL_DMA_GET_COUNTER(huart1.hdmarx); // 总数据量减去未接收到的数据量为已经接收到的数据量
UART_RX_BUF[UART_RX_STA] = 0; // 添加结束符
UART_RX_STA |= 0X8000; // 标记接收结束
HAL_UART_Receive_DMA(&huart1, UART_RX_BUF, UART_RX_LEN); // 重新启动DMA接收
}
}
while(1)中添加下面的代码: if(UART_RX_STA & 0X8000)
{
HAL_UART_Transmit(&huart1, UART_RX_BUF, UART_RX_STA & 0X7FFF, 100); // 将接收到的数据发送回去
UART_RX_STA = 0; // 清除标记
}
printf("STM32F103CET6");
HAL_Delay(1000);
}
usart.c文件中添加下面的代码,并在target设置中勾选Use Micro Lib选项,,并在调用printf函数的地方包含stdio.h头文件。#include
int fputc(int ch,FILE *f)
{
uint32_t temp = ch;
HAL_UART_Transmit(&huart1,(uint8_t *)&temp,1,0xFFFF); //huart1是串口的句柄
HAL_Delay(2);
return ch;
}
#include
#include "usart.h"
#include
#include
//使用printf()发送数据,需要对printf函数进行重定向,且只能使用USART1。
// 重定向fputc函数,使用printf()发送数据
int fputc(int ch, FILE *f)
{
// 参数1:串口句柄,参数2:要发送的数据;参数3:要发生数据的长度;参数4:超时等待时间
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 100);
return ch;
}
//DMA发送:本项目中使用的方法
// DMA模式
void log_DMA(const char *format, ...)
{
va_list args; // 定义参数列表变量
va_start(args, format); // 从format位置开始接收参数表,放在arg里面
char strBuf[256]; // 定义输出的字符串
vsprintf(strBuf, format, args); // 使用vsprintf将格式化的数据写入缓冲区
va_end(args); // 结束可变参数的使用
// 等待上次的数据发送完成,避免新的数据覆盖正在传输的数据,导致混乱
while (HAL_UART_GetState(&huart1) == HAL_UART_STATE_BUSY_TX)
{
// Wait for DMA transfer to complete
}
HAL_UART_Transmit_DMA(&huart1, (uint8_t *)strBuf, strlen(strBuf));
}
//中断式发送:
// 中断模式
void log_IT(const char *format, ...)
{
va_list args; // 定义参数列表变量
va_start(args, format); // 从format位置开始接收参数表,放在arg里面
char strBuf[256]; // 定义输出的字符串
vsprintf(strBuf, format, args); // 使用vsprintf将格式化的数据写入缓冲区
va_end(args); // 结束可变参数的使用
// 等待上次的数据发送完成,避免新的数据覆盖正在传输的数据,导致混乱
while (HAL_UART_GetState(&huart1) == HAL_UART_STATE_BUSY_TX)
{
// Wait for transfer to complete
}
HAL_UART_Transmit_IT(&huart1, (uint8_t *)strBuf, strlen(strBuf));
}
//使用sprintf()函数,阻塞式发送:
// 堵塞模式
void log(const char *format, ...)
{
va_list args; // 定义参数列表变量
va_start(args, format); // 从format位置开始接收参数表,放在arg里面
char strBuf[256]; // 定义输出的字符串
vsprintf(strBuf, format, args); // 使用vsprintf将格式化的数据写入缓冲区
va_end(args); // 结束可变参数的使用
HAL_UART_Transmit(&huart1, (uint8_t *)strBuf, strlen(strBuf), HAL_MAX_DELAY);
}
链接:https://pan.baidu.com/s/1O1CnA0eMttLLXWZPpUWJEQ
提取码:ud7l
链接:https://pan.baidu.com/s/1qOtfw21j0pQmAhJoVUe-cw?pwd=pb23
提取码:pb23
链接:https://pan.baidu.com/s/1TaeL2FCV-uqDv6xbXrnvhw?pwd=vtrk
提取码:vtrk