通过中断控制led灯 与 中断通信

一、中断的介绍

1.1 单片机的中断

中断,在单片机中占有非常重要的地位。代码默认地从上向下执行,遇到条件或者其他语句,会按照指定的地方跳转。而在单片机执行代码的过程中,难免会有一些突发的情况需要处理,这样就会打断当前的代码,待处理完突发情况之后,程序会回到被打断的地方继续执行。

1.2 STM32的中断

几乎任何一款单片机都会有中断。以STM32F103来说,这是一款基于Cortex-M3内核的芯片,在CM4内核中有关于中断的一些管理,在STM32芯片中也有关于中断的一些管理。因此可以总结出一条规律,STM32的中断是有两层控制器分别控制的,如果你想使用中断,那么必须同时配置内核和芯片。
在这里插入图片描述
从内核架构图可以看到,NVIC控制器来管理内核中的中断。内核对中断的控制主要表现为几个方面:中断地址、中断优先级、中断使能

1.2.1 中断地址

程序的执行无非就是寻找地址,中断也是程序的一部分,而它的地址却是由内核来确定的,而且是不允许修改的。NVIC控制器可以帮我们找到中断的地址

1.2.2 中断优先级

优先级在中断里是一个非常重要的概念,如果同时产生多个中断,CPU会根据他们的优先级来选择这些中断的处理顺序。在CM4内核中,优先级用整数来表示,这个数越小代表级别越高。
在这里插入图片描述
在这里插入图片描述

1.2.3 中断使能

NVIC对中断有总控的功能,因此这里会有一个开关决定中断功能能否被开启

  • STM32外部中断
    外部中断只是中断的一种,一般由IO口的电平信号变化而引起。STM32有23个用于产生事件/中断请求的边沿检测器。每根输入线都可以单独配置,可以选择类型(中断或事件)和相应的触发事件(上升沿触发、下降沿触发、边沿触发)。每根线还可以单独配置。
  1. 中断框架
    在这里插入图片描述
    从上图可以看出外部中断的配置方法:

1)打开对应的APB时钟

2)选择外部中断输入线

3)设置中断的触发方式

4)选择工作模式(外部中断、事件)

5)使能

  1. 外部中断选择
    在这里插入图片描述

1.3 中断的过程

中断的步骤又中断发生、中断处理、中断返回执行的过程如下图

Created with Raphaël 2.3.0 开始 中断发生 中断处理 中断返回 结束

在这里插入图片描述

下图是中断程序的执行流程图
在这里插入图片描述

二、通过中断实现LED的控制

2.1 HAL库代码生成

  1. 在Patr Number中找到stm32f103c8,并双击选择芯片
    在这里插入图片描述
  2. 点击sys,选择Serial Wire
    在这里插入图片描述
  3. 点击RCC,选择Crystal/Ceramic Resonator
    在这里插入图片描述
  4. 点击芯片接口,将PA1作为输出,选择为GPIO_OutputPB0作为中断口,选择为GPIO_EXIT0
    在这里插入图片描述
    在这里插入图片描述
  5. 选则Clock Configuration配置时钟,然后将后面的晶振频率最大值改为72M赫兹
    在这里插入图片描述
  6. 选择GENERATE CODE生成代码

在这里插入图片描述

2.2 代码配置

打开自动生成Kei工程,打开主函数文件main.c,在其中添加以下函数代码。

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_1,1 - b0_pin);  // 将a1写入与b0相同的电位
			break;
	}
	
}

在这里插入图片描述

  1. 效果展示
    在这里插入图片描述

三、通过HAL库实现串口通信

3.1 使用STM32CubeMX生成代码

  1. 在CubeMX中选择工程,选择芯片stm32f103c8后,RCC设置如下
    在这里插入图片描述
  2. SYS设置如下
    在这里插入图片描述
  3. USART1设置为异步模式,并使能中断
    在这里插入图片描述
    USART1 参数配置如下
    在这里插入图片描述
    设置DMA
    在这里插入图片描述
    时钟改为72MHz
    在这里插入图片描述

3.2 代码

打开Cube生成的工程,打开main.c文件,更改以下代码

uint8_t aRxBuffer;			//接收中断缓冲
uint8_t Uart1_RxBuff[256];		//接收缓冲
uint8_t Uart1_Rx_Cnt = 0;		//接收缓冲计数
uint8_t	cAlmStr[] = "数据溢出(大于256)\r\n";
/* USER CODE BEGIN 2 */
	HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1);
/* USER CODE END 2 */
/* USER CODE BEGIN 4 */
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

3.3 效果展示

在这里插入图片描述

四、总结

本次实验采用了中断模式编程,反别通过中断控制了led并且通过中断实现了串口通信,中断程序在单片机程序中非常重要,通过中断可以更加灵活地处理程序,以后还需要继续学习中断的使用。


参考文献

手把手之STM32中断

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值