|
60鱼币
需求:用两个按键控制两个LED灯循环点亮,要按键2的按键中断能够中断按键1的按键中断。
我的想法是两个按键控制进入中断程序,在各自的中断程序中写入5秒的循环点亮灯(循环用的滴答定时器)。把按键2的优先级设置高于按键1。
现象:初始化是两个灯都灭的状态,按键1按了之后就一直亮不闪,按键2按了也是。但过一会之后两个灯都灭了。
灯的引脚是PB0和PB5,按键引脚是PA0和PC13。
delay.c
- #include "delay.h"
- static u8 fac_us = 0;
- static u16 fac_ms = 0;
- void delay_init(){
- //((SysTick_Type*)(0xE000E010))->CTRL &= ~(1<<2); //系统时钟的8分频
- SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
- fac_us = SystemCoreClock / 8000000;
- fac_ms = (u16)fac_us*1000;
- }
- void delay_ms(u16 nms){
- u32 temp;
- SysTick->LOAD = nms*fac_ms;//重装数值
- SysTick->VAL = 0x00; //清空计数器
- SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; //启动计数器
- do{
- temp = SysTick->CTRL; //查询状态
- }while((temp&0x01) && !(temp&(1<<16)));
-
- SysTick->CTRL &= ~(1<<0); //关闭计数器
- SysTick->VAL = 0x00; //清空计数器
- }
复制代码
exti_key.c
- #include "exti_key.h"
- #include "misc.h"
- void EXTI_Key_Init(void)
- {
-
- //初始化按键PA0、PC13的引脚为浮空输入,开启时钟复用功能,并使能
- GPIO_InitTypeDef GPIO_InitStructure_PA;
- GPIO_InitTypeDef GPIO_InitStructure_PC;
- //开启PA0、PC13的时钟,并开启复用时钟
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO,ENABLE);
- //设置PA0、PC13引脚为下拉输入,速度可以不用配置
- GPIO_InitStructure_PA.GPIO_Pin = GPIO_Pin_0;
- GPIO_InitStructure_PC.GPIO_Pin = GPIO_Pin_13;
- //配置输入引脚功能为下拉输入
- GPIO_InitStructure_PA.GPIO_Mode = GPIO_Mode_IPD;
- GPIO_InitStructure_PC.GPIO_Mode = GPIO_Mode_IPD;
- //使能PA、PC端口
- GPIO_Init(GPIOA,&GPIO_InitStructure_PA);
- GPIO_Init(GPIOC,&GPIO_InitStructure_PC);
-
- //初始化NVIC,
- NVIC_InitTypeDef NVIC_InitStructure;
- //选择中断优先级分组2
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
-
- NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
- NVIC_Init(&NVIC_InitStructure);
-
- NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
- NVIC_Init(&NVIC_InitStructure);
-
- //初始化EXTI
- EXTI_InitTypeDef EXTI_InitStructure;
- //清空中断标志
- EXTI_ClearITPendingBit(EXTI_Line0);
- EXTI_ClearITPendingBit(EXTI_Line13);
- //设置中断线工作模式
- EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
- EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
- EXTI_InitStructure.EXTI_LineCmd = ENABLE;
- //设置GPIO相应的PA0引脚和中断线连接起来
- GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);
- EXTI_InitStructure.EXTI_Line = EXTI_Line0;
- EXTI_Init(&EXTI_InitStructure);
- //设置GPIO相应的PC13引脚和中断线连接起来
- GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource13);
- EXTI_InitStructure.EXTI_Line = EXTI_Line13;
- EXTI_Init(&EXTI_InitStructure);
- }
复制代码
main.c
- #include "stm32f10x.h"
- #include "delay.h"
- #include "led.h"
- #include "exti_key.h"
- void flicker(u8 n, GPIO_TypeDef * GPIO, uint16_t GPIO_Pin){
- u8 i;
- for(i=0; i<n; i++){
- GPIO_WriteBit(GPIO,GPIO_Pin,(BitAction)((1-GPIO_ReadOutputDataBit(GPIO,GPIO_Pin))));
- delay_ms(500);
- GPIO_WriteBit(GPIO,GPIO_Pin,(BitAction)((1-GPIO_ReadOutputDataBit(GPIO,GPIO_Pin))));
- delay_ms(500);
- }
- }
- int main(void)
- {
- LED_Init();
- GPIO_SetBits(GPIOB,GPIO_Pin_5);
- GPIO_SetBits(GPIOB,GPIO_Pin_0);
-
- EXTI_Key_Init();
-
- while(1)
- {
-
- }
-
- }
- void EXTI0_IRQHandler(void)
- {
- if(EXTI_GetITStatus(EXTI_Line0) != RESET)
- {
- flicker(5, GPIOB, GPIO_Pin_5);
- EXTI_ClearITPendingBit(EXTI_Line0);
- }
- }
- void EXTI15_10_IRQHandler(void)
- {
- if(EXTI_GetITStatus(EXTI_Line13) != RESET)
- {
- flicker(5, GPIOB, GPIO_Pin_0);
- EXTI_ClearITPendingBit(EXTI_Line13);
- }
- }
复制代码 |
|