上次讲的只剩滴答定时器的优先级设置函数NVIC_SetPriority没有讲,这个函数具体如下
static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
{
if(IRQn < 0) {
SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } * set Priority for Cortex-M3 System Interrupts */
else {
NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } * set Priority for device specific Interrupts */
}
它是设置中断标号以及优先级的函数,由于滴答定时器是系统内部中断因此优先级是通过SCB中的SHP寄存器设置的。
这里的SCB无论是STM32技术手册还是CORTEX技术手册都没有具体的说明,在英文的cortex编程手册中介绍,这个是系统控制块system control block。
库函数中,SCB的基地址为0xE000ED00,其结构体如下(注释符还是跟原来同理。。怕被注释)
typedef struct
{
__I uint32_t CPUID; *!< Offset: 0x00 CPU ID Base Register */
__IO uint32_t ICSR; *!< Offset: 0x04 Interrupt Control State Register */
__IO uint32_t VTOR; *!< Offset: 0x08 Vector Table Offset Register */
__IO uint32_t AIRCR; *!< Offset: 0x0C Application Interrupt / Reset Control Register */
__IO uint32_t SCR; *!< Offset: 0x10 System Control Register */
__IO uint32_t CCR; *!< Offset: 0x14 Configuration Control Register */
__IO uint8_t SHP[12]; *!< Offset: 0x18 System Handlers Priority Registers (4-7, 8-11, 12-15) */
__IO uint32_t SHCSR; *!< Offset: 0x24 System Handler Control and State Register */
__IO uint32_t CFSR; *!< Offset: 0x28 Configurable Fault Status Register */
__IO uint32_t HFSR; *!< Offset: 0x2C Hard Fault Status Register */
__IO uint32_t DFSR; *!< Offset: 0x30 Debug Fault Status Register */
__IO uint32_t MMFAR; *!< Offset: 0x34 Mem Manage Address Register */
__IO uint32_t BFAR; *!< Offset: 0x38 Bus Fault Address Register */
__IO uint32_t AFSR; *!< Offset: 0x3C Auxiliary Fault Status Register */
__I uint32_t PFR[2]; *!< Offset: 0x40 Processor Feature Register */
__I uint32_t DFR; *!< Offset: 0x48 Debug Feature Register */
__I uint32_t ADR; *!< Offset: 0x4C Auxiliary Feature Register */
__I uint32_t MMFR[4]; *!< Offset: 0x50 Memory Model Feature Register */
__I uint32_t ISAR[5]; *!< Offset: 0x60 ISA Feature Register */
} SCB_Type;
其结构体与技术手册中的寄存器完全对应,可以看到 __IO uint8_t SHP[12] ,其是系统异常优先级寄存器,关于这个为什么8位寄存器,12个8位,同样需要参考cm3编程手册。
其地址虽然是连续的,但是实际寄存器内部分布比较特殊
下面回到程序
SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff)
查滴答定时器的中断标号为-1,这里涉及了uint32_t(32位无符号整形)强制转换一个负数,由于stm32必须通过硬件才能进入调试状态,因此使用visual C/C++编个程序验证一下.
#include
typedef unsigned __int32 uint32_t;
void main()
{
//typedef unsigned __int32 uint32_t;
int aa=-1;
uint32_t bb = 888;
bb=(uint32_t)aa;
printf("bb is %x", bb);
}
最后得出的结果是0xFFFFFFFF,这里的原因在于机器存储负数的机制,最高位为符号位,负数为其补码,补码为反码加一,因此-1表示就是10000001,反码11111110,补码1111111,32位表示就是0xFFFFFFFF。
回到程序中其实就是0xF-4,也就是SHP[11],也就是寄存器组的最后一个。
#define __NVIC_PRIO_BITS 4 *!< STM32 uses 4 Bits for the Priority Levels */
代入得出优先级是15,也就是系统中断的最低优先级。
滴答定时器就全部介绍完毕啦,实际滴答定时器用起来只要会算计数值就可以了,为什么这么详细呢,因为我自己认为这是学stm32的一个方法,学会了这种思路,以后学习stm32不论是内核还是外设,都能触类旁通,明白学习库函数到寄存器到数据手册的流程
上一篇:stm32之nRF24L01无线模块(2):无线模块的地址
下一篇:stm32之滴答定时器(3):滴答定时器的初始化设置
推荐阅读
史海拾趣
引言 目前,以太网802.3协议和TCP/IP协议是现今嵌入式系统接入Internet的首选协议。而以太网(Ethernet)的核心思想是多用户使用共享的公共传输信道,它通过带冲突检测的载波侦听多路访问协议(CSMA/CD)来控制对介质的访问。 本文给出了完全用FPGA ...… 查看全部问答∨ |
|
上海公司招聘以下职位,有兴趣请速发简历到xinjihr_cn@126.com,或者msn: mouhuitou@hotmail.com,谢谢 ASIC Verfication Engineer: 1)本科以上学历 2)有3年左右验证工作背景. 3)熟悉system verilog最好. Process Engineer: 1)本科以上学历 2) ...… 查看全部问答∨ |
程序要分离系统声音和按键声音,使两者互不干扰。 现在系统声音的设置通过waveOutSetVolume(0, 音量值) 这种情况下,可不可以实现另外做一个音频的通道,使其不受主音量的干扰,成为按键的声音? 要怎么做才能实现呢? 请指教啊~~~~~谢谢… 查看全部问答∨ |
各位大大,知道怎样在UC/OS II 中实现route add , rout delete之类的路由函数功能? 或者这些函数的原型是怎么样的? 谢谢!… 查看全部问答∨ |
现在有个心片,是一个usb的audio设备 ,我现在可以把她作为一个普通的usb设备读写,但是现在有个问题就是希望该设备作为audio 设备来播放音乐,除了控制命令用endpoint1和4来传外,另外的audio channel怎么指定啊? 谢谢指定一下!… 查看全部问答∨ |
今天熟悉了一下LM提供的StellarisWare固件库,感觉跟STM32的固件库有很大的差异,使用上有点像Windows平台API函数的意思,使用外设的时候到对应的固件库看看有啥函数可以用就行了。 &nbs ...… 查看全部问答∨ |