STM32自学周记(四)
这一周在按键程序的基础上学习了外部中断实验,吸取上周教训,在学习32的中断系统之前首先查阅了51中断系统的资料,对中断系统有了大致的概念:强制CPU中断当前的任务去执行其他的任务,当强制任务完成后再继续之前的任务。
代码的编写和跑马灯程序类似,初始化GPIO和EXTI函数。需要注意的是,由于按键多于一个,所以需要给这些按键“排序”——中断优先级,顾名思义优先级高的可以打断优先级低的进行操作。这次的按键延续了之前的程序,在中断服务函数中对变量进行定义:按下KEY0后两个小灯现象取反,按下KEY1之后LED1现象取反。代码如下:
void EXTIX_Init(void)
{
EXTI_InitTypeDef EXTI_InitWrq;
NVIC_InitTypeDef NVIC_InitWrq;
KEY_Init();
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource5);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource15);
EXTI_InitWrq.EXTI_Line=EXTI_Line5;
EXTI_InitWrq.EXTI_LineCmd=ENABLE;
EXTI_InitWrq.EXTI_Mode=EXTI_Mode_Interrupt;
EXTI_InitWrq.EXTI_Trigger=EXTI_Trigger_Falling;
EXTI_Init(&EXTI_InitWrq);
EXTI_InitWrq.EXTI_Line=EXTI_Line15;
EXTI_InitWrq.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitWrq.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitWrq.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitWrq);
NVIC_InitWrq.NVIC_IRQChannel=EXTI9_5_IRQn;
NVIC_InitWrq.NVIC_IRQChannelCmd=ENABLE;
NVIC_InitWrq.NVIC_IRQChannelPreemptionPriority=2; //优先级为2
NVIC_InitWrq.NVIC_IRQChannelSubPriority=2;
NVIC_Init(&NVIC_InitWrq);
NVIC_InitWrq.NVIC_IRQChannel = EXTI15_10_IRQn;
NVIC_InitWrq.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitWrq.NVIC_IRQChannelPreemptionPriority = 1; //优先级为1
NVIC_InitWrq.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&NVIC_InitWrq);
}
void EXTI9_5_IRQHandler(void)
{
delay_ms(10); //消抖
if(KEY0==0) //如果按键按下
{
LED0=!LED0;
LED1=!LED1;
}
EXTI_ClearITPendingBit(EXTI_Line5);
}
void EXTI15_10_IRQHandler(void)
{
delay_ms(10); //消抖
if(KEY1==0) //如果按键按下
{
LED0=!LED0;
}
EXTI_ClearITPendingBit(EXTI_Line15);
}
之后回过头看了32的时钟系统,觉得很多东西都是死记的,给出一个程序,只需要根据参数选出合适的时钟,不要太纠结于为什么,要在在各个实验中加深对时钟的记忆,单独硬性记忆时钟反而会适得其反(我曾经就背过每个时钟都是干嘛的,背过之后都不知道自己背的什么……)。通过这几周的学习已经熟悉了RCC,APB2,GPIO等时钟的运用,初始化,这就是在实践中不知不觉记忆的。