// Configuring the System Control Space (SCS) registers
typedef volatile struct
{
int MasterCtrl;
int IntCtrlType;
int zReserved008_00c[2];
/* Reserved space */
struct {
int Ctrl;
int Reload;
int Value;
int Calibration;
} SysTick;
int zReserved020_0fc[(0x100-0x20)/4];
/* Reserved space */
/* Offset 0x0100 */
struct {
int Enable[32];
int Disable[32];
int Set[32];
int Clear[32];
int Active[64];
int Priority[64];
} NVIC;
int zReserved0x500_0xcfc[(0xd00-0x500)/4];
/* Reserved space */
/* Offset 0x0d00 */
int CPUID;
int IRQcontrolState;
int ExceptionTableOffset;
int AIRC;
int SysCtrl;
int ConfigCtrl;
int SystemPriority[3];
int SystemHandlerCtrlAndState;
int ConfigurableFaultStatus;
int HardFaultStatus;
int DebugFaultStatus;
int MemManageAddress;
int BusFaultAddress;
int AuxFaultStatus;
int zReserved0xd40_0xd90[(0xd90-0xd40)/4];
/* Reserved space */
/* Offset 0x0d90 */
struct {
int Type;
int Ctrl;
int RegionNumber;
int RegionBaseAddr;
int RegionAttrSize;
} MPU;
} SCS_t;
要搞懂它们,看到头都大了!
是 从 ARM 公司下载的的文件
《Application Note 179 Cortex -M3 Embedded Software Development》
是《Cortex-M3 权威指南》介绍下载的
看来,深入研究 CM3的高手不多啊!
要成为高手,这些都不懂!?
刚刚发现的 中文板CORTEX-M3 权威指南的错误。
表D.12 向量表偏移量寄存器(VTOR) 0xE000_ED08
位段 名称 类型 复位值 描述
29 TBLBASE RW 0 向量表是在Code 区(0),还是在RAM 区(1)
15 ENDIANESS R ‐ 向量表的起始地址
正确是如下:
Table 8-15 Vector Table Offset Register bit assignments
Field Name Definition
[31:30] - Reserved
[29] TBLBASE Table Base is in Code (0) or RAM (1)
[28:7] TBLOFF Vector table base offset field. Contains the offset of the table base from the bottom of the SRAM
or CODE space.
[6:0] - Reserved.
在 void NVIC_Configuration(void) 有如下语句:
#ifdef VECT_TAB_RAM
/* Set the Vector Table base location at 0x20000000 */
NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
#else /* VECT_TAB_FLASH */
/* Set the Vector Table base location at 0x08000000 */
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
#endif
再看看函数的代码:
void NVIC_SetVectorTable(u32 NVIC_VectTab, u32 Offset)
{
/* Check the parameters */
assert(IS_NVIC_VECTTAB(NVIC_VectTab));
assert(IS_NVIC_OFFSET(Offset));
SCB->ExceptionTableOffset = NVIC_VectTab | (Offset & (u32)0x1FFFFF80);
}
我的STM32头文件更正如下:
//------------------------------------------------------------------------
// 向量表偏移量寄存器(VTOR) 0xE000_ED08
//------------------------------------------------------------------------
struct SCB_ExceptionTableOffset_BITS {
Uint32 Reserved :15; // 6:0
Uint32 TBLOFF :1; // 28:7 Vector table base offset field. Contains the offset of the table base from the bottom of the SRAMor CODE space.
Uint32 TBLBASE :1; // 29 向量表是在Code 区(0),还是在RAM 区(1)TBLBASE Table Base is in Code (0) or RAM (1)
Uint32 Reserved0 :2; // 31:30
};
union SCB_ExceptionTableOffset_REG {
Uint32 all;
struct SCB_ExceptionTableOffset_BITS bit;
};
高错了!
struct SCB_ExceptionTableOffset_BITS {
Uint32 Reserved :7; // 6:0
Uint32 TBLOFF :22; // 28:7 Vector table base offset field. Contains the offset of the table base from the bottom of the SRAMor CODE space.
Uint32 TBLBASE :1; // 29 向量表是在Code 区(0),还是在RAM 区(1)
Uint32 Reserved0 :2; // 31:30
};
那些是CM3内核的一些寄存器,是针对群星的片子的
STM32并没有MPU
斑竹可否说说 优先级分组 和优先级设置的方法。
这个函数也太罗嗦了吧,偶看到头都大了!望各位指教。
void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct)
{
u32 tmppriority = 0x00, tmpreg = 0x00, tmpmask = 0x00;
u32 tmppre = 0, tmpsub = 0x0F;
/* Check the parameters */
assert(IS_FUNCTIONAL_STATE(NVIC_InitStruct->NVIC_IRQChannelCmd));
assert(IS_NVIC_IRQ_CHANNEL(NVIC_InitStruct->NVIC_IRQChannel));
assert(IS_NVIC_PREEMPTION_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority));
assert(IS_NVIC_SUB_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelSubPriority));
if (NVIC_InitStruct->NVIC_IRQChannelCmd != DISABLE)
{
/* Compute the Corresponding IRQ Priority --------------------------------*/
tmppriority = (0x700 - (SCB->AIRC & (u32)0x700))>> 0x08;
tmppre = (0x4 - tmppriority);
tmpsub = tmpsub >> tmppriority;
tmppriority = (u32)NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority << tmppre;
tmppriority |= NVIC_InitStruct->NVIC_IRQChannelSubPriority & tmpsub;
tmppriority = tmppriority << 0x04;
tmppriority = ((u32)tmppriority) << ((NVIC_InitStruct->NVIC_IRQChannel & (u8)0x03) * 0x08);
tmpreg = NVIC->Priority[(NVIC_InitStruct->NVIC_IRQChannel >> 0x02)];
tmpmask = (u32)0xFF << ((NVIC_InitStruct->NVIC_IRQChannel & (u8)0x03) * 0x08);
tmpreg &= ~tmpmask;
tmppriority &= tmpmask;
tmpreg |= tmppriority;
NVIC->Priority[(NVIC_InitStruct->NVIC_IRQChannel >> 0x02)] = tmpreg;
/* Enable the Selected IRQ Channels --------------------------------------*/
NVIC->Enable[(NVIC_InitStruct->NVIC_IRQChannel >> 0x05)] =
(u32)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (u8)0x1F);
}
else
{
/* Disable the Selected IRQ Channels -------------------------------------*/
NVIC->Disable[(NVIC_InitStruct->NVIC_IRQChannel >> 0x05)] =
(u32)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (u8)0x1F);
}
}