Hal库创建项目并采用中断方式进行串口通信&采用串口DMA方式向上位机连续发送数据


前言

环境

  • 硬件:stm32f103c8t6 核心板
  • 软件:STM32CubeMX 6.4.0
  • 软件:keil5 mdk

一、创建StmCubeMX项目文件

  • 选择相对应的芯片型号

在这里插入图片描述

  • 时钟RCC配置,将HSE选为外部晶振模式
    在这里插入图片描述
  • SYS设置,选择Serial Wire模式。

在这里插入图片描述

  • 设置USART
    在这里插入图片描述

  • 设置NVIC
    在这里插入图片描述

  • 时钟树设置
    在这里插入图片描述

  • 设置工程路径、工程名
    在这里插入图片描述

  • 设置工程文件,并导出在这里插入图片描述

二、配置代码

1.定义全局变量

char c;//指令 s:停止  t:开始
char message[]="hello Windows\n";//输出信息
char tips[]="输错了!\n";//提示1
char tips1[]="Start.....\n";//提示2
char tips2[]="Stop......\n";//提示3
int flag=0;//标志 0:停止发送 1.开始发送

2、设置函数接受中断

1、在main函数里加入下面语句表示接受中断

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

2、在while循环里加入

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

3、重写中断回调函数

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	
	//当输入的指令为0时,发送提示并改变flag
	if(c=='s'){
		flag=0;
		HAL_UART_Transmit(&huart1, (uint8_t *)&tips2, strlen(tips2),0xFFFF); 
	}
	
	//当输入的指令为1时,发送提示并改变flag
	else if(c=='t'){
		flag=1;
		HAL_UART_Transmit(&huart1, (uint8_t *)&tips1, strlen(tips1),0xFFFF); 
	}
	
	//当输入不存在指令时,发送提示并改变flag
	else {
		flag=0;
		HAL_UART_Transmit(&huart1, (uint8_t *)&tips, strlen(tips),0xFFFF); 
	}

	//重新设置中断
		HAL_UART_Receive_IT(&huart1, (uint8_t *)&c, 1);  
}

3、编译&烧录

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

3、效果

在这里插入图片描述

三、拓展要求

当stm32接收到字符“stop stm32!”时,停止持续发送“hello windows!”; 当接收到字符“go stm32!”时,持续发送“hello windows!”

新建一个项目,与前面一致,不再赘述

1、打开目标文件

1、在usart.c和main.c中添加头文件

#include “stdio.h”
#include “string.h”

解释:因为后面我们需要用到printf和strcmp。
在这里插入图片描述
在这里插入图片描述

2、重定义printf函数和勾选项

在这里插入图片描述

  • main函数外定义
int fputc(int ch, FILE *f)
 
{
 
  HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
 
  return ch;
 
}

3、设置全局变量

uint8_t aRxBuffer;		
uint8_t Uart1_RxBuff[256]; 
uint8_t start[20] = "go stm32!";
uint8_t stop[20] = "stop stm32!";
uint8_t Uart1_Rx_Cnt = 0;	
uint8_t cAlmStr[] = "溢出了\r\n";
unsigned int flag = 1;

4、设置接收中断函数

  • 1、在main函数里加入
HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1);
  • 2、在while循环中添加
while (1)
{
	if(flag == 1){		
	  		printf("Hello windows!\r\n");
		}
	HAL_Delay(1000);
}
  • 3、重写回调函数(写在main函数外)
 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	
	if (strcmp(Uart1_RxBuff, start) == 0){
			flag = 1;
			printf("start....\r\n");
		
	}
	if (strcmp(Uart1_RxBuff, stop) == 0){
			flag = 0;
			printf("stop....\r\n");
		
	}
	if(Uart1_Rx_Cnt >= 255)  //溢出判断
	{
		Uart1_Rx_Cnt = 0;
		memset(Uart1_RxBuff,0x00,sizeof(Uart1_RxBuff));
		HAL_UART_Transmit(&huart1, (uint8_t *)&cAlmStr, sizeof(cAlmStr),0xFFFF);	
	}
	else
	{
		Uart1_RxBuff[Uart1_Rx_Cnt++] = aRxBuffer;   //接收数据转存
	
		if((Uart1_RxBuff[Uart1_Rx_Cnt-1] == 0x0A)&&(Uart1_RxBuff[Uart1_Rx_Cnt-2] == 0x0D)) //判断结束位
		{
			Uart1_Rx_Cnt = 0;
			memset(Uart1_RxBuff,0x00,sizeof(Uart1_RxBuff)); //6清空数组
		}
	}
	
	HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1);   //再开启接收中断

}

2、烧录运行

在这里插入图片描述

3、效果

在这里插入图片描述

四、采用串口DMA方式向上位机连续发送数据

1、新建工程项目

-新建工程,并找到芯片相对应型号
在这里插入图片描述

  • 进行时钟RCC选项配置
    在这里插入图片描述

  • 设置串口
    在这里插入图片描述

  • 使能中断
    在这里插入图片描述

  • DMA设置,将传输速率设置为中速Medium,模式设置为Normal,右侧选择Memory
    在这里插入图片描述

  • 在System view下选择DMA
    在这里插入图片描述

  • 时钟树设置
    在这里插入图片描述

  • 设置工程路径、工程名
    在这里插入图片描述

  • 设置工程文件,并导出
    在这里插入图片描述

2、main.c代码

1、定义一个全局变量

uint8_t Senbuff[] = "Hello world!";  //定义数据发送数组

2、在while循环里添加

  HAL_UART_Transmit_DMA(&huart1, (uint8_t *)Senbuff, sizeof(Senbuff));
  HAL_Delay(1000);

编译成功
在这里插入图片描述
下一步进行烧录,烧录成功后的效果如下:
在这里插入图片描述


五、总结

实验过程中遇到许多困难,最终还是得以解决。对两种中断模式的理解更加的深刻,以及对HAL库中的接口函数的深刻理解和基本使用。

六、参考资料

https://blog.csdn.net/qq_45917157/article/details/121141873
https://blog.csdn.net/qq_47281915/article/details/121053903

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
在使用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发送完成。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

混子王江江

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值