STM32按键中断学习记录

发布者:幸福微风最新更新时间:2018-06-15 来源: eefocus关键字:STM32  按键  中断 手机看文章 扫描二维码
随时随地手机看文章

习惯了调程序遇到问题就在网上各种搜罗,常常能从大牛的记录或者回复中得到启发,没想到有一天自己也开始写博客记录下学习的点滴。

学习STM32的这一个月颇有点闭门造车的意思,因为周围没有学习这个开发板的朋友,遇到问题要么远程求助要么自己琢磨,感觉略苦逼,也容易造成不自信。。。最近一直断断续续得学习STM32里的中断实验,遇到了很多问题,今天总算是把程序调了出来,趁着现在内心扑腾的小火苗还在燃烧,先把按键中断实验记录下来。

 

我使用的开发板是淘宝购置的STM32奋斗板V3,是从朋友处得到的,因为我从来没有接触过硬件开发,导致这一个月里有近四分之一的时间是花在琢磨如何使用JTAG,让开发板和软件连接好上了,一开始甚至连短接线是啥都不知道。。更搞笑的是开发板有两种供电方式——DC5V和USB,朋友既没有给我电源也没有给我USB线,我以为只能用USB供电,那就需要一颗CR1220电池,在市里跑了一圈也没买着,歪打正着想着买个DC5V供电试试,还真搞定了。。现在想想真是汗啊,太幼稚了。。此外,这个月里还经历了JTAG固件损坏,尝试自己修复不得,又重新购置了一个JLINK这种事情。。。

 

我使用的开发软件是keil uv3,选择这么古老的版本是因为之前用的JLINK和keil软件的高级版本相连时总会报错说JLINK是山寨的不能使用,好在退回到UV3还是勉强可以配合工作的,也就一直没有更换软件了。

 

前面说得这些都是吐槽,下面开始进入正题。

 

对于STM32来说,中断的使用除了需要进行RCC的配置、GPIO的配置外,剩下的就是要进行NVIC向量中断控制器配置和EXTI中断配置,还有一定要记住将中断线和GPIO管脚相连,一开始我就忘了这茬。。。

 

中断实验里我使用到LED灯(PB.5),将按键K1的列扫描线(PC.5)作为中断输入,行扫描线(PE.2)也需要打开时钟,并对管脚初始化为推挽输出——这一点我其实还不是特别理解,之前程序没有调出来时,只对PC.5进行了初始化,PE.2没有管,一直都进不到中断服务程序,后来加上了对PE.2的初始化程序就正常了。

时钟初始化代码如下:

void RCC_Configuration(void)

{   

  SystemInit();

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); 

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOE, ENABLE);

}

APB2总线上控制了AFIO和GPIO管脚,APB1总线控制了TIM、WDG等。下面这个图是在uv3的Peripherals选项卡中APB Bridges选项中得到的,必须要在调试状态下才可以选择,可以查看相应的控制器时钟配置情况。

 

接下来就是配置GPIO。GPIO管脚的模式一定要正确~GPIO的管脚可以在Peripherals选项卡中的General Purpose IO选项中查看。

GPIO配置代码如下:

void GPIO_Configuration(void){  

  GPIO_InitTypeDef GPIO_InitStructure;

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //LED1  V6--PB5     

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//将PB.5配置为通用推挽输出

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//口线翻转速度为50MHz

  GPIO_Init(GPIOB, &GPIO_InitStructure);  

  

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 ;//K1 PE2 行扫描线     

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//按键配置成推挽输出

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//口线翻转速度为50MHz

  GPIO_Init(GPIOE, &GPIO_InitStructure);

 

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //K1 PC5 列扫描线——中断线   

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//配置成上拉输入

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//口线翻转速度为50MHz

  GPIO_Init(GPIOC, &GPIO_InitStructure);

}

中断向量控制器的配置:

void NVIC_Configuration(void)

{   

NVIC_InitTypeDef NVIC_InitStructure;

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

NVIC_InitStructure.NVIC_IRQChannel=EXTI9_5_IRQn;//配置EXTI5~9线的中断向量

NVIC_InitStructure.NVIC_IRQChannelCmd= ENABLE;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;

NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;

NVIC_Init(&NVIC_InitStructure);

}

中断初始化:

void EXTI_Configuration(void)

{   

EXTI_InitTypeDef EXTI_InitStructure;

EXTI_InitStructure.EXTI_Line=EXTI_Line5;

EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;

EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;

EXTI_InitStructure.EXTI_LineCmd=ENABLE;

EXTI_Init(&EXTI_InitStructure);

}

把PC.5设为EXTI中断线:

GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource5);

中断服务函数:(在stm32f10x_it.c中)

void EXTI9_5_IRQHandler(void)

{

if(EXTI_GetITStatus(EXTI_Line5)!=RESET)  //PC.5

it=1;//中断标志,全局变量

EXTI_ClearITPendingBit(EXTI_Line5);

}

}

 

主函数:

#include "stm32f10x.h"

#include "stm32f10x_exti.h"

#include "stm32f10x_rcc.h"

#include "misc.h"

#include "stdio.h"

uint32_t it=0;

unsigned char num=0;

void RCC_Configuration(void);

void GPIO_Configuration(void);

void NVIC_Configuration(void);

void EXTI_Configuration(void);

void Delay(__IO uint32_t nCount);

void numm(void);

int main(void)

{

  unsigned char a=0;

  RCC_Configuration();    //系统时钟配置

  GPIO_Configuration(); //GPIO端口配置

  NVIC_Configuration(); //向量中断控制器配置

  GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource5);

  EXTI_Configuration();

  GPIO_SetBits(GPIOB, GPIO_Pin_5);    //LED1亮

  GPIO_ResetBits(GPIOE, GPIO_Pin_2); 

  while (1)

  {

   GPIO_ResetBits(GPIOE, GPIO_Pin_2); 

   numm();    //键盘扫描程序

if(num==1&&a==0){GPIO_ResetBits(GPIOB, GPIO_Pin_5);a=1;} //K1 按下作处理 复位--PB5=0 灭 置位--PB5=1 亮

else if(num==1&&a==1){GPIO_SetBits(GPIOB, GPIO_Pin_5);a=0;}

  }

}

void numm(void){

   num=0;

   if(it==1){     //按键按下标志 

      GPIO_ResetBits(GPIOE, GPIO_Pin_2);   //置PE2为0。  

  if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_5)==0){   //

   Delay(0xffff);   

if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_5)==0){   //按键消抖动

while(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_5)==0);//是否松开按键  

num=1;  //键值1 为K1按下

goto n_exit;

}

  }

 else ;

  n_exit:;

      it=0;

   } 

}

 

代码全贴上来了,进行了初始化以后就一直while(1)检测是否进中断,在中断服务函数里加了断点,进中断的话会跳到断点处,中断标志置位,再回到主函数,经过延时函数消抖,判断中断是否为真,再进行点灯灭灯操作。

 

写了一个多小时,感觉文章后半部分还不太详细,改天再修改。

 

相信付出一定会有收获!


关键字:STM32  按键  中断 引用地址:STM32按键中断学习记录

上一篇:STM32外部中断及定时器编程示例
下一篇:STM32 外部中断使用方法总结

推荐阅读最新更新时间:2024-03-16 16:05

7、STM32的外部中断EXTI及NVIC中断优先级介绍(内附代码)
一、什么是中断? 打断当前的操作,执行中断需要做的事情。 中断的作用:中断机制不仅赋予了系统处理意外情况的能力,就可以“同时”完成多个任务,提高了并发“处理”能力。 和线程的区别:线程是同时执行多个任务,中断是停下来去执行其他的(注意优先级),执行完了再回来执行, 定时器才相当于线程,定一个时间,每到这个时间执行一次 二、中断概述 STM32F4并没有使用CM4内核的全部东西,而是只用了它的一部分。 STM32F40xx/STM32F41xx总共有92个中断 STM32F42xx/STM32F43xx则总共有96个中断 STM32F40xx/STM32F41xx的92个中断里面,包括10个内核中
[单片机]
7、<font color='red'>STM32</font>的外部<font color='red'>中断</font>EXTI及NVIC<font color='red'>中断</font>优先级介绍(内附代码)
STM32入门编程总结4 (中断+串口)
系统异常中断与外部中断统称为中断,复位中断的优先级最高, NVIC(NestedVectored Interrupt Controller)嵌套向量中断控制器,调整各个中断的优先级,中断优先级 =抢占优先级(1-4bit)+子优先级(0、1)如果两个中断的抢占优先级与子优先级参数一致,则按照中断向量表里的顺序区分优先级。GPIO的中断,EXTI(External interrupt/event controller)外部中断/事件(event)控制器,外部中断为用户自定义中断内容(用户编写程序发生中断后要干啥事儿),外部事件为具体对应外设自动执行,EXTI 0-15总共16个,GPIO A-G当中的pin尾数与EXTI尾数对应
[单片机]
<font color='red'>STM32</font>入门编程总结4 (<font color='red'>中断</font>+串口)
单片机 MSP430 独立按键检测
可以不用while等待。 定义函数 #define CPU_F ( (double) 8000000) #define delay_us( x ) __delay_cycles( (long) (CPU_F * (double) x / 1000000.0) ) #define delay_ms( x ) __delay_cycles( (long) (CPU_F * (double) x / 1000.0) ) #define CO 1 #define SET 2 #define UP 3 #define DOWN 4 #define key_01 (P2IN&BIT5) #define key_02 (P
[单片机]
MCS-51定时器,串行口和中断初始化程序
  程序框图    电路 程序 0030 758160 CHK00: MOV SP,#60H 0033 1204A5 LCALL LED P 0036 900081 MOV DPTR,#C LOC K 0039 A882 MOV R0,DPL 003B A983 MOV R1,DPH 003D 90000B MOV DPTR,#000BH 0040 7402 MOV A,#02H 0042 F0 MOVX @DPTR,A 0043 A3 INC DPTR 0044 E
[单片机]
MCS-51定时器,串行口和<font color='red'>中断</font>初始化程序
STM8中断的设置(ST Visual Develop和IAR环境下)
以下以stm8s103为例介绍在ST Visual Develop和IAR环境下的中断设置;这两种只是环境不同其实中断向量是不会变的,先看一下数据手册, 再结合芯片手册中中断向量映像表,如下图所示 结合起来的话我们就能够理解的。 在用ST Visual Develop环境时新建一个新的Stm8工程它会自动生成一个main.c和一个stm8_interrupt_vector.c文件。 空白的main.c文件时如下所示的: view plaincopy /* MAIN.C file * * Copyright (c) 2002-2005 STMicroelectronics */ main() {
[单片机]
stm32 窗口看门狗 WWDG
窗口看门狗WWDG其实和独立看门狗类似,它是一个7位递减计数器不断的往下递减计数,当减到一个固定值0x40时还不喂狗的话,产生一个MCU复位,这个值叫窗口的下限,是固定的值,不能改变 窗口看门狗(WWDG)的时钟来自PCLK1,即挂接在APB1总线上,APB1时钟最大为36M 窗口值由配置寄存器WWDG_CFR的 位设置,所以最大值0x7F 当递减计数器递减到0x40的时候,还不会马上产生复位,如果使能了提前唤醒中断,则产生提前唤醒中断,提醒喂狗,随后将复位 WWDG配置步骤 1.使能WWDG时钟 2.设置WWDG窗口值 3.设置WWDG预分频因子 4.初始化NVIC外设,设置WWDG中断优先级 5.初始化计数
[单片机]
stm32的学习之存储器和总线架构
四个驱动单元:context-M3内核的D-bus总线和S-bus总线、通用DMA1和通用DMA2。 四个被驱动的单元:内部FLASH(内部山村存储器)、内部SRAM、FSMC、AHB到APB的桥AHP2APBx。 ICode总线是context-M3与内部闪存FLASH指令接口之间的连接的总线,实现指令的预取功能。 DCode总线是将context-M3与内部闪存存储器(FLASH)的数据接口连接起来的总线,实现数据读取。 系统总线(system bus)连接context-M3和总线矩阵,总线矩阵协调着context-M3和DMA间的访问。 DMA总线实现DMA的AHB主控接口道总线接口的连接。 总线矩阵 此总线矩阵协调内
[单片机]
STM32 延时函数封装
/*--------------------------------- 延时模块函数 说明:只需在工程中加入delay.c和delay.h 文件,即可用 Delayms(__IO uint32_t nTime); Delayus(__IO uint32_t nTime) -----------------------------------*/ #ifndef __DELAY_H #define __DELAY_H #include "stm32f10x.h" /*--------------------------------- 描 述:参数1即为1ms,1000即为1s;只有几 us的误差; -----
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved