• stm32片上资源分析


    SysTick----系统定时器----常用的寄存器:STK_VAL、STK_LOAD、STK_CTRL

    ----SysTick定时器被捆绑在NVIC中,用于产生SysTick异常(异常号:15)
      -----SysTick是一个24位的定时器,即一次最多可以计数224 个时钟脉冲,这个脉冲计数值被保存到 当前计数值寄存器STK_VAL (SysTick current valueregister) 中,只能向计数,每接收到一个时钟脉冲STK_VAL的值就向下减1,直至0,当STK_VAL的值被减至0时,由硬件自动把重载寄存器STK_LOAD(SysTick reload valueregister)中保存的数据加载到STK_VAL(相当于51定时器模式2),重新向下计数。当STK_VAL的值被计数至0时,触发异常,就可以在中断服务函数中处理定时事件了。
    -----SysTick_Config(uint32 ticks)此函数用来配置SysTick(详见st的库函数)。注:如果不配置SysTick的clk_source和SystemLP的话就不用添加misc这个中断设置文

    NVIC----中断控制器(关于stm32的优先级分组我就不解释了,参考书很多;这里我主要是想结合ARICR这个寄存器分析NVIC的函数)
    先给个链接看看吧http://www.ichanging.org/stm32_NVIC.html
    ----关于ARICR这个寄存器(关于这个寄存器的资料很少),它配置了中断的优先级分组






                                             

    详细的内容可以参看这个http://d1.ourdev.cn/bbs_upload782111/files_48/ourdev_699297A502KF.pdf
    ----void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)//定义了中断优先级分组
    库函数如下:SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup;

    相关宏定义如下: #define NVIC_PriorityGroup_0         ((uint32_t)0x700)

    #define NVIC_PriorityGroup_1         ((uint32_t)0x600)

    #define NVIC_PriorityGroup_2         ((uint32_t)0x500)
    #define NVIC_PriorityGroup_3         ((uint32_t)0x400)
    #define NVIC_PriorityGroup_4         ((uint32_t)0x300)
    #define AIRCR_VECTKEY_MASK    ((uint32_t)0x05FA0000)
    由上可知NVIC_PriorityGroupConfig函数就是改变了ARICR寄存器的[8-10]位来配置中断优先级分组的
    到此你也许会有两个问题:
    1:SCB是什么:SCB是st库定义的一个数据结构(其实就是一段连续的地址空间,查看core_m3.h中scb的定义可知,下面的NVIC类同)
    AIRCR_VECTKEY_MASK定义为  0x05FA0000,请看下图
    ----void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct)//设置外设的中断
    库函数如下:
    tmppriority = (0x700 - ((SCB->AIRCR) & (uint32_t)0x700))>> 0x08;
        tmppre = (0x4 - tmppriority);
        tmpsub = tmpsub >> tmppriority;
        tmppriority = (uint32_t)NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority << tmppre;
        tmppriority |=  NVIC_InitStruct->NVIC_IRQChannelSubPriority & tmpsub;
        tmppriority = tmppriority << 0x04;//如果你看了上面的pdf的话 就会理解为什么要想左移4位
        NVIC->IP[NVIC_InitStruct->NVIC_IRQChannel] = tmppriority;
        /* Enable the Selected IRQ Channels --------------------------------------*/
        NVIC->ISER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] =

          (uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F);

    函数实现的功能:根据NVIC_IRQChannelPreemptionPriority、NVIC_IRQChannelSubPriority和中断优先级分组设置好对应外设的中断响应
    这里需要注意的是不能随便设置NVIC_IRQChannelPreemptionPriority和NVIC_IRQChannelSubPriority,否则会出现意想不到的错误。你可以在
    NVIC_PriorityGroup_4情况下,NVIC_IRQChannelPreemptionPriority不为0,则会出现你不想要的结果(具体原因你可以查看和上面的文档)
    ----SysTick_Config(由于此函数中也有中断相关的内容,所以没在SysTick分析而放在了这里;SysTick这个有别与其他外设中断)
    追踪库函数SysTick_Config,发现与中断有关的函数是
    ----static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority),然后函数体是:
     SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff);
    库函数默认SysTick的中断是最小的(查看__NVIC_PRIO_BITS值为4),注意此时SysTick中断的优先级分组也是按照ARICR来进行的(至于SHP是什么查库函数吧)

    最后解释下为什么说SysTick和其他外设中断不一样呢,stm32包含60个可屏蔽中断通道(不包含16个Cortex™-M3的中断线),SysTick属于后者。

    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    strcpy,memset,memcpy三者之间的根本区别
    最便捷、最强大、速度最快的C++序列化框架
    C++读写二进制文件
    boost binary 序列化
    febird.dataio和boost.serialization性能对比
    Boost文本序列化和二进制序列化的效率比较
    Boost文本序列化和二进制序列化的效率比较
    c++的vector赋值方法汇总
    OCP-1Z0-051-V9.02-36题
    遍历list或map时删除元素(较巧妙)
  • 原文地址:https://www.cnblogs.com/vendanner/p/4784386.html
Copyright © 2020-2023  润新知