基于hal库的串口中断通信和DMA通信

基于hal库的串口中断通信和DMA通信

实验工具

stm32f103c8t6,usb to ttl,stm32cubemx

一.完成串口中断通信

1.配置stm32cubemx

(1)选择合适的芯片

(2)配置RCC

在这里插入图片描述


(3)配置SYS

在这里插入图片描述


(4)配置USART1

在这里插入图片描述


(5)配置NVIC

在这里插入图片描述


(6)配置clock configuriation

在这里插入图片描述


(7)完成基本项目配置

在这里插入图片描述
在这里插入图片描述


(8)创建项目

2.代码编写

(1)先定义全局变量来进行后面的使用,

uint8_t c;
uint8_t d[10];//指令 s:停止  t:开始
uint8_t  index=0;
uint8_t  num=0;
char message[]="hello windows!\n";//输出信息
char tips[]="CommandError\n";//提示1
uint8_t r[5]="start";
uint8_t t[4]="stop";
int flag1=0,i=0;
int flag2=0,j=0;
char tips1[]="start stm32";//提示2
char tips2[]="stop stm32";//提示3
int flag=0;//标志 s:停止发送 t:开始发送
(2)要完成对串口的输出中断必须在main.c中重写中断处理函数,
```c
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{	
	
	HAL_UART_Transmit(&huart1,(uint8_t *)&c,1,0xFFFF);
		if(c==r[i]){
		flag1++;
			i++;
		}
		else
		{
			flag1=0;
			i=0;
		}
		if(c==t[j]){
		flag2++;
			j++;
		}
		else
		{
			flag2=0;
			j=0;
		}
		if(flag1==5)
		{
			flag=1;
			flag1=0;
			i=0;
		}
		if(flag2==4)
		{
			
			flag=0;
			flag2=0;
			j=0;
		}
		//HAL_UART_Transmit(&huart1,(uint8_t *)&flag2,1,0xFFFF);
        HAL_UART_Receive_IT(&huart1,(uint8_t *)&c, 1);	
}

(3)在mian函数的while循环前添加串口接收函数,

HAL_UART_Receive_IT(&huart1, (uint8_t *)&c, 1);	

(4)最后再加入之前的串口输出代码但要加上if识别语句,

if(flag==1){
			//发送信息
			HAL_UART_Transmit(&huart1, (uint8_t *)&message, strlen(message),0xFFFF); 			
			//延时
			HAL_Delay(1000);
		}

(5)完整代码,

#include "main.h"
#include "usart.h"
#include "gpio.h"
#include <string.h>
void SystemClock_Config(void);
uint8_t c;
uint8_t d[10];//指令 s:停止  t:开始
uint8_t  index=0;
uint8_t  num=0;
char message[]="hello windows!\n";//输出信息
char tips[]="CommandError\n";//提示1
uint8_t r[5]="start";
uint8_t t[4]="stop";
int flag1=0,i=0;
int flag2=0,j=0;
char tips1[]="start stm32";//提示2
char tips2[]="stop stm32";//提示3
int flag=0;//标志 s:停止发送 t:开始发送
int main(void)
{
	HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_USART1_UART_Init();
	//设置接受中断
	HAL_UART_Receive_IT(&huart1,(uint8_t *)&c, 1);

  while (1)
  {
		
	  if(flag==1){
			//发送信息
			HAL_UART_Transmit(&huart1, (uint8_t *)&message, strlen(message),0xFFFF); 			
			//延时
			HAL_Delay(1000);
			
		}
  }
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{	
	
	HAL_UART_Transmit(&huart1,(uint8_t *)&c,1,0xFFFF);
		if(c==r[i]){
		flag1++;
			i++;
		}
		else
		{
			flag1=0;
			i=0;
		}
		if(c==t[j]){
		flag2++;
			j++;
		}
		else
		{
			flag2=0;
			j=0;
		}
		if(flag1==5)
		{
			flag=1;
			flag1=0;
			i=0;
		}
		if(flag2==4)
		{
			
			flag=0;
			flag2=0;
			j=0;
		}
		//HAL_UART_Transmit(&huart1,(uint8_t *)&flag2,1,0xFFFF);
        HAL_UART_Receive_IT(&huart1,(uint8_t *)&c, 1);	
}
/* USER CODE END 4 */
/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
  {
    Error_Handler();
  }
}
/* USER CODE BEGIN 4 */
/* USER CODE END 4 */
/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}



3.运行调试

在这里插入图片描述

4.烧录

在这里插入图片描述

5.结果

(1)发送区输入*开始发送"hello windows!“

在这里插入图片描述


(2)发送区发送#停止发送"hello windows!”

在这里插入图片描述

6.波形图

时序状态比较准确。
在这里插入图片描述

二.完成DMA通信

1.配置stm32cubemx

(1)新建并选择对应芯片

(2)配置RCC

在这里插入图片描述


(3)配置SYS

在这里插入图片描述


(3)配置USART1

在这里插入图片描述


(4)配置NVIC

在这里插入图片描述


(5)配置clock configuriation

在这里插入图片描述


(6)完成基本工程设置

在这里插入图片描述
在这里插入图片描述

(7)创建工程

2.代码编写

代码:

#include "main.h"
#include "dma.h"
#include "usart.h"
#include "gpio.h"
uint8_t A;
int flag=0;
uint8_t r[5]="start";
int j=0;
int i=0;
int flag1=0;
int flag2=0;
uint8_t t[4]="stop";

void SystemClock_Config(void);

/**
* @brief  The application entry point.
* @retval int
*/
int main(void)
{

HAL_Init();

/* USER CODE BEGIN Init */

/* USER CODE END Init */

/* Configure the system clock */
SystemClock_Config();

/* USER CODE BEGIN SysInit */

/* USER CODE END SysInit */

/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */

/* USER CODE END 2 */
HAL_UART_Receive_DMA(&huart1,(uint8_t *)&A,1);

/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
  /* USER CODE END WHILE */
    if(flag==1){
HAL_UART_Transmit_DMA(&huart1,"hello windows!\n",15);
    HAL_Delay(1000);
    }
  /* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  
  
  if(A==r[i]){
  	flag1++;
  		i++;
  	}
  	else
  	{
  		flag1=0;
  		i=0;
  	}
  	if(A==t[j]){
  	flag2++;
  		j++;
  	}
  	else
  	{
  		flag2=0;
  		j=0;
  	}
  	if(flag1==5)
  	{
  		flag=1;
  		HAL_UART_Transmit_DMA(&huart1,"start",5);
  		flag1=0;
  		i=0;
  	}
  	if(flag2==4)
  	{
  		
  		flag=0;
  		HAL_UART_Transmit_DMA(&huart1,"stop",4);
  		flag2=0;
  		j=0;
  	}
  HAL_UART_Receive_IT(&huart1,(uint8_t *)&A,1);
}
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
  Error_Handler();
}

/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                            |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
{
  Error_Handler();
}
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
* @brief  This function is executed in case of error occurrence.
* @retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
while (1)
{
}
/* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
* @brief  Reports the name of the source file and the source line number
*         where the assert_param error has occurred.
* @param  file: pointer to the source file name
* @param  line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
   ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

3.运行调试

在这里插入图片描述

4.烧录

在这里插入图片描述

5.结果

在这里插入图片描述
在这里插入图片描述

6.观察波形

时序状态比较准确

在这里插入图片描述

三.总结

这次实验让我掌握了串口中断通信和DMA通信的具体方法,更深入的了解了串口中断函数和DMA函数的使用,但对这种方法还不够熟悉。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在使用STM32 HAL进行串口通信时,可以使用中断接收和DMA发送的方式来提高通信效率。 首先需要初始化串口,并配置接收中断DMA发送。以下是一个示例代码: ``` UART_HandleTypeDef huart1; void MX_USART1_UART_Init(void) { huart1.Instance = USART1; huart1.Init.BaudRate = 115200; huart1.Init.WordLength = UART_WORDLENGTH_8B; huart1.Init.StopBits = UART_STOPBITS_1; huart1.Init.Parity = UART_PARITY_NONE; huart1.Init.Mode = UART_MODE_TX_RX; huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart1.Init.OverSampling = UART_OVERSAMPLING_16; if (HAL_UART_Init(&huart1) != HAL_OK) { Error_Handler(); } /* Enable the UART Parity Error Interrupt */ HAL_UART_Receive_IT(&huart1, rxBuffer, 1); /* Enable the DMA transfer for transmit */ HAL_UART_Transmit_DMA(&huart1, txBuffer, strlen((char *)txBuffer)); } void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if (huart == &huart1) { /* process received data */ HAL_UART_Receive_IT(&huart1, rxBuffer, 1); } } void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) { if (huart == &huart1) { /* transmit completed */ } } void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart) { if (huart == &huart1) { /* handle UART error */ } } ``` 在上面的代码中,`USART1`是串口的实例,`rxBuffer`和`txBuffer`是接收和发送缓冲区。在串口初始化时,使用`HAL_UART_Receive_IT`函数开启接收中断,并使用`HAL_UART_Transmit_DMA`函数开启DMA发送。在接收中断回调函数`HAL_UART_RxCpltCallback`中,可以对接收到的数据进行处理,并继续接收下一个字节。在发送完成回调函数`HAL_UART_TxCpltCallback`中,可以进行一些操作,例如将发送缓冲区中的数据更新,等待下一次发送。在出现UART错误时,`HAL_UART_ErrorCallback`函数会被调用,可以在该函数中处理错误。 需要注意的是,在使用DMA发送时,需要保证发送缓冲区的数据不会被修改,直到DMA发送完成。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值