【嵌入式】——STM32F401VE 中断+按键 点灯

实现四个按钮分别控制四个LED灯,按一次亮,再按一次熄灭。
掌握芯片的终端机制,并学会进行中断配置。
GPIO控制器 -> SYSCFG选择器 -> EXTI外部中断控制器 -> NVIC中断控制器

startup_stm32f40x.s中修改成如下:
【嵌入式】——STM32F401VE 中断+按键 点灯_第1张图片
记得IMPORT,否则报错BADSymbol:
在这里插入图片描述
rj_led.h代码:

#ifndef LED_H
#define LED_H
#include "stm32f4xx.h"
void led_init(void);
void led_ctrl(int led_n);
void delay(int num);
void led_loop(void);

#endif

rj_led.c代码:

#include "rj_led.h"
#include "systick.h"

void led_init()
{
   GPIO_InitTypeDef P;
	/*使能GPIOD的时钟*/
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);

	/*配置PD0,PD1,PD2,PD3,为输出模式,输出类型为输出推挽,
	               速率为50MHz,无上拉下拉电阻*/
	P.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;
	P.GPIO_Mode = GPIO_Mode_OUT;
	P.GPIO_OType = GPIO_OType_PP;	
	P.GPIO_Speed = GPIO_Speed_50MHz;
	P.GPIO_PuPd = GPIO_PuPd_NOPULL;
	GPIO_Init(GPIOD, &P);
}

void led_ctrl(int led_n)
{	
	switch(led_n)
		{
			case 1:
				{            /*控制LED1亮,其他灯熄灭,给PD0端口置1,PD1,PD2,PD3端口置0*/
					GPIO_SetBits(GPIOD, GPIO_Pin_0);
					GPIO_ResetBits(GPIOD, GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3);
					break;
				}
			case 2:
				{            /*控制LED2亮,其他灯熄灭,给PD1端口置1,PD0,PD2,PD3端口置0*/
					GPIO_SetBits(GPIOD, GPIO_Pin_1);
					GPIO_ResetBits(GPIOD, GPIO_Pin_0|GPIO_Pin_2|GPIO_Pin_3);
					break;
				}
			case 3:
				{             /*控制LED3亮,其他灯熄灭,给PD2端口置1,PD1,PD0,PD3端口置0*/
					GPIO_SetBits(GPIOD, GPIO_Pin_2);
					GPIO_ResetBits(GPIOD, GPIO_Pin_1|GPIO_Pin_0|GPIO_Pin_3);
					break;
				}
			case 4:
				{              /*控制LED4亮,其他灯熄灭,给PD3端口置1,PD1,PD2,PD0端口置0*/
					GPIO_SetBits(GPIOD, GPIO_Pin_3);
					GPIO_ResetBits(GPIOD, GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_0);
					break;
				}
			default:
				break;
		}
}

void delay(int num)
{
		while(num--);
}

void led_loop()      //LED等循环点亮;
{
	int led_count=1;	
	for(led_count=1;led_count<5;led_count++)
	{
		led_ctrl(led_count);
		delay_ms(200);
	}	
}

rj_init_key.h代码:

#ifndef KEY_INT_H
#define KEY_INT_H

#include "stm32f4xx.h"
void key_int_init(void);
void key_irqHandler(void);
#endif

rj_init_key.c代码:

#include "stm32f4xx.h"


/*
	KEY -> PA -> EXTI -> NVIC -> CPU EXTI_IRQHandler
*/
void key_int_init(void)
{
	//时钟使能;
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA|RCC_AHB1Periph_GPIOE,ENABLE);

	/*配置端口,为输入模式,速率为50MHz,不上拉*/
	GPIO_InitTypeDef p;
	p.GPIO_Pin=GPIO_Pin_0;
	p.GPIO_Mode=GPIO_Mode_IN;       
	p.GPIO_Speed=GPIO_Speed_50MHz;
	//p.GPIO_OType=GPIO_OType_PP;  //输出推挽;
	p.GPIO_PuPd=GPIO_PuPd_NOPULL;

	GPIO_Init(GPIOA,&p);
	p.GPIO_Pin=GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4;
	GPIO_Init(GPIOE,&p);
	
	/*SYSCFG选择器的配置*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);	//时钟使能;
	SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA,EXTI_PinSource0);  //选择PA0作为外部中断的输入引脚;
	SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE,EXTI_PinSource2);   //PE2
	SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE,EXTI_PinSource3);  //PE3
	SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE,EXTI_PinSource4);   //PE4
	
	/*外部中断控制器的配置*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_EXTIT, ENABLE);//时钟使能;
	EXTI_InitTypeDef e;
	e.EXTI_Line=EXTI_Line0|EXTI_Line2|EXTI_Line3|EXTI_Line4;
	e.EXTI_Mode=EXTI_Mode_Interrupt;    //中断模式;
	e.EXTI_LineCmd=ENABLE;
	e.EXTI_Trigger=EXTI_Trigger_Rising;       //上升沿;
	
	EXTI_Init(&e);
	
	/*NVIC的控制*/
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//pre:2,sub:2 
	NVIC_InitTypeDef n;
	n.NVIC_IRQChannel=EXTI0_IRQn;
	n.NVIC_IRQChannelCmd=ENABLE;
	//n.NVIC_IRQChannelPreemptionPriority = 0x02;
	//n.NVIC_IRQChannelSubPriority = 0x02;
	NVIC_Init(&n);
	
	n.NVIC_IRQChannel=EXTI2_IRQn;
	NVIC_Init(&n);
	
	n.NVIC_IRQChannel=EXTI3_IRQn;
	NVIC_Init(&n);
	
	n.NVIC_IRQChannel=EXTI4_IRQn;
	NVIC_Init(&n);
}


//uint8_t	status = 0;
//void key_irqHandler(void)
//{
//	//	1.EXTI_GetITStatus 
//	if (EXTI_GetITStatus(EXTI_Line0) == SET)
//	{
//		status = 1;
//		//EXTI_ClearFlag 清除中断标识,否则会一直产生中断;
//		EXTI_ClearFlag(EXTI_Line0);
//	}
//
//}


//中断函数,按一下亮,再按一下灭
int f1 = 0, f2 = 0, f3 = 0, f4 = 0;

void key_irqHandler(void)
{
	if (EXTI_GetITStatus(EXTI_Line0) == SET)
	{
		if (f1 == 0)
		{
			GPIO_SetBits(GPIOD, GPIO_Pin_0);
			f1 = 1;
		}
		else
		{
			GPIO_ResetBits(GPIOD, GPIO_Pin_0);
			f1 = 0;
		}
		EXTI_ClearITPendingBit(EXTI_Line0);
	}
	if (EXTI_GetITStatus(EXTI_Line2) == SET)
	{
		if (f2 == 0)
		{
			GPIO_SetBits(GPIOD, GPIO_Pin_1);
			f2 = 1;
		}
		else
		{
			GPIO_ResetBits(GPIOD, GPIO_Pin_1);
			f2 = 0;
		}
		EXTI_ClearITPendingBit(EXTI_Line2);
	}
	if (EXTI_GetITStatus(EXTI_Line3) == SET)
	{
		if (f3 == 0)
		{
			GPIO_SetBits(GPIOD, GPIO_Pin_2);
			f3 = 1;
		}
		else
		{
			GPIO_ResetBits(GPIOD, GPIO_Pin_2);
			f3 = 0;
		}
		EXTI_ClearITPendingBit(EXTI_Line3);
	}
	if (EXTI_GetITStatus(EXTI_Line4) == SET)
	{
		if (f4 == 0)
		{
			GPIO_SetBits(GPIOD, GPIO_Pin_3);
			f4 = 1;
		}
		else
		{
			GPIO_ResetBits(GPIOD, GPIO_Pin_3);
			f4 = 0;
		}
		EXTI_ClearITPendingBit(EXTI_Line4);
	}
}

main.c

#include "main.h" 
#include "rj_led.h" 
#include "rj_int_key.h" 
#include "systick.h"
//#include "rj_buzzer.h"
//extern uint8_t status;
int main(void)
{
	//status=0;
	led_init();
	key_int_init();
  while (1)
  {


  }
}

演示视频:https://www.bilibili.com/video/BV1Pi4y1x7q1
【嵌入式】——STM32F401VE 中断+按键 点灯_第2张图片

【嵌入式】——STM32F401VE 中断+按键 点灯_第3张图片

你可能感兴趣的:(嵌入式)