前言
DMA(直接存储器访问)是一种机制,使得设备能够在使用CPU的情况下进行数据传输。在STM32中,DMA可以用于在片上外设之间进行数据传输,而无需使用CPU。这提高了系统效率并减少了CPU的使用,从而使系统更加可靠。
采用中断方式、DMA方式完成:STM32系统给上位机(win10)连续发送"hello windows!“;当上位机给stm32发送字符"stop"后,stm32暂停发送"hello windows!”;发送一个字符"start"后,stm32继续发送。
一、环境
- 硬件:stm32f103c8t6 核心板
- 软件:STM32CubeMX 6.9.2
- 软件:keil5 mdk
二、STM32CubeMX
1、引脚配置
PA10 配置为 USART1_RX
PA9 配置为USART1_TX
PC13 配置为 GPIO_Output
2、配置RCC
3、配置SYS
4、配置NVIC
5、配置USART1
6、配置时钟
7、Code Generator设置
8、Project Manager 设置
然后生成工程文件。
三、通过KEil配置代码
1、打开main.c
添加初始化和声明:
/* USER CODE BEGIN PV */
#define LENGTH 4 //接受缓冲区大小
uint8_t RxBuffer[LENGTH]; //接受缓冲区
uint8_t RxFlag = 0; //接收完成标志;0表示接受未完成,1表示接收完成
/* USER CODE END PV */
在int main( )
中while
外添加代码:
/* USER CODE BEGIN WHILE */
//发送提示信息
HAL_UART_Transmit(&huart1,(uint8_t *)"****UART commucition using IT****\n",34,HAL_MAX_DELAY);
HAL_UART_Transmit(&huart1,(uint8_t *)"Please enter 4 characters: \n",30,HAL_MAX_DELAY);
//使能接收中断
HAL_UART_Receive_IT(&huart1, (uint8_t *)RxBuffer,LENGTH);
在while
中添加代码:
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
//添加下面代码
HAL_UART_Transmit(&huart1, (uint8_t *)"hello windows!\r\n", 16 , HAL_MAX_DELAY);
HAL_Delay(1000); //延时1s
if(RxFlag == 1) //如果接受完成,不在发送数据
{
HAL_UART_Transmit(&huart1,(uint8_t *)"Recevie Success!\n",17,HAL_MAX_DELAY); //提示接受成功
break; //退出循环,不在发送数据
}
}
2、编译烧录
3、结果展示
串口中断通信
4、串口输出波形
使用keil的逻辑分析仪
进行观测:
分析:
由图可知时序状态正确,波特率实际为0.999517Hz。
四、DMA串口通信
1、配置RCC
2、配置SYS
3、配置USART1
4、NVIC Settings设置
5、DMA Settings设置
6、时钟配置
7、Code Generate设置
8、Project设置
生成工程文件后打开。
五、通过KEil配置代码
1、打开main.c
添加代码:
#include <string.h>
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#define RX_BUFFER_SIZE 64
/* UART reception buffer */
uint8_t rxBuffer[RX_BUFFER_SIZE];
uint8_t rxData = 0;
uint8_t txData[] = "Hello Windows!\r\n";
uint8_t sending = 1;
/* USER CODE END Includes */
在while
中添加代码:
/* USER CODE BEGIN WHILE */
HAL_UART_Receive_IT(&huart1, &rxData, 1); // Start UART reception
while (1) {
if (sending) {
// Send data using DMA
HAL_UART_Transmit_DMA(&huart1, txData, strlen((char *)txData));
// You can also add a delay here if needed
HAL_Delay(1000);
}
}
/* USER CODE END 3 */
重写中断处理函数:
/* USER CODE BEGIN 0 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
if (huart == &huart1) {
// Process received data here
// For example, check if "stop" or "start" was received
if (strncmp((char *)rxBuffer, "stop", 4) == 0) {
sending = 0; // Stop sending
} else if (strncmp((char *)rxBuffer, "start", 5) == 0) {
sending = 1; // Start sending
}
// Clear the buffer
memset(rxBuffer, 0, sizeof(rxBuffer));
// Restart reception
HAL_UART_Receive_IT(&huart1, &rxData, 1);
}
}
/* USER CODE END 0 */
2、烧录程序
3、结果展示
使用串口助手进行串口通信
DMA通信
4、串口输出波形
使用keil的逻辑分析仪
进行观测:
分析:
由图可知时序状态正确,波特率实际为0.98325Hz。
六、总结
中断和DMA方式的串口通信实验是非常典型的嵌入式系统实验,通过实验的过程可以深入了解串口通信的原理和实现方式,并掌握利用中断和DMA方式实现串口数据收发的技能。
参考
https://blog.csdn.net/qq_52187415/article/details/127474339
https://blog.csdn.net/qq_47281915/article/details/121053903
https://blog.csdn.net/qq_45945548/article/details/121153469