编程语言
首页 > 编程语言> > STM32中断与DMA通信编程

STM32中断与DMA通信编程

作者:互联网

目录

一、STM32中断介绍

1、中断概念

2、中断优先级

3、中断向量表

二、高低电平控制LED灯亮和灭

三、中断实现串口通信

四、DMA

1、DMA定义:

2、DMA传输方式

3、DMA的主要特征

五、实现用DMA连续向上位机发送数据

六、总结

七、参考


一、STM32中断介绍

1、中断概念

      中断其实就是当 CPU 执行程序时,由于发生了某种随机的事件(外部或内部),引起 CPU 暂时中断正在运行的程序,转去执行一段特殊的服务程序(中断服务子程序或中断处理程序),以处理该事件,该事件处理完后又返回被中断的程序继续执行,这一过程就称为中断。

中断示意图:

2、中断优先级

     处理器根据不同中断的重要程序设置不同的优先等级。不同优先级中断的处理原则是:高级中断可以打断低级中断;低级中断不能打断高级中断,如图所示:

3、中断向量表

如图所示:

 

    除了个别异常的优先级被定死外,其它异常的优先级都是可编程的。这些中断通道已按照不同优先级顺序固定分配给相应的外部设备。从 STM32F10x 中文参考手册的中断向量表可以知道具体分配到那些外设,这里只截取一部分,如需了解更详细可参考《STM32F10x 中文参考手册》

STM32 的 IO 口外部中断函数只有 6 个,分别为:

EXPORT   EXTI0_IRQHandler          

EXPORT   EXTI1_IRQHandler       

EXPOR T   EXTI2_IRQHandler         

EXPORT   EXTI3_IRQHandler        

EXPORT   EXTI4_IRQHandler          

EXPORT   EXTI9_5_IRQHandler        

EXPORT   EXTI15_10_IRQHandler   

中断线 0-4 每个中断线对应一个中断函数,中断线 5-9 共用中断函数 EXTI9_5_IRQHandler,中断线 10-15 共用中断函数 EXTI15_10_IRQHandler。 

二、高低电平控制LED灯亮和灭

进入STMCUBEMX,选择新建项目

 

选择STM32F103C8,创建新的项目

点击start project。

点击sys,将debug选项改为Serial Wire

然后在Rcc里的HSE选择Crystal/Ceramic Resonator

将PB0选为外部中断触发器,PA8是控制led灯的,将它选择为GPIO_output就行了

选择PLLCLK,然后将后面的晶振频率最大值改为72M赫兹 

 

配置EXIT

 

点击project manager把toolchain那里改为MDK-ARM。

点击code generator,选择generate...如下图所示:

 然后点击上图中的generate code。

选择open project。

进入到keil里,接下来就是在回调函数里写代码了,将回调函数重写一遍就行了,代码如下 

 

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){
	GPIO_PinState b0_pin = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0);  // 读取b0的状态
	b0_pin=1-b0_pin;
	switch (GPIO_Pin){//判断引脚
		case GPIO_PIN_0:
			HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6,1-b0_pin);  // 将a6写入与b0相同的电位
			break;
	}
	
}

 烧录,然后运行结果为

在这里插入图片描述

 

三、中断实现串口通信

还是使用CUBEMX,新建项目的过程和上一个是一样的,就不多说了设置rcc

SYS里也是选择serial Wire

选择UASRT1,将mode改为异步通信,选择下面的NVIC Setting,将enabled选上。

uint8_t aRxBuffer;//接收缓冲中断
uint8_t Uart1_RxBuff[256];//接收缓冲
uint8_t Uart1_Rx_Cnt=0;//接收缓冲计数
uint8_t cAlmStr[]="数据溢出(大于256)";
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  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)) //判断结束位
		{
			HAL_UART_Transmit(&huart1, (uint8_t *)&Uart1_RxBuff, Uart1_Rx_Cnt,0xFFFF); //将收到的信息发送出去
			Uart1_Rx_Cnt = 0;
			memset(Uart1_RxBuff,0x00,sizeof(Uart1_RxBuff)); //清空数组
		}
	}
	
	HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1);   //再开启接收中断

}

设置串口 

DMA设置 

 DMA基础设置

右侧点击System Core 点击DMA

项目文件设置

创建工程文件

然后点击GENERATE CODE 创建工程

进入keil5,

进入到main.c文件,在main.c文件中的while循环那块的代码如下

while (1)
  {
   uint8_t send_char[]="hello \n";//发送的字符串
    HAL_UART_Transmit_DMA(&huart1,(uint8_t *)send_char,0xc);//DMA发送
		HAL_Delay(500);//延时
  }

 结果为:

六、总结

此次作业的内容较多,所以花费了我很多的时间来完成,同时在完成此次作业 的时候也遇到了很多问题,通过查询资料和问同学,一些问题也基本解决,通过此次作业,学到了关于中断以及DMA的一些相关知识,获益良多。

七、参考

【STM32】HAL库 STM32CubeMX教程十一---DMA (串口DMA发送接收)_Z小旋-CSDN博客

 stm32hal库串口DMA收发 - Breezy-ye - 博客园

 STM32F103C8通过DMA方式向上位机连续发送信息_junseven164的博客-CSDN博客

 

 

 

 

 

 

 

 

标签:DMA,HAL,中断,编程,Uart1,STM32,GPIO,外设
来源: https://blog.csdn.net/m0_61863551/article/details/121178492