stm32cubemx的版本是6.10.0
第一步,配置stm32cubemx,我用的是stm32F407ZGT6.
选择RCC,设置为无源晶振
第二步,设置SYS,选择SW烧写模式
第三步,配置串口,选择USART1,mode配置为Asynchronous (异步模式)
在NVIC setings ,勾选“USART1 global interrupt”
这里我做过验证,如果不勾选USART1的中断,程序不能循环接收数据,只能执行一次。
第四步;配置DMA settings,点击“Add”,添加"USART1_RX"和"USART1_RX"
第五步:设置时钟,
第六步:设置工程名称、地址
第七步:设置代码生成工具,注意勾选图中的选项
最后一步就是“generate code”!
生成的代码,打开main.c
1、添加头文件和变量(尽量添加到user code begin 和 end内部 )/
* USER CODE BEGIN Includes */
#include <stdio.h> //第一步包含头文件
uint8_t rx_flag=0; //输入结束的标志位
uint8_t uart_rxbuf[100]; //输入数据的缓存区
uint8_t uart_rx[1];//输入字符缓存区
uint16_t len; //输入字符的个数
/* USER CODE END Includes */
2、添加printf函数,位置放在int main()上方。
int fputc(int c, FILE *stream) //重写fputc函数
{
/*
huart1是工具生成代码定义的UART1结构体,
如果以后要使用其他串口打印,只需要把这个结构体改成其他UART结构体。
*/
HAL_UART_Transmit(&huart1, (unsigned char *)&c, 1, 1000);
return 1;
}
这里需要添加一下微库。
3、在main函数内部,while(1)外部,添加代码
HAL_UART_Receive_DMA(&huart1, (uint8_t *)uart_rx, 1);
printf("welcome to uart DMA:DMA试验\r\n\r\n");
HAL_Delay(2000);
4、在while(1)内部,添加代码,功能:通过UART——DMA接收到数据后,统计出个数,打印出来。我在uart_rxbuf 添加两个回车和换行符,是因为发现执行完HAL_UART_Transmit_DMA后,但是不会执行下一行代码 printf("\r\n\r\n");这里没弄清楚是什么原因导致的?有知道原因小伙伴,欢迎指出。
while(1)
{
/* USER CODE END WHILE */
if(rx_flag==1)
{
printf("字符数目是%d,输入内容如下:\r\n",len);
uart_rxbuf[len]=0x0d;
uart_rxbuf[len+1]=0x0a;
uart_rxbuf[len+2]=0x0d;
uart_rxbuf[len+3]=0x0a;
HAL_UART_Transmit_DMA(&huart1,(uint8_t *)uart_rxbuf ,len+4 );
printf("\r\n\r\n");
len=0;
rx_flag=0;
}
printf("please input your code\r\n");
HAL_Delay(2000);
}
5、添加串口DMA的回调函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)//uart接收的回调函数
{
if(huart->Instance == USART1)
{
if(uart_rx[0]!=0x0A) //结束符是换行
{
len ++ ;
uart_rxbuf[len -1]=uart_rx[0];
if(len > 99) //超出最大长度
{
len=0;
}
}
else //接收到换行符,把len的长度减去1
{
len--;
rx_flag =1;
}
}
HAL_UART_Receive_DMA(&huart1, (uint8_t *)uart_rx, 1);//再次打开uart接口的DMA函数
}
上面就是全部代码。
开始编译,烧录。打开串口助手
同时,打开串口监控助手。能看到输入,输出情况。
完全一致!!
最后还是把有疑问的地方,再说一次,欢迎大家解答
我在uart_rxbuf 添加两个回车和换行符,是因为发现执行完HAL_UART_Transmit_DMA后,但是不会执行下一行代码 printf("\r\n\r\n");这里没弄清楚是什么原因导致的?有知道原因小伙伴,欢迎指出。