豆芽菜丶 发表于 2022-10-24 12:48:40

STM32如何在中断程序中加入有限循环函数

需求:用两个按键控制两个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);
    }

}

豆芽菜丶 发表于 2022-10-24 12:55:43

我知道问题了各位,是我没有在主函数里加滴答定时器的初始化。{:10_266:}{:10_266:}{:10_266:}
但我不知道怎么取消帖子了{:10_306:}{:10_306:}{:10_306:}

豆芽菜丶 发表于 2022-10-24 12:59:21

但是我又遇到了一个问题,程序刚开始可以用按键2中断按键1的中断,但第二遍再按就不会中断了,而是各自亮各自的。但第三遍又恢复正常了, 下一次又不正常了。这又是什么原因呢
页: [1]
查看完整版本: STM32如何在中断程序中加入有限循环函数