本次学习的是:
可直接复制粘贴之前的工程文件,重新命名文件名即可使用
方法一、模块化代码:
main.c
#include "stm32f10x.h"
#include "led.h"
#include "key.h"
void Delay(__IO uint32_t nCount);
int main(void)
{
SystemInit();
LED_Config();
Key_Init();
while(1)
{
if(Key_Press()==1) {LED1_ON();LED2_OFF();LED3_OFF();}
if(Key_Press()==2) {LED1_OFF();LED2_ON();LED3_OFF();}
if(Key_Press()==3) {LED1_OFF();LED2_OFF();LED3_ON();}
}
}
void Delay(__IO uint32_t nCount)
{
for(; nCount != 0; nCount--);
}
led.c
#include "led.h"
#include "stm32f10x.h"
void LED_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOD , ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //LED1 V6//½«V6,V7,V8 配置为通用复用推挽输出
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //翻转速度为50MHz
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_3; //LED2, LED3 V7 V8
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOD, &GPIO_InitStructure);
LED_ALL_OFF();
}
led.h
#ifndef _LED_H
#define _LED_H
#include "stm32f10x.h"
#define LED1_ON() GPIO_SetBits(GPIOB, GPIO_Pin_5);
#define LED1_OFF() GPIO_ResetBits(GPIOB, GPIO_Pin_5);
#define LED2_ON() GPIO_SetBits(GPIOD, GPIO_Pin_6);
#define LED2_OFF() GPIO_ResetBits(GPIOD, GPIO_Pin_6);
#define LED3_ON() GPIO_SetBits(GPIOD, GPIO_Pin_3);
#define LED3_OFF() GPIO_ResetBits(GPIOD, GPIO_Pin_3);
#define LED_ALL_OFF() {GPIO_ResetBits(GPIOB, GPIO_Pin_5);GPIO_ResetBits(GPIOD, GPIO_Pin_3|GPIO_Pin_6); }
#define LED_ALL_ON() {GPIO_SetBits(GPIOB, GPIO_Pin_5);GPIO_SetBits(GPIOD, GPIO_Pin_3|GPIO_Pin_6); }
#define LED3_ON_OFF() GPIO_WriteBit(GPIOD,GPIO_Pin_3, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOD,GPIO_Pin_3)))
#define LED2_ON_OFF() GPIO_WriteBit(GPIOD,GPIO_Pin_6, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOD,GPIO_Pin_6)))
#define LED1_ON_OFF() GPIO_WriteBit(GPIOB,GPIO_Pin_5, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOB,GPIO_Pin_5)))
void LED_Config(void);
#endif
key.c
#include "key.h"
u8 _it0=0;
void Key_Delay(__IO uint32_t nCount)
{
for(; nCount != 0; nCount--);
}
void Key_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //输入上拉
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOC, &GPIO_InitStructure);
/* K3 配置 PC3 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOC, &GPIO_InitStructure);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
/* Enable the EXTI9-5 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel =EXTI9_5_IRQn; //外部中断9-5
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级0
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //子优先级2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn; //外部中断2
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级0
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //子优先级2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource5); //外部中断AFIO--ETXI9-5
GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource2); //外部中断AFIO--ETXI2
GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource3); //外部中断AFIO--ETXI3
EXTI_InitStructure.EXTI_Line = EXTI_Line5; //PC5作为键盘K1 检测状态
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //中断模式
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
EXTI_InitStructure.EXTI_Line = EXTI_Line2; //PC2 作为键盘K2 检测状态
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //中断模式
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
EXTI_InitStructure.EXTI_Line = EXTI_Line3;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
}
void EXTI9_5_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line5) != RESET) //判别是否有按键按下
{
_it0=1; //按键中断标志
EXTI_ClearITPendingBit(EXTI_Line5); //清除中断请求标志
}
}
void EXTI2_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line2) != RESET) //判断是否有按键按下
{
_it0=2; //按键中断标志
EXTI_ClearITPendingBit(EXTI_Line2); //清除中断请求标志
}
}
void EXTI3_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line3) != RESET)
{
_it0=3;
EXTI_ClearITPendingBit(EXTI_Line3);
}
}
u8 Key_Press(void){
if(_it0==1){ //按键按下
if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_5)==0){ //K1
Key_Delay(0x1ffff);
if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_5)==0){ //按键消抖
while(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_5)==0);//是否松开按键
_it0=0; return 1; //健值1 为K1 按下
}
}
}
else if(_it0==2){
if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_2)==0){
Key_Delay(0x1ffff);
if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_2)==0){
while(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_2)==0);
_it0=0; ;return 2;//¼üÖµ2 ΪK2°´ÏÂ
}
}
}
else if(_it0==3){
if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_3)==0){ //K3
Key_Delay(0x1ffff);
if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_3)==0){
while(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_3)==0);
_it0=0; return 3;//¼üÖµ3 ΪK3°´ÏÂ
}
}
}
return 0;
}
key.h
#ifndef __KEY__H
#define __KEY__H
#include "stm32f10x.h"
void Key_Init(void);
void EXTI9_5_IRQHandler(void);
void EXTI2_IRQHandler(void);
void EXTI3_IRQHandler(void);
u8 Key_Press(void);
#endif
方法一把索要需要的函数配置都配置好了,注意题目要求,根据题目要求再稍加修改就是了
方法二代码、集中写在main函数中:
main
#include"stm32f10x.h"
void Delay(u32 ncount);
void GPIO_Configuration(void);
void NVIC_Configuration(void);
void EXTI_Configuration(void);
extern vu8 _it0;
int main()
{
GPIO_Configuration();
NVIC_Configuration();
EXTI_Configuration();
while(1){
if(_it0==1){
if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_3)==0)
Delay(0xAFFFFF);
if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_3)==0){
while(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_3)==0);//等按键释放
if(GPIO_ReadOutputDataBit(GPIOD,GPIO_Pin_3)==0)
GPIO_SetBits(GPIOD,GPIO_Pin_3);
else
GPIO_ResetBits(GPIOD,GPIO_Pin_3);
} } } }
void GPIO_Configuration(void){
GPIO_InitTypeDef p;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO,ENABLE);//开时钟
p.GPIO_Pin=GPIO_Pin_3;
p.GPIO_Mode=GPIO_Mode_Out_PP;
p.GPIO_Speed=GPIO_Speed_2MHz;
GPIO_Init(GPIOD,&p);
p.GPIO_Pin=GPIO_Pin_3;
p.GPIO_Mode=GPIO_Mode_IPU;
GPIO_Init(GPIOC,&p);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource5);
GPIO_ResetBits(GPIOD,GPIO_Pin_3);//复位,led的初始状态为灭
}
void NVIC_Configuration(void){
NVIC_InitTypeDef nv;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
nv.NVIC_IRQChannel=EXTI3_IRQn;
nv.NVIC_IRQChannelPreemptionPriority=0;
nv.NVIC_IRQChannelSubPriority=0;
nv.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&nv);
}
void EXTI_Configuration(void){
EXTI_InitTypeDef ext;
ext.EXTI_Line=EXTI_Line3;
ext.EXTI_Mode=EXTI_Mode_Interrupt;
ext.EXTI_Trigger=EXTI_Trigger_Falling;
ext.EXTI_LineCmd=ENABLE;
EXTI_Init(&ext);
}
void Delay(u32 ncount)
{
for(;ncount!=0;ncount--);
}
总结:不管是应用哪一种方法,掌握中断控制定时是必须掌握的一个入门基础,从胚配置函数的参数到实际应用理解,需要花费一点时间