【嵌入式】——STM32F401VE 时钟+编程定时器——中断方式按键(PA0)实现流水灯,每个灯之间的切换时延是2秒。

实验目的:中断方式按键(PA0)实现流水灯,每个灯之间的切换时延是2秒。
1.在文件stm32f4xx.h中找到STM32F40_41xxx系列HSE_VALUE(L144)改为8000000
在这里插入图片描述
在文件system_stm32f4xx.c中修改STMF40_41xxx系列
PLL_M=8 L371
PLL_N=336 L401
PLL_P=2 L403
【嵌入式】——STM32F401VE 时钟+编程定时器——中断方式按键(PA0)实现流水灯,每个灯之间的切换时延是2秒。_第1张图片
systick.c

#include "stm32f4xx.h"
#include 
#define rSysTickCtrl *((volatile unsigned long*)0xE000E010)

static uint32_t systicknum = 0;


//定时器中断函数
void SysTick_Handler(void)
{
    if(systicknum != 0)
    {
        systicknum--;
    }    
}

void delay_ms(uint32_t m)
{
    systicknum = m;	
		SysTick_Config(SystemCoreClock/1000);
		NVIC_SetPriority(SysTick_IRQn, 0); 
    while(systicknum != 0);
		rSysTickCtrl &=  ~(1 << 0) ; // bit0 -> 0  disable SysTick
}

void delay_us(uint32_t u)
{
	systicknum = u;
	SysTick_Config(SystemCoreClock/1000000);
	//NVIC_SetPriority(SysTick_IRQn, 1); 
	while(systicknum != 0);
	rSysTickCtrl &=  ~(1 << 0) ; // bit0 -> 0  disable SysTick
}

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_int_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);
	
	NVIC_SetPriority(EXTI0_IRQn,0x07);
	
	
}


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);
//	}
//}

【嵌入式】——STM32F401VE 时钟+编程定时器——中断方式按键(PA0)实现流水灯,每个灯之间的切换时延是2秒。_第2张图片
实验框图:
【嵌入式】——STM32F401VE 时钟+编程定时器——中断方式按键(PA0)实现流水灯,每个灯之间的切换时延是2秒。_第3张图片
演示视频:https://www.bilibili.com/video/BV1Pi4y1x7q1
【嵌入式】——STM32F401VE 时钟+编程定时器——中断方式按键(PA0)实现流水灯,每个灯之间的切换时延是2秒。_第4张图片

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