2、Proteus仿真STM32外部EXTI中断、按键中断控制led流水灯的亮灭。

一、实验说明
本次实验是在上次实验的基础上,稍加修改,通过中断方式,利用按键控制led流水灯的闪烁,配置非常简单,只需要几分钟搞定。(附加上次实验链接:Proteus仿真STM32流水灯实验例程、详细步骤。
二、在Proteus中配置实验所需器件
1.配置按键,打开上次proteus实验工程,点击左边P,在关键字中输入BUTTON,并点击确认,如下图标记所示。
( 这里给大家分享下最近无意发现的一个好的公众号: 希望招聘,基本上推送的都是关于毕业生的招聘,全都是有效的信息,个人感觉对我们毕业生挺重要的,各大公司、事业单位、研究所的招聘都有。
在这里插入图片描述
)

在这里插入图片描述

2.将BUTTON添加到原理图中,并连接到PA1口。
在这里插入图片描述

3.配置接地,如下图所示,点击中断模式,选中GROUND。
在这里插入图片描述

4.将GROUND和按键BUTTON连接,如下图所示。
在这里插入图片描述
5.配置电阻,点击RES(即电阻),并连接如下图所示,此时proteus的所有配置都已经完成。
在这里插入图片描述

三、在keil中配置代码

1.打开上次实验的main.c文件,并删除main.c中的内容,将以下代码拷贝进去。
(小提示:在keil中每个文件末都要回车,新建一行,负责提醒有错,keil官方的一个bug)

#include "stm32f10x.h"

GPIO_InitTypeDef   GPIO_InitStructure;
EXTI_InitTypeDef   EXTI_InitStructure;
NVIC_InitTypeDef   NVIC_InitStructure;

void EXTI0_Config(void);
int main(void)
{
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
  
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOC, &GPIO_InitStructure);
  GPIOC->BSRR=0xff;
  while (1)
  {
  }
}
void EXTI0_Config(void)
{
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

  GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);

  EXTI_InitStructure.EXTI_Line = EXTI_Line1;
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;  
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  EXTI_Init(&EXTI_InitStructure);

  NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}

2.选中stm32f10x_it.c文件并打开,删除stm32f10x_it.c文件所有内容,将以下代码复制进去即可。
在这里插入图片描述

#include "stm32f10x_it.h"
uint32_t i;
void delay_ms(uint32_t ms)
{
  uint32_t i_cnt,j_cnt;
  for(i_cnt=0;i_cnt<3000;i_cnt++);
  for(j_cnt=0;j_cnt<ms;j_cnt++);
}
 void EXTI1_IRQHandler(void)
{
  if(EXTI_GetITStatus(EXTI_Line1) != RESET)
  {
    while(1)
    {
         for(i=0;i<8;i++)
         {
  	delay_ms(99000);
  	GPIOC->BRR=(1<<i);
  	  
  	delay_ms(99000);
 	 GPIOC->BSRR=(1<<i);
	 }
   	for(i=0;i<8;i++)
   	{
   	 delay_ms(99000);
   	 GPIOC->BRR=0x000000ff;
   	 
    	delay_ms(99000);
    	GPIOC->BSRR=0x000000ff;
	} 
     }
    EXTI_ClearITPendingBit(EXTI_Line1);
  }
}

3.最好在keil中运行,调试,软仿真成功之后,再在proteus中仿真。
4.老样子,将keil生成的hex文件写入proteus实验中,点击Program File选中所用的hex文件,该晶振为8M ,如下图所示。
在这里插入图片描述

四、实验结果
1.点击左下角第一个图标运行,未点击按键时,8个灯都熄灭,如下图所示。
在这里插入图片描述

2.点击按键后,8个led灯依次闪烁,说明按键实现了中断控制led灯,实验成功如下图所示。
在这里插入图片描述

五、实验原理
1.如下图讲解:
a.中断设置为上升沿有效
在这里插入图片描述

b.
对于这个芯片来说,它本身管脚是低电平有效,即无电流是是有效的,大家看下图圈中的地方,有蓝色的方块和红色的方块,(蓝色接地,原本为低电平,但因为芯片是低电平有效,所以蓝色代表有效电平),(红色有一部分接电源,原本为高电平,但因芯片是低电平有效,所以蓝色代表无效电平)。对于按键来说,未按下时,芯片PA1管脚和电源VDD连接为高电平,也就是无效电平;当按键按下时,接通了地为低电平,也就是有效电平,此时管脚PA1由无效电平变为有效电平,刚好为上升沿,触发中断,使led灯闪烁。
在这里插入图片描述
c.看下图我圈中的地方,led灯左边为蓝色的小方块(即有效电平),右边为红色的小方块(即无效电平),只有这样灯才能亮,就像现实中灯泡一边正,一边接负
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_46136508/article/details/105880196