zoukankan      html  css  js  c++  java
  • 2019年9月9日星期一(STM32 内部时钟 中断)

    .stm32的启动过程

      在stm32的开发中,芯片的启动代码官方通常会提供,一般不需要修改。但是对芯片的启动代码有一定了解,有助于对某些组件工作原理加深了解

      可以借助官方提供的启动代码来理解启动过程,启动代码是一个汇编文件(.s作为后缀),我们开发板的启动文件是start_stm32f40_41xxx.s

    1.初始化栈

    2.初始化堆

    3.实现异常向量表

    4.处理各个异常的代码

        其中复位异常中 ----- 初始化一些基本硬件(时钟,SRAM,FLASH...),调用主函数

    .stm32的时钟系统

      stm32f407的推荐时钟频率 168MHz

    1.提供参考时钟的硬件

      晶振 ----------- 产生低频的稳定震荡信号

      RC震荡电路 ----- 产生低频的不稳定震荡信号

    以上产生的频率不足以直接供给CPU使用,实际上使用PLL(锁相环)通过一个低频信号产生一个高频信号,供给CPU使用

        

    stm32f407一共4个原始时钟源

        HSIRC -------- 高速内部RC震荡时钟(16M)

        HSEOSC -------- 高速外部晶振(4-26M)

        LSIRC -------- 低速内部RC震荡时钟(32K)

        LSEOSC ------- 低速外部晶振(32.768K)

    2.stm32f407时钟树

     


       

                        

    绝大多数的外设挂在AHB总线和APB总线上,这些总线上的频率和系统频率一起提供,可选(HSI HSE PLL)

    其中RTC和看门狗通常使用独立的时钟源,RTC使用LSE,看门狗使用LSI

    3.PLL锁相环频率配置

        PLL输出频率(168M) = f时钟输入(8M) X PLLN / (PLLM X PLLP)

        168 =                     8 X      336 /  (8    X   2)

    4.修改工程中PLL配置,让主频为168M

    1system_stm32f4xx.c文件中

    第316行改为

        

    2stm32f4xx.h

    第123行改为

     

       

    .GPIO输入

    1.原理图

     

       

      如果按键按下去,接地,管脚低电平

      案件松开,由于上拉电阻,管脚高电平

     

     

       

        

        连接到了CPU的PA0 PE2 PE3 PE4

    2.硬件说明手册()

    3.查看芯片参考手册,库函数手册

        输入数据的获取通过读输入数据寄存器

     

       

      获取输入电平的库函数

            uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)

            参数:

                GPIOx - 哪一组GPIO

                GPIO_Pin - 哪一个脚

            返回对应脚的状态(1 - 高电平 0 - 低电平)

    物理按键在理想情况下按下松开是如下的电平信号

     

       

    实际上物理按键在按下和松开的时候会有一段时间的抖动(<10ms),造成发生多次按键操作的假象,我们需要通过延时操作消除抖动

     

       

     消抖的代码

        if(按下){

            //延时10ms

            if(按下){

                //真实按键事件

            }

        }

    以上的按键驱动叫做轮询操作,轮询操作实现简单,但是效率比较低

    更多的时候我们会使用中断来实现事件的响应,效率比较高

    .中断

    1.概念

      中断指的是计算机运行期间,出现了某些需要立即处理的事务,计算机能够自动停止当前正在运行的程序,转而去执行处理需要立即处理的事务的代码,执行完成后回到被打断的程序位置继续往下执行。

     

       

    2.stm32中断处理层次结构

     

       

    3.NVIC向量中断控制器

    1)特性

        

        NVIC的其他细节信息包含在 权威指南 中,其中包括 寄存器介绍以及优先级

    2stm32中断优先级

        stm32中断优先级分为响应优先级和抢占优先级

        高抢占优先级的中断可以打断正在执行的低抢占优先级的中断

        如果抢占优先级相同,高响应优先级的中断不能抢占低响应优先级的中断

        如果抢占优先级相同,当两个中断同时发生,优先响应响应优先级高的中断

        如果抢占优先级和响应优先级都相同,哪个中断先发生就响应哪个中断

    注意事项:

        1)数字越小,优先级越高

        2)抢占优先级和响应优先级一起占用固定的空间(4位二进制位)

            设置每种优先级占的位数叫做优先级分组,优先级分组程序中只能设置一次,多次设置带来不可预知的后果

        3)中断处理程序的时间尽可能短,禁止延时(睡眠)

    4.中断源(外部中断)

      由外部硬件设备触发的中断叫外部中断,外部中断可以配置为 电平触发和边沿触发,包含23个可编程的外部中断源,其中由IO口触发的中断是

      EXINT0 ---- EXINT15

         

       

      EXINT0可以选择任意一个GPIO组中的0号管脚接入(PA0 PB0...)

      之后的外部中断线依此类推

      EXINT15可以选择任意一个GPIO组中的15号管脚接入(PA15 PB15...)

    注:

      EXINT0 --- EXINT4有单独的中断号

      EXINT5-9共用一个中断号

      EXINT10-15共用一个中断号

    外部中断处理框图

        

    5.中断编程实现

    1)在程序开头设置优先级分组

        void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)

            


    /******************中断初始化*******************************************/

    2)使能SYSCFG时钟

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

    //中断源部分

    3)初始化GPIO为输入模式

        GPIO_Init(...)

    4)设置IO口和中断线的映射关系

        void SYSCFG_EXTILineConfig(uint8_t EXTI_PortSourceGPIOx, uint8_t EXTI_PinSourcex)

        参数:

            EXTI_PortSourceGPIOx - 哪一组

            EXTI_PinSourcex - 哪个脚

    5)初始化中断源

        void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct)

     typedef struct
    {
      uint32_t EXTI_Line;               /*!< 中断线 @ref EXTI_Lines */
      
      EXTIMode_TypeDef EXTI_Mode;       /*!< 中断or事件 @ref EXTIMode_TypeDef */

      EXTITrigger_TypeDef EXTI_Trigger; /*!< 触发边沿 @ref EXTITrigger_TypeDef */

      FunctionalState EXTI_LineCmd;     /*!< 使能/禁止 ENABLE or DISABLE */
    }EXTI_InitTypeDef;

    //NVIC部分

        void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct)

      typedef struct
    {
      uint8_t NVIC_IRQChannel;                    /*!< 中断通道(中断号) */

      uint8_t NVIC_IRQChannelPreemptionPriority;  /*!< 抢占优先级(不能超过分配的位数) */

      uint8_t NVIC_IRQChannelSubPriority;         /*!< 响应优先级(不能超过分配的位数) */

      FunctionalState NVIC_IRQChannelCmd;         /*!< 使能/禁止 ENABLE or DISABLE */  
    } NVIC_InitTypeDef;
     


    /*编写中断处理程序*/

    中断处理程序是一个函数,无参无返回值,函数名要去异常向量表中找

     void EXTI0_IRQHandler(void)

    {

        //..........

        //清除中断标识

        EXTI_ClearITPendingBit(EXTI_Line0);//

    }

  • 相关阅读:
    Ninject之旅之十四:Ninject在ASP.NET Web Form程序上的应用(附程序下载)
    Ninject之旅之十三:Ninject在ASP.NET MVC程序上的应用(附程序下载)
    Ninject之旅之十二:Ninject在Windows Form程序上的应用(附程序下载)
    Ninject之旅之十一:Ninject动态工厂(附程序下载)
    Ninject之旅之十:Ninject自定义提供者
    Ninject之旅之九:Ninject上下文绑定(附程序下载)
    Ninject之旅之八:Ninject插件模型(附程序下载)
    linq语句的顺序查询,查询结果不同
    layui 的使用 table 和后端数据交互
    获取post的参数
  • 原文地址:https://www.cnblogs.com/zjlbk/p/11502555.html
Copyright © 2011-2022 走看看