stm32f103zet6外部中断控制led灯
stm32f103zet6外部中断控制led灯
led端口定义
#define LED1_GPIO_PORT GPIOB /* GPIO端口 */
#define LED1_GPIO_CLK RCC_APB2Periph_GPIOB
#define LED1_GPIO_PIN GPIO_Pin_5
#define LED2_GPIO_PORT GPIOE /* GPIO端口 */
#define LED2_GPIO_CLK RCC_APB2Periph_GPIOE
#define LED2_GPIO_PIN GPIO_Pin_5
按键端口定义
#define KEY1_INT_GPIO_PORT GPIOE
#define KEY1_INT_GPIO_CLK (RCC_APB2Periph_GPIOE|RCC_APB2Periph_AFIO)
#define KEY1_INT_GPIO_PIN GPIO_Pin_3
#define KEY1_INT_EXTI_PORTSOURCE GPIO_PortSourceGPIOE
#define KEY1_INT_EXTI_PINSOURCE GPIO_PinSource3
#define KEY1_INT_EXTI_LINE EXTI_Line3
#define KEY1_INT_EXTI_IRQ EXTI3_IRQn
#define KEY1_IRQHandler EXTI3_IRQHandler
#define KEY2_INT_GPIO_PORT GPIOE
#define KEY2_INT_GPIO_CLK (RCC_APB2Periph_GPIOE|RCC_APB2Periph_AFIO)
#define KEY2_INT_GPIO_PIN GPIO_Pin_4
#define KEY2_INT_EXTI_PORTSOURCE GPIO_PortSourceGPIOE
#define KEY2_INT_EXTI_PINSOURCE GPIO_PinSource4
#define KEY2_INT_EXTI_LINE EXTI_Line4
#define KEY2_INT_EXTI_IRQ EXTI4_IRQn
#define KEY2_IRQHandler EXTI4_IRQHandler
按键中断的配置
void EXTI_Key_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure; //定义GPIO结构体变量
EXTI_InitTypeDef EXTI_InitStructure;//定义EXTI结构体变量 用来初始化外部中断的IO
/*开启按键GPIO口的时钟*/
RCC_APB2PeriphClockCmd(KEY1_INT_GPIO_CLK,ENABLE);
/* 配置 NVIC 中断*/
NVIC_Configuration();
/*--------------------------KEY1配置-----------------------------*/
/* 选择按键用到的GPIO */
GPIO_InitStructure.GPIO_Pin = KEY1_INT_GPIO_PIN;
/* 配置为上拉输入 */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//上拉输入
GPIO_Init(KEY1_INT_GPIO_PORT, &GPIO_InitStructure);
/* 选择EXTI的信号源 */
GPIO_EXTILineConfig(KEY1_INT_EXTI_PORTSOURCE, KEY1_INT_EXTI_PINSOURCE);
EXTI_InitStructure.EXTI_Line = KEY1_INT_EXTI_LINE;
/* EXTI为中断模式 */
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//设置 EXTI 线路为中断请求
/* 下降沿中断 */
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
/* 使能中断 */
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
/*--------------------------KEY2配置-----------------------------*/
/* 选择按键用到的GPIO */
GPIO_InitStructure.GPIO_Pin = KEY2_INT_GPIO_PIN;
/* 配置为上拉输入 */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//按键的另一端接地,故而使用上拉输入
GPIO_Init(KEY2_INT_GPIO_PORT, &GPIO_InitStructure);
/* 选择EXTI的信号源,将GPIOE4配置为外部中断线路,挂载在外部线路EXTI_Line4 */
GPIO_EXTILineConfig(KEY2_INT_EXTI_PORTSOURCE, KEY2_INT_EXTI_PINSOURCE);
EXTI_InitStructure.EXTI_Line = KEY2_INT_EXTI_LINE;//选择中断线路
/* EXTI为中断模式 */
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
/* 下降沿中断 */
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
/* 使能中断 */
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
}
中断的配置
static void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* 配置NVIC为优先级组1 */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
/* 配置中断源:按键1 */
NVIC_InitStructure.NVIC_IRQChannel = KEY1_INT_EXTI_IRQ;
/* 配置抢占优先级 */
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 15;
/* 配置子优先级 */
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
/* 使能中断通道 */
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* 配置中断源:按键2,其他使用上面相关配置 */
/* 配置抢占优先级 */
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 14;
/* 配置子优先级 */
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannel = KEY2_INT_EXTI_IRQ;
NVIC_Init(&NVIC_InitStructure);
}
个人笔记
关于GPIO功能的配置,开发板的按键是接地的 ,故而用上拉输入,才会有高低电平的变化(新手个人理解)
中断的配置
定义结构体变量
NVIC_InitTypeDef NVIC_InitStructure;
配置中断组别
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);
配置中断源(NVIC_InitTypeDef)
中断抢占式优先级(NVIC_InitTypeDef)
中断的响应优先级(NVIC_InitTypeDef)
使能中断通道(NVIC_InitTypeDef)
将结构体变量的值初始化给中断
延时函数
void Delay_us(u32 i)
{
u32 temp;
SysTick->LOAD=9*i; //设置重装数值, 72MHZ时
SysTick->CTRL=0X01; //使能,减到零是无动作,采用外部时钟源
SysTick->VAL=0; //清零计数器
do
{
temp=SysTick->CTRL; //读取当前倒计数值
}
while((temp&0x01)&&(!(temp&(1<<16)))); //等待时间到达
SysTick->CTRL=0; //关闭计数器
SysTick->VAL=0; //清空计数器
}
void Delay_ms(u32 i)
{
u32 temp;
SysTick->LOAD=9000*i; //设置重装数值, 72MHZ时
SysTick->CTRL=0X01; //使能,减到零是无动作,采用外部时钟源
SysTick->VAL=0; //清零计数器
do
{
temp=SysTick->CTRL; //读取当前倒计数值
}
while((temp&0x01)&&(!(temp&(1<<16)))); //等待时间到达
SysTick->CTRL=0; //关闭计数器
SysTick->VAL=0; //清空计数器
}