在上一个流水灯实验的基础上在PC1口加一个按键,当按键按下时产生一个下降沿触发PC1口的外部中断功能,控制流水灯的亮灭。
- 电路的搭建, 8个LED灯与PB0~PB7连接,按键的一端与PC1口连接,一端与地连接。
- 软件:在上一个流水灯实验的基础上编写三个配置子程序,一个主程序和一个中断程序。
(1) 配置PC1端口为浮空输入的函数GPIO_Config(void),包括使能PC时钟和初始化PC1(管脚的选择,速率,工作模式)。
(2) 配置EXTI1为PC1的中断通道函数EXTI_Config(void),包括使能PC口复用(AFIO)功能时钟,配置PC1引脚为EXTI1的输入口(用GPIO_EXTILineConfig函数配置),初始化EXTI1(包括中断通道的选择,中断模式的选择,触发中断方式的选择)。
(3) 配置中断向量NVIC,初始化NVIC。包括触发中断的方式,主从优先级的选择
(4) 编写主函数,在上一个流水灯程序的基础上调用三个配置的子程序
(5) 编写中断函数,先在74页中找到EXTI1的中断入口地址作为中断函数名,在中断中编写函数使8个LED灯亮灭,并用FOR编写延时程序(使For至少执行500000次)
三、实验原理
STM32的各个引脚除了具有GPIO 的功能外,还具有一些复用功能如外部中断EXTI,USART的输入输出等功能,在这里我们启用其PC1口的外部中断功能,当PC1口做为外部中断时为输入口,因此要配置其为浮空输入口,通过87页图4-2可知PC1的中断通道为EXTI1,指定PC1作为EXTI1的触发引脚。在中断程序中先利用函数EXTI_GetITStatus读取中断标志位的值。
#include "stm32f10x.h"
#include "stm32f10x_it.h"
uint32_t i;int m;
void delay_ms(uint32_t ms)
{
uint32_t i_cnt,j_cnt;
for(i_cnt=0;i_cnt<3000;i_cnt++);
for(j_cnt=0;j_cnt<ms;j_cnt++);
}
void EXTI1_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line1) != RESET)
{ m=3;
while(m--){
for(i=0;i<8;i++)
{
delay_ms(99000);
GPIOB->BRR=(1<<i);
delay_ms(99000);
GPIOB->BSRR=(1<<i);
}
EXTI_ClearFlag(EXTI_Line1);
}
}
}
#include "stm32f10x.h"
GPIO_InitTypeDef GPIO_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
void EXTI0_Config(void);
int main(void)
{
EXTI0_Config();
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIOB->BSRR=0xff;
while (1)
{
}
}
void EXTI0_Config(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Speed =GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource1);//á??ó
EXTI_InitStructure.EXTI_Line = EXTI_Line1;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}