STM32中断与DMA通信编程

一、中断

1.什么是中断
中断是指计算机运行过程中,出现某些意外情况需主机干预时,机器能自动停止正在运行的程序并转入处理新情况的程序,处理完毕后又返回原被暂停的程序继续运行。单片机的中断系统是计算机的重要组成部分。实时控制、故障自动处理、计算机与外围设备间的数据传输往往采用中断系统。中断系统的应用大大提高了计算机效率。
2.中断的过程
大致过程
中断的发生:当CPU处理某一事件A时,B此时发生,CPU被请求优先处理B
中断处理:CPU暂停了A的处理,去处理B了
中断返回:处理完B后开始处理A
具体过程
①接收中断请求。
②查看本级中断屏蔽位,若该位为1则本级中断源参加优先权排队。
③中断优先级选择。
④处理机执行完一条指令后或者这条指令已无法执行完,则立即中止现行程序。接着,中断部件根据中断级去指定相应的主存单元,并把被中断的指令地址和处理机当前的主要状态信息存放在此单元中。
⑤中断部件根据中断级又指定另外的主存单元,从这些单元中取出处理机新的状态信息和该级中断控制程序的起始地址。
⑥执行中断控制程序和相应的中断服务程序。
⑦执行完中断服务程序后,利用专用指令使处理机返回被中断的程序或转向其他程序。
详情中断知识点合集

二、HAL库中断点亮LED灯

打开STM32CubeMX,点击file–new project
在这里插入图片描述
将PB5设置为GPIO_EXIT5,将PA1设置为GPIO_Output

在这里插入图片描述
在这里插入图片描述
再System core–GPIO里面如上图设置,PA1要设置为高电平
在这里插入图片描述
如图所示,在NVIC处打开中断模式

在这里插入图片描述

配置时钟源为外部时钟源
在这里插入图片描述
时钟树配置

在project manager里面设置,如图所示改为MDK-ARM
在这里插入图片描述
配置完毕后生成并打开project,如图找到这一段代码,这个函数是中断函数
在这里插入图片描述

可以看到,在中断函数里面调用了HAL_GPIO_EXTI_Callback函数,而这个函数就在中断函数下面
在这里插入图片描述
这个函数的内容 UNUSED(GPIO_Pin),很明显需要我们重写它,自己设置引脚,根据之前设置的PA1,我们将代码改写为HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_1);
此时就可以开始编程了
在这里插入图片描述

三、HAL库中断编程

在STM32CubeMX里打开这个项目,在connectivity里将USART1改为异步通信模式
在这里插入图片描述
在NVIC settings使他能够中断
在这里插入图片描述
设置完毕后生成代码

在main.c中定义

uint8_t aRxBuffer;			//接收中断缓冲
uint8_t Uart1_RxBuff[256];		//接收缓冲
uint8_t Uart1_Rx_Cnt = 0;		//接收缓冲计数
uint8_t	cAlmStr[] = "数据溢出(大于256)\r\n";

main函数

/* USER CODE BEGIN 2 */
	HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1);
/* USER CODE END 2 */

/* USER CODE BEGIN 4 */
/**
  * @brief  Rx Transfer completed callbacks.
  * @param  huart pointer to a UART_HandleTypeDef structure that contains
  *                the configuration information for the specified UART module.
  * @retval None
  */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(huart);
  /* NOTE: This function Should not be modified, when the callback is needed,
           the HAL_UART_TxCpltCallback could be implemented in the user file
   */
 
	if(Uart1_Rx_Cnt >= 255)  //溢出判断
	{
		Uart1_Rx_Cnt = 0;
		for(int i=0;i<255;i++)
		{
			Uart1_RxBuff[i]=0;
		}
		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;
			for(int i=0;i<255;i++)
		    {
			    Uart1_RxBuff[i]=0;
		    } //清空数组
		}
	}
	
	HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1);   //再开启接收中断
}
/* USER CODE END 4 */c

编译烧写代码,打开野火调试助手,在发送框随便输入,完毕后回车,点击发送
在这里插入图片描述

四、DMA通信

DMA直接内存存取原理. DMA 是指外部设备不通过CPU而直接与系统内存交换数据的接口技术。. 要把外设的数据读入内存或把内存的数据传送到外设,一般都要通过CPU控制完成,如CPU程序查询或中断方式。. 利用中断进行数据传送,可以大大 提高CPU的利用率 。. 但是采用 中断传送有它的缺点 ,对于一个高速I/O设备,以及批量交换数据的情况,只能采用DMA方式,才能解决效率和速度问题。. DMA在外设与内存间直接进行数据交换,而不通过CPU,这样数据传送的速度就取决于存储器和外设的工作速度
DMA设置
还是在usart1里面,DMAsettings里面如图设置
在这里插入图片描述

System core里面的DMA如图设置
在这里插入图片描述
然后生成代码调试运行
在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值