实验题目
使用基本定时器TIM6定时5s后蜂鸣器响,按按键3会中断使蜂鸣器关闭,按下按键3后,TIM7开始定时6s后蜂鸣器响,按键4会中断使蜂鸣器关闭
类似订一个闹铃,到一定时间,闹铃响,按键关闭,过几秒闹铃再次响起,按另外一个键关闭;
复习前面
一、GPIO配置(按键控制)
a、使能时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF,ENABLE);
b、初始化 GPIO_Init();
二、外部中断配置(GPIO->SYSCFG->EXTI->NVIC)
1、使能时钟
2、GPIO:设置输入模式(0-15) ->见GPIO配置
3、SYSCFG:设置EXTI和IO映射关系(0-15)
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOx, EXTI_PinSourcex);
4、EXTI:边沿检测(0-22) EXTI_Init();
5、NVIC:中断优先级,分组,使能 NVIC_Init();
6、设置中断服务函数
(1)在startup文件里面找到对应的中断函数
(2)判断是否有中断
不同函数的判断条件不一样,但基本都是 xxx_GetITStatus();
(3)清除中断标志位
清除中断标志位的函数,否则CPU将陷在中断函数
三、基本定时器配置(TIM6,TIM7)
<1>开启TIM时钟
<2>配置NVIC, NVIC_Init();
<3>配置TIM,TIM_TimeBaseInit();
<4>开启中断。TIM_ITConfig();
<5>使能定时器:TIM_ITCmd();
<6>重写中断函数,TIM6_DAC_IRQHandler()
<7>清除中断标志位。void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
实现实验
配置按键
void Key_Init()
{
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE,ENABLE);
GPIO_InitTypeDef GPIO_InitStruct1;
GPIO_InitStruct1.GPIO_Mode=GPIO_Mode_IN;
GPIO_InitStruct1.GPIO_Pin=GPIO_Pin_3;
GPIO_InitStruct1.GPIO_PuPd=GPIO_PuPd_UP;
GPIO_InitStruct1.GPIO_Speed=GPIO_High_Speed;
GPIO_Init(GPIOE,&GPIO_InitStruct1);
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN;
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_4;
GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_UP;
GPIO_InitStruct.GPIO_Speed=GPIO_High_Speed;
GPIO_Init(GPIOE,&GPIO_InitStruct);
}
蜂鸣器配置
void Beep_Init()
{
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF,ENABLE);
GPIO_InitTypeDef GPIO_InitStruct1;
GPIO_InitStruct1.GPIO_Mode=GPIO_Mode_OUT;
GPIO_InitStruct1.GPIO_OType=GPIO_OType_PP;
GPIO_InitStruct1.GPIO_Pin=GPIO_Pin_8;
GPIO_InitStruct1.GPIO_Speed=GPIO_High_Speed;
GPIO_InitStruct1.GPIO_PuPd=GPIO_PuPd_UP;
GPIO_Init(GPIOF,&GPIO_InitStruct1);
}
void Beep_On()
{
GPIO_SetBits(GPIOF,GPIO_Pin_8);
}//开启蜂鸣器
void Beep_Off()
{
GPIO_ResetBits(GPIOF,GPIO_Pin_8);
}//关闭蜂鸣器
外部中断配置
#include "stm32f4xx.h"
#include "stm32f4xx_rcc.h"
#include "exti.h"
void Exti_Init()
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG,ENABLE);
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource3);
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource4);//映射关系
EXTI_InitTypeDef EXTI_InitStruct1;
EXTI_InitStruct1.EXTI_Line=EXTI_Line3;
EXTI_InitStruct1.EXTI_LineCmd=ENABLE;
EXTI_InitStruct1.EXTI_Mode=EXTI_Mode_Interrupt;
EXTI_InitStruct1.EXTI_Trigger=EXTI_Trigger_Falling;
EXTI_Init(&EXTI_InitStruct1);
EXTI_InitTypeDef EXTI_InitStruct2;
EXTI_InitStruct2.EXTI_Line=EXTI_Line4;
EXTI_InitStruct2.EXTI_LineCmd=ENABLE;
EXTI_InitStruct2.EXTI_Mode=EXTI_Mode_Interrupt;
EXTI_InitStruct2.EXTI_Trigger=EXTI_Trigger_Falling;
EXTI_Init(&EXTI_InitStruct2);
NVIC_InitTypeDef NVIC_InitStruct1;
NVIC_InitStruct1.NVIC_IRQChannel=EXTI3_IRQn;
NVIC_InitStruct1.NVIC_IRQChannelCmd=ENABLE;
NVIC_InitStruct1.NVIC_IRQChannelPreemptionPriority=0;
NVIC_InitStruct1.NVIC_IRQChannelSubPriority=1;
NVIC_Init(&NVIC_InitStruct1);
NVIC_InitTypeDef NVIC_InitStruct2;
NVIC_InitStruct2.NVIC_IRQChannel=EXTI4_IRQn;
NVIC_InitStruct2.NVIC_IRQChannelCmd=ENABLE;
NVIC_InitStruct2.NVIC_IRQChannelPreemptionPriority=1;
NVIC_InitStruct2.NVIC_IRQChannelSubPriority=1;
NVIC_Init(&NVIC_InitStruct2);
}
定时器配置
#include "Tim.h"
#include "stm32f4xx.h"
void Tim6_Init()
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6,ENABLE);
NVIC_InitTypeDef NVIC_InitStruct1;
NVIC_InitStruct1.NVIC_IRQChannel=TIM6_DAC_IRQn;
NVIC_InitStruct1.NVIC_IRQChannelCmd=ENABLE;
NVIC_InitStruct1.NVIC_IRQChannelPreemptionPriority=2;
NVIC_InitStruct1.NVIC_IRQChannelSubPriority=1;
NVIC_Init(&NVIC_InitStruct1);
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct1;
TIM_TimeBaseInitStruct1.TIM_Period=29999;
TIM_TimeBaseInitStruct1.TIM_Prescaler=8399;
TIM_TimeBaseInit(TIM6,&TIM_TimeBaseInitStruct1);
TIM_ITConfig(TIM6,TIM_IT_Update,ENABLE); //定时中断配置
TIM_Cmd(TIM6,ENABLE); //使能定时器
}
void Tim7_Init()
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM7,ENABLE);
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel=TIM7_IRQn;
NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=3;
NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;
NVIC_Init(&NVIC_InitStruct);
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
TIM_TimeBaseInitStruct.TIM_Period=49999;
TIM_TimeBaseInitStruct.TIM_Prescaler=8399;
TIM_TimeBaseInit(TIM7,&TIM_TimeBaseInitStruct);
TIM_ITConfig(TIM7,TIM_IT_Update,ENABLE); //定时中断配置
TIM_Cmd(TIM7,DISABLE); //使能定时器
}
中断函数
void TIM6_DAC_IRQHandler(void) //重写定时器中断函数
{
if(TIM_GetITStatus(TIM6,TIM_IT_Update) == SET)
{
Beep_On();
TIM_ClearITPendingBit(TIM6,TIM_IT_Update);
}
}
void TIM7_IRQHandler(void) //重写定时器中断函数
{
if(TIM_GetITStatus(TIM7,TIM_IT_Update) == SET)
{
Beep_On();
TIM_ClearITPendingBit(TIM7,TIM_IT_Update);
}
}
void EXTI3_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line3)== SET)
{
Beep_Off();
TIM_Cmd(TIM6,DISABLE);
TIM_Cmd(TIM7,ENABLE);
EXTI_ClearITPendingBit(EXTI_Line3);
}
}
void EXTI4_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line4)== SET)
{
Beep_Off();
TIM_Cmd(TIM7,DISABLE);
EXTI_ClearITPendingBit(EXTI_Line4);
}
}
主函数
int main()
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_3);
Tim6_Init();
Tim7_Init();
Key_Init();
Beep_Init();
Exti_Init();
while(1)
{
}
}
使用上述即可实现本实验要求
需要多加注意中断函数的查找,有的中断函数名称比较奇怪