鱼C论坛

 找回密码
 立即注册
查看: 891|回复: 2

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

[复制链接]
发表于 2022-10-24 12:48:40 | 显示全部楼层 |阅读模式
60鱼币
需求:用两个按键控制两个LED灯循环点亮,要按键2的按键中断能够中断按键1的按键中断。
我的想法是两个按键控制进入中断程序,在各自的中断程序中写入5秒的循环点亮灯(循环用的滴答定时器)。把按键2的优先级设置高于按键1。
现象:初始化是两个灯都灭的状态,按键1按了之后就一直亮不闪,按键2按了也是。但过一会之后两个灯都灭了。
灯的引脚是PB0和PB5,按键引脚是PA0和PC13。
delay.c
  1. #include "delay.h"
  2. static u8 fac_us = 0;
  3. static u16 fac_ms = 0;
  4. void delay_init(){
  5.         //((SysTick_Type*)(0xE000E010))->CTRL &= ~(1<<2);     //系统时钟的8分频
  6.         SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
  7.         fac_us = SystemCoreClock / 8000000;
  8.         fac_ms = (u16)fac_us*1000;
  9. }
  10. void delay_ms(u16 nms){
  11.         u32 temp;
  12.         SysTick->LOAD = nms*fac_ms;//重装数值
  13.         SysTick->VAL = 0x00;          //清空计数器
  14.         SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;         //启动计数器
  15.         do{
  16.                 temp = SysTick->CTRL;     //查询状态
  17.         }while((temp&0x01) && !(temp&(1<<16)));
  18.        
  19.         SysTick->CTRL &= ~(1<<0);     //关闭计数器
  20.         SysTick->VAL = 0x00;          //清空计数器
  21. }
复制代码


exti_key.c
  1. #include "exti_key.h"
  2. #include "misc.h"

  3. void EXTI_Key_Init(void)
  4. {
  5.    
  6.     //初始化按键PA0、PC13的引脚为浮空输入,开启时钟复用功能,并使能
  7.     GPIO_InitTypeDef GPIO_InitStructure_PA;
  8.         GPIO_InitTypeDef GPIO_InitStructure_PC;
  9.     //开启PA0、PC13的时钟,并开启复用时钟
  10.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO,ENABLE);
  11.     //设置PA0、PC13引脚为下拉输入,速度可以不用配置
  12.     GPIO_InitStructure_PA.GPIO_Pin = GPIO_Pin_0;
  13.         GPIO_InitStructure_PC.GPIO_Pin = GPIO_Pin_13;
  14.     //配置输入引脚功能为下拉输入
  15.     GPIO_InitStructure_PA.GPIO_Mode = GPIO_Mode_IPD;
  16.         GPIO_InitStructure_PC.GPIO_Mode = GPIO_Mode_IPD;
  17.     //使能PA、PC端口
  18.     GPIO_Init(GPIOA,&GPIO_InitStructure_PA);
  19.         GPIO_Init(GPIOC,&GPIO_InitStructure_PC);
  20.    
  21.     //初始化NVIC,
  22.     NVIC_InitTypeDef NVIC_InitStructure;
  23.     //选择中断优先级分组2
  24.     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  25.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  26.        
  27.     NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
  28.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  29.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  30.     NVIC_Init(&NVIC_InitStructure);
  31.    
  32.         NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
  33.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  34.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  35.     NVIC_Init(&NVIC_InitStructure);

  36.     //初始化EXTI
  37.     EXTI_InitTypeDef EXTI_InitStructure;
  38.     //清空中断标志
  39.     EXTI_ClearITPendingBit(EXTI_Line0);
  40.         EXTI_ClearITPendingBit(EXTI_Line13);       
  41.         //设置中断线工作模式
  42.         EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  43.     EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
  44.     EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  45.     //设置GPIO相应的PA0引脚和中断线连接起来
  46.     GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);
  47.     EXTI_InitStructure.EXTI_Line = EXTI_Line0;         
  48.     EXTI_Init(&EXTI_InitStructure);
  49.         //设置GPIO相应的PC13引脚和中断线连接起来
  50.         GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource13);
  51.         EXTI_InitStructure.EXTI_Line = EXTI_Line13;
  52.         EXTI_Init(&EXTI_InitStructure);
  53. }
复制代码


main.c
  1. #include "stm32f10x.h"
  2. #include "delay.h"
  3. #include "led.h"
  4. #include "exti_key.h"

  5. void flicker(u8 n, GPIO_TypeDef * GPIO, uint16_t GPIO_Pin){
  6.         u8 i;
  7.         for(i=0; i<n; i++){
  8.                 GPIO_WriteBit(GPIO,GPIO_Pin,(BitAction)((1-GPIO_ReadOutputDataBit(GPIO,GPIO_Pin))));
  9.                 delay_ms(500);
  10.                 GPIO_WriteBit(GPIO,GPIO_Pin,(BitAction)((1-GPIO_ReadOutputDataBit(GPIO,GPIO_Pin))));
  11.                 delay_ms(500);
  12.         }
  13. }
  14. int main(void)
  15. {
  16.     LED_Init();
  17.     GPIO_SetBits(GPIOB,GPIO_Pin_5);
  18.         GPIO_SetBits(GPIOB,GPIO_Pin_0);
  19.    
  20.     EXTI_Key_Init();
  21.      
  22.     while(1)
  23.     {
  24.         
  25.     }
  26.    
  27. }


  28. void EXTI0_IRQHandler(void)
  29. {
  30.     if(EXTI_GetITStatus(EXTI_Line0) != RESET)
  31.     {
  32.                 flicker(5, GPIOB, GPIO_Pin_5);
  33.         EXTI_ClearITPendingBit(EXTI_Line0);
  34.     }

  35. }

  36. void EXTI15_10_IRQHandler(void)
  37. {
  38.     if(EXTI_GetITStatus(EXTI_Line13) != RESET)
  39.     {
  40.                 flicker(5, GPIOB, GPIO_Pin_0);
  41.         EXTI_ClearITPendingBit(EXTI_Line13);
  42.     }

  43. }
复制代码

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2022-10-24 12:55:43 | 显示全部楼层
我知道问题了各位,是我没有在主函数里加滴答定时器的初始化。
但我不知道怎么取消帖子了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2022-10-24 12:59:21 | 显示全部楼层
但是我又遇到了一个问题,程序刚开始可以用按键2中断按键1的中断,但第二遍再按就不会中断了,而是各自亮各自的。但第三遍又恢复正常了, 下一次又不正常了。这又是什么原因呢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-28 02:42

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表