STM32F103RB 实作笔记(七)- 外来中断试验

发布者:灵感火花最新更新时间:2022-07-20 来源: csdn关键字:STM32F103RB  MDK 手机看文章 扫描二维码
随时随地手机看文章

关于中断和 计时寄存器的有关理论, 有兴趣的朋友可以看我一年前写的笔记 :“STM32F072RB 实作笔记(五)- 计时器加上中断EXTI_IRQHandler(一)” 和 “(二)” 两篇笔记。


这一篇笔记就直接解析实验的程式内容


main.c

和前几篇一样,进入“实验5 外部中断实验” 的 USER 资料夹点开 MDK 的项目档案。执行编译。

以下是 main.c 的内容:


#include "key.h"

#include "beep.h"

#include "usart.h"

#include "exti.h"

/************************************************/

int main(void)

{

 

Stm32_Clock_Init(9); //

delay_init(72);      //

uart_init(72,115200);//

LED_Init();   // 

BEEP_Init();         //

  EXTIX_Init(); //设定 外部中断的操作方式

    LED0=0; //设定 LED0 的初始值

while(1)

{     

printf("OKn"); //输出到 SSCom 的程式上

delay_ms(1000);   

}


我们看到 main.c 除了设定初始值以外,只执行了一个 “printf()” 和 “delay_ms” 就没有其他的动作了。这里有两个重点:


中断后的操作程式是在 exti.c 这个档案里(可以由EXTIX_Init() 取鼠标右键打开档案)

printf() 输出的 “OKn” 这个字串 会透过开发板的 USB 线, 呈现在电脑的 SSCom 程式上面(或是其他你熟悉的串口调试软件)。也可以自行修改 "OKn"的内容,看看输出的结果。SSCom 的操作,请看上一篇笔记 “STM32F103RB 实作笔记(六)- HC-05 蓝牙模组与手机 APP(正点原子 STM32F103 nano开发板)程式解析”

在这里插入图片描述

exti.c 程式解析

以下是exti.c 的内容


#include "exti.h"

#include "led.h"

#include "beep.h"

#include "key.h"

#include "delay.h"

#include "usart.h"


//  

void EXTIX_Init(void)

    KEY_Init();//

    Ex_NVIC_Config(GPIO_C,8,FTIR); // 见下面说明

Ex_NVIC_Config(GPIO_C,9,FTIR); //

Ex_NVIC_Config(GPIO_D,2,FTIR); //

Ex_NVIC_Config(GPIO_A,0,RTIR); //


MY_NVIC_Init(2,2,EXTI0_IRQn,2);    //见下面说明

MY_NVIC_Init(2,1,EXTI9_5_IRQn,2);  //

MY_NVIC_Init(2,0,EXTI2_IRQn,2);  //

//

void EXTI0_IRQHandler(void)

{

    delay_ms(10);    //

if(WK_UP==1)     //KEY_UP

{   

LED0=!LED0;

LED1=!LED1;

}

EXTI->PR=1<<0;  //LINE0

}

//

void EXTI2_IRQHandler(void)

{

    delay_ms(10);    //  

    if(KEY2==0)      //KEY2

    {

       BEEP=!BEEP;

    }

    EXTI->PR=1<<2;     //LINE2

}

//

 void EXTI9_5_IRQHandler(void)

{

delay_ms(10);   //  

if(KEY0==0)     //KEY0

{

LED0=!LED0;

}

  if(KEY1==0)     //KEY1

{

LED1=!LED1;

}

EXTI->PR=1<<8;  //LINE8

EXTI->PR=1<<9;  //LINE9 

}


exti.c 整个程式除了 include 之外,包含了下面四大部分。


void EXTIX_Init(void)

void EXTI0_IRQHandler(void)

void EXTI2_IRQHandler(void)

void EXTI9_5_IRQHandler(void)


我先说明 三个类似的 IRQHandler(void),

这三个IRQHandler(void) 是 INT 产生后 需要执行的程式入口 (Vectors)。从文件上可以看见 STM32f103 是把所有 GPIO 的同一bit 设一个 EXTI 线,从 EXTI0 到 EXTI5.


在这里插入图片描述

不过在记忆体的配置上却只是分成六个


   EXTI0_IRQHandler           ; EXTI Line 0

     EXTI1_IRQHandler           ; EXTI Line 1

     EXTI2_IRQHandler           ; EXTI Line 2

     EXTI3_IRQHandler           ; EXTI Line 3

     EXTI4_IRQHandler           ; EXTI Line 4

     EXTI9_5_IRQHandler       ; EXTI Line 9..15

在这里插入图片描述

实际的程式的定义是放在 startup_stm32f10x_md.s 这个档案。

在这里插入图片描述

在编写 RQHandler(void) 的时候,最重要的是在结束之前要把 IRQ 复位,使得程式可以接收下一个外部中断。

像这个样子:


void EXTI2_IRQHandler(void)

{

  。。。

。。。

  EXTI->PR=1<<2;     //LINE2

}


解析 EXTIX_Init(void)

这个涵式里放了几个NVIC 的结构设定涵式,都是放在 sys.c 里,结果如下:


void EXTIX_Init(void)

    KEY_Init();//

    Ex_NVIC_Config(GPIO_C,8,FTIR); //见下面说明

Ex_NVIC_Config(GPIO_C,9,FTIR); //

Ex_NVIC_Config(GPIO_D,2,FTIR); //

Ex_NVIC_Config(GPIO_A,0,RTIR); //


MY_NVIC_Init(2,2,EXTI0_IRQn,2);    //MY_NVIC_Init()见下面说明

MY_NVIC_Init(2,1,EXTI9_5_IRQn,2);  //EXTI9_5_IRQn 见下面说明

MY_NVIC_Init(2,0,EXTI2_IRQn,2);  //

}


第一个追查的是 Ex_NVIC_Config() 涵式,追查每一个定义如下:


//============== sys,c

void Ex_NVIC_Config(u8 GPIOx,u8 BITx,u8 TRIM) 

{

u8 EXTADDR;

u8 EXTOFFSET;

EXTADDR=BITx/4;// 

EXTOFFSET=(BITx%4)*4; 

RCC->APB2ENR|=0x01;//  

AFIO->EXTICR[EXTADDR]&=~(0x000F< AFIO->EXTICR[EXTADDR]|=GPIOx< // 

EXTI->IMR|=1< //EXTI->EMR|=1<  if(TRIM&0x01)EXTI->FTSR|=1< if(TRIM&0x02)EXTI->RTSR|=1<}


GPIO_x 的定义


//===========================sys.c

//Ex_NVIC_Config 

#define GPIO_A 0

#define GPIO_B 1

#define GPIO_C 2

#define GPIO_D 3

#define GPIO_E 4

#define GPIO_F 5

#define GPIO_G 6

#define FTIR   1  //

#define RTIR   2  // 


以下是 AFIO 定义

请添加图片描述
请添加图片描述

第二个追查的是 MY_NVIC_Init() 涵式,追查每一个定义如下:


//============== sys,c

void MY_NVIC_Init(u8 NVIC_PreemptionPriority,u8 NVIC_SubPriority,u8 NVIC_Channel,u8 NVIC_Group)  

u32 temp;

MY_NVIC_PriorityGroupConfig(NVIC_Group);// 见下面说明

temp=NVIC_PreemptionPriority<<(4-NVIC_Group);   

temp|=NVIC_SubPriority&(0x0f>>NVIC_Group);

temp&=0xf;//  

NVIC->ISER[NVIC_Channel/32]|=(1< NVIC->IP[NVIC_Channel]|=temp<<4;//             


以下是 NVIC 定义

请添加图片描述
请添加图片描述

以下是 MY_NVIC_PriorityGroupConfig() 定义


//===========================sys.c


void MY_NVIC_PriorityGroupConfig(u8 NVIC_Group)  

u32 temp,temp1;   

temp1=(~NVIC_Group)&0x07;// 

temp1<<=8;

temp=SCB->AIRCR;  // 

temp&=0X0000F8FF; // 

temp|=0X05FA0000; // 

temp|=temp1;    

SCB->AIRCR=temp;  // SCB    见下面说明    

}

以下是 SCB 定义

请添加图片描述
请添加图片描述

以下是 EXTIx_IRQn 定义


/******  STM32 specific Interrupt Numbers ******************************************/

  WWDG_IRQn                = 0,      /*!< Window WatchDog Interrupt             */

  PVD_IRQn                    = 1,      /*!< PVD through EXTI Line detection Interrupt  */

  TAMPER_IRQn                 = 2,      /*!< Tamper Interrupt                      */

  RTC_IRQn                    = 3,      /*!< RTC global Interrupt                    */

  FLASH_IRQn                  = 4,      /*!< FLASH global Interrupt                  */

  RCC_IRQn                    = 5,      /*!< RCC global Interrupt                    */

  EXTI0_IRQn                  = 6,      /*!< EXTI Line0 Interrupt                     */

  EXTI1_IRQn                  = 7,      /*!< EXTI Line1 Interrupt                     */

  EXTI2_IRQn                  = 8,      /*!< EXTI Line2 Interrupt                     */

  EXTI3_IRQn                  = 9,      /*!< EXTI Line3 Interrupt                     */

  EXTI4_IRQn                  = 10,     /*!< EXTI Line4 Interrupt                     */

  DMA1_Channel1_IRQn         = 11,     /*!< DMA1 Channel 1 global Interrupt         */

  DMA1_Channel2_IRQn         = 12,     /*!< DMA1 Channel 2 global Interrupt         */

  DMA1_Channel3_IRQn         = 13,     /*!< DMA1 Channel 3 global Interrupt         */

  DMA1_Channel4_IRQn         = 14,     /*!< DMA1 Channel 4 global Interrupt         */

  DMA1_Channel5_IRQn         = 15,     /*!< DMA1 Channel 5 global Interrupt         */

  DMA1_Channel6_IRQn         = 16,     /*!< DMA1 Channel 6 global Interrupt         */

  DMA1_Channel7_IRQn         = 17,     /*!< DMA1 Channel 7 global Interrupt         */

  EXTI9_5_IRQn                = 23,     /*!< External Line[9:5] Interrupts */     


以上是 程式的追踪结果,方便分析。


关键字:STM32F103RB  MDK 引用地址:STM32F103RB 实作笔记(七)- 外来中断试验

上一篇:STM32F103RB 实作笔记(八)- IWDG 内部看门狗试验
下一篇:十五年创新路:意法半导体举办首届STM32中国线上技术周

推荐阅读最新更新时间:2024-11-16 23:10

MDK-ARM代码格式化插件AStyle
今天分享两点内容: 1.一个代码格式化插件【AStyle】 --- 来自关注我的朋友推荐! 2.STM32时钟及注意事项; 1AStyle插件 前两天,一位关注我的朋友(*inbun Yi*)给我推荐了这款AStyle插件,我当时看了下感觉还可以。于是,下来就下载并添加到MDK-ARM中试用了一下,挺好用的。所以,这里也给大家推荐一下。 代码格式化插件,顾名思义就是格式化代码,简单理解就是对代码进行排版的插件。比如:代码缩进。 插件下载地址: http://astyle.sourceforge.net/ 具体下载安装过程我就不说了,可以参考: https://zhuanlan.zhihu.com/p/23012
[单片机]
<font color='red'>MDK</font>-ARM代码格式化插件AStyle
STM32F103RB 实作笔记(一)- GPIOC LED 跑马灯
这几天被隔离管着无聊,就上淘宝买了一块《正点原子》 STM32F103 nano开发板,来练习 stm32f103 的程式。买这块开发板的原因是因为,板子已经有大部分MPU可以应用的线路包括 LED, 七节显示,IR, BUZZ, botton, 和 ST-link 等等基本需要的线路。还附上一个小塑料盒,嶲带方便,也不需要接太多的线。毕竟只是练习了解 F072 和 F103 的差别。 另外,F103的资源多,找资料方便。 下边我就把过程记录一下。(这里舍去去正点原子网站取资料的过程) 开发板 从淘宝下单后,收到的东西是这样,原有的内付程式是个24 小时的时钟。 跑马灯 内附的跑马灯程式是使用左上方那一排红色 LED, 线
[单片机]
<font color='red'>STM32F103RB</font> 实作笔记(一)- GPIOC LED 跑马灯
手把手带你创建HAL版本MDK工程模板
如何快速开发 STM32 项目?我们总不能每次开发一个项目就搭建一次工程,这样效率太低了。 通常我们会使用一个模板工程,需要开发新项目的时候拿出来添加一些对应的模块及业务代码,一个项目就开发完成了。 但对于新手朋友来讲,如何创建一个工程模板对他们来讲是个非常大的挑战。因为这个过程非常繁琐,虽然不复杂,但只要其中有一个环节做错了,那么就前功尽弃了,而且还不好排查。 本文将手把手带你创建 HAL 版本 MDK 工程模板,基于 STM32F103C8T6 芯片。文章参照正点原子的教程,并结合自己的工作经验写作而成,如果你能按照这个教程跟着操作,相信一定能够自己搭建一个HAL版本MDK工程模板。 1. 源码下载及前置阅读 如果大家
[单片机]
手把手带你创建HAL版本<font color='red'>MDK</font>工程模板
Keil(MDK-ARM-STM32)系列教程(六)Configuration(Ⅱ)
Ⅰ、写在前面 本文接着上一篇文章“Configuration(Ⅰ)”进行讲述Configuration后面三项Shortcut Keys快捷键、Text Completion代码完形、Other其他的内容。 Shortcut Keys快捷键:Keil软件里面所有快捷键都可以在Configuration配置中查看的到,也可以自定义快捷键。 Text Completion代码完形:包含代码自动完成、代码模板、语法错误检测等。 Other其他:这个选项不常用,包含UVSOCK (TCP/IP)设置、打开软件设置等。 阅读本文之前建议先阅读上一篇文章: Keil(MDK-ARM-STM32)系列教程(五)_Configu
[单片机]
Keil(<font color='red'>MDK</font>-ARM-STM32)系列教程(六)Configuration(Ⅱ)
STM32在MDK下的一种通用建立库函数工程的方法(标准库)
物料准备 MDK4或者(MDK5+Legacy支持包) ST官方下载的库文件(STM32F10x_StdPeriph_Lib_V3.5.0) 下载地址 http://pan.baidu.com/s/1cyxwXS 库函数主要文件夹简介 需要的用的库文件都在STM32F10x_StdPeriph_Lib_V3.5.0Libraries文件夹下,它又包含了以下两个文件夹 CMSIS(一些核心和库文件代码,CMSIS主要代码) CM3DeviceSupportSTSTM32F10x文件夹 system_stm32f10x.c(STM32F10x CMSIS Cortex-M3设备访问层的系统源文件) system_stm3
[单片机]
STM32在<font color='red'>MDK</font>下的一种通用建立库函数工程的方法(标准库)
Keil MDK3.20的stm32调试方法
1. 程序在RAM中运行 要点: (1)程序的下载地址改到RAM空间中 (2)程序的debug之前要设定SP,PC指针到Ram空间 新建工程,选择STM32 的具体型号,我买的万利的开发板,选择stm32f103Vb。 设定程序下载地址,如下图所示,IROM1的地址指向了STM32的ram空间。 空间大小如何分配取决于自己的需求。本款处理器内部ram大小为20K,分配16K给只读区,4K给可读可写区。这样IROM设定的大小为0x4000,IRAM1的起始就变为0X20004000,大小只剩下0X1000。 Debug标签选择ULINK1 Cortex Debugger(软件采用yjgyiysbCC兄crack方
[单片机]
Keil <font color='red'>MDK</font>3.20的stm32调试方法
关于STM32 MDK中USE_STDPERIPH_DRIVER问题的解释
初学STM32,在RealView MDK 环境中使用STM32固件库建立工程时,初学者可能会遇到编译不通过的问题。出现如下警告或错误提示: warning: #223-D: function assert_param declared implicitly;assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); 这时候我们需要在“Target Options” 中的“C/C++”选项卡中如图-2所示红框中添加USE_STDPERIPH_DRIVER、STM32F10X_HD。这样才能使编顺利通过。 图-2 知其然了,我们还得知其所以然。下面就听Herison给大家一一道来。我们知道,程序的执行是
[单片机]
关于STM32 <font color='red'>MDK</font>中USE_STDPERIPH_DRIVER问题的解释
小广播
设计资源 培训 开发板 精华推荐

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

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

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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