cortexm3异常和中断.docx

上传人:b****5 文档编号:5599054 上传时间:2022-12-28 格式:DOCX 页数:13 大小:22.30KB
下载 相关 举报
cortexm3异常和中断.docx_第1页
第1页 / 共13页
cortexm3异常和中断.docx_第2页
第2页 / 共13页
cortexm3异常和中断.docx_第3页
第3页 / 共13页
cortexm3异常和中断.docx_第4页
第4页 / 共13页
cortexm3异常和中断.docx_第5页
第5页 / 共13页
点击查看更多>>
下载资源
资源描述

cortexm3异常和中断.docx

《cortexm3异常和中断.docx》由会员分享,可在线阅读,更多相关《cortexm3异常和中断.docx(13页珍藏版)》请在冰豆网上搜索。

cortexm3异常和中断.docx

cortexm3异常和中断

0.前言

本文想解决的问题有:

∙如何开启、关闭中断

∙如何开启、关闭异常

∙LPC177x/8x支持的中断优先级个数

∙复位后,异常/中断默认的优先级

∙如何设置异常/中断的优先级

∙什么是优先级组,如何设置优先级组,复位后的优先级组

1.Cortex-M3的异常/中断屏蔽寄存器组

注:

只有在特权级下,才允许访问这3个寄存器。

名字

功能描述

PRIMASK

只有单一比特的寄存器。

置为1后,就关掉所有可屏蔽异常,只剩下NMI和硬Fault可以响应。

默认值是0,表示没有关闭中断。

FAULTMASK

只有单一比特的寄存器。

置为1后,只有NMI可以响应。

默认值为0,表示没有关异常。

BASEPRI

该寄存器最多有9位(由表达优先级的位数决定)。

定义了被屏蔽优先级的阈值。

当它被设置为某个值后,所有优先级号大于等于此值的中断都被关。

若设置成0,则不关断任何中断,0为默认值。

注:

寄存器BASEPRI的有效位数受系统中表达优先级的位数影响,如果系统中只使用3个位来表达优先级,则BASEPRI有意义的值仅为0x00、0x20、0x40、0x60、0x80、0xA0、0xC0和0xE0

使用MRS/MSR指令访问这三个寄存器,比如:

MRSR0,BASEPRI;读取BASEPRI到R0中

MSRBASEPRI,R0;将R0数据写入到BASEPRI中

为了快速的开关中断,CM3还专门设置了一条CPS指令,有四种用法:

CPSIDI;PRIMASK=1,关中断

CPSIEI;PRIMASK=0,开中断

CPSIDF;FAULTMASK=1,关异常

CPSIEF;FAULTMASK=0,开异常

CMSIS-M3微控制器软件接口标准中的core_cm3.h给出了开关中断或异常的函数:

1.1开/关中断

1:

/**

2:

*@briefSetthePriorityMaskvalue

3:

*

4:

*@parampriMaskPriMask

5:

*

6:

*Settheprioritymaskbitintheprioritymaskregister

7:

*/

8:

static__INLINEvoid__set_PRIMASK(uint32_tpriMask)

9:

{

10:

registeruint32_t__regPriMask__ASM("primask");

11:

__regPriMask=(priMask);

12:

}

    使用__set_PRIMASK

(1)关闭中断;__setPRIMASK(0)开启中断。

    一些说明:

__INLINE是宏定义,对应__inline,这是keil编译器自定义关键字,表示这个函数是内联函数,但并不是强制性内联,编译器最终决定是否内联。

    __ASM(“primask”):

__ASM也是一个宏,对应__asm,这是keil编译器自定义关键字,关于这个关键字,有相当多的用法,可以在C中内嵌汇编语言、内嵌汇编函数、指定汇编标号以及本代码中的声明一个已命名寄存器变量。

这里,已命名的寄存器是("primask"),也就是说寄存器变量__regPriMask等同于编译器已命名的primask。

语法为:

registertypevar-name__asm(reg);

keil编译器已命名的寄存器变量为:

寄存器

__asm修饰的字符串

处理器

APSR

"apsr"

Allprocessors

CPSR

"cpsr"

Allprocessors

BASEPRI

"basepri"

Cortex-M3,Cortex-M4

BASEPRI_MAX

"basepri_max"

Cortex-M3,Cortex-M4

CONTROL

"control"

Cortex-M0,Cortex-M1,Cortex-M3,Cortex-M4

DSP

"dsp"

Cortex-M0,Cortex-M1,Cortex-M3,Cortex-M4

EAPSR

"eapsr"

Cortex-M0,Cortex-M1,Cortex-M3,Cortex-M4

EPSR

"epsr"

Cortex-M0,Cortex-M1,Cortex-M3,Cortex-M4

FAULTMASK

"faultmask"

Cortex-M3,Cortex-M4

IAPSR

"iapsr"

Cortex-M0,Cortex-M1,Cortex-M3,Cortex-M4

IEPSR

"iepsr"

Cortex-M0,Cortex-M1,Cortex-M3,Cortex-M4

IPSR

"ipsr"

Cortex-M0,Cortex-M1,Cortex-M3,Cortex-M4

MSP

"msp"

Cortex-M0,Cortex-M1,Cortex-M3,Cortex-M4

PRIMASK

"primask"

Cortex-M0,Cortex-M1,Cortex-M3,Cortex-M4

PSP

"psp"

Cortex-M0,Cortex-M1,Cortex-M3,Cortex-M4

PSR

"psr"

Cortex-M0,Cortex-M1,Cortex-M3,Cortex-M4

r0tor12

"r0"to"r12"

Allprocessors

r14orlr

"r14"or"lr"

Allprocessors

r13orsp

"r13"or"sp"

Allprocessors

r15orpc

"r15"or"pc"

Allprocessors

SPSR

"spsr"

Allprocessors,apartfromCortex-Mseriesprocessors.

XPSR

"xpsr"

 

XX文库-让每个人平等地提升自我XX文库-让每个人平等地提升自我Cortex-M0,Cortex-M1,Cortex-M3,Cortex-M4

1.2开/关异常

1:

/**

2:

*@briefSettheFaultMaskvalue

3:

*

4:

*@paramfaultMaskfaultMaskvalue

5:

*

6:

*Setthefaultmaskregister

7:

*/

8:

static__INLINEvoid__set_FAULTMASK(uint32_tfaultMask)

9:

{

10:

registeruint32_t__regFaultMask__ASM("faultmask");

11:

__regFaultMask=(faultMask&1);

12:

}

使用__set_FAULTMASK

(1)来关闭中断和异常;使用__set_FAULTMASK(0)开启中断和异常.

1.3更精确的优先级屏蔽

1:

/**

2:

*@briefSettheBasePriorityvalue

3:

*

4:

*@parambasePriBasePriority

5:

*

6:

*Setthebasepriorityregister

7:

*/

8:

static__INLINEvoid__set_BASEPRI(uint32_tbasePri)

9:

{

10:

registeruint32_t__regBasePri__ASM("basepri");

11:

__regBasePri=(basePri&0xff);

12:

}

比如想屏蔽优先级不高于0x60的中断,则使用代码:

__set_BASEPRI(0x60);如果想取消中断屏蔽,则使用__set_BASEPRI(0)即可。

2.异常/中断和优先级

    Cortex-M3的异常包括系统异常和外设中断,系统异常是Cortex-M3内核自带的一些异常,比如复位、总线Fault和SysTick等等(见表2-1),外设中断是指制造CPU的厂家加入的,比如串口、定时器中断等等(见表2-2)。

注:

关于异常和中断,想要分个清清楚楚实在有点困难。

异常和中断都可以“中断”正常执行的代码流,区别在于,异常是Cortex-M3内核产生的“中断”信号,而中断是Cortex-M3内核外部(片上外设或外部中断信号)产生的“中断”信号。

希望你看懂了,有时候你心里明白,但要讲的清清楚楚着实难!

表2-1:

系统异常

编号

类型

优先级

简介

0

N/A

N/A

1

复位

-3(最高)

复位

2

NMI

-2

不可屏蔽中断(来自外部NMI输入脚)

3

硬Fault

-1

只要FAULTMASK没有置位,硬Fault服务例程会被强制执行

4

存储器管理Fault

可编程

MPU访问违例以及访问非法位置均可引发。

企图在“非执行区”取址也会引发此Fault。

5

总线Fault

可编程

总线收到了错误响应,原因可以使预取流产或数据流产,企图访问协处理器也会引发此Fault

6

用法Fault

可编程

由于程序错误导致的异常。

通常是使用了一条无效指令,或者是非法的状态转换,例如尝试切换到ARM状态

7~10

保留

保留

保留

11

SVCall

可编程

执行系统服务调用指令(SVC)引发的异常

12

调试监视器

可编程

调试器(断点、数据观察点,或者是外部调试请求)

13

保留

保留

保留

14

PendSV

可编程

为系统设备而设的“可挂起请求”

15

SysTick

可编程

系统节拍时钟定时器(SysTick)

表2-2:

外设中断

编号

类型

优先级

简介

16

IRQ#0

可编程

外设中断#0

17

IRQ#1

可编程

外设中断#1

...

...

可编程

...

255

IRQ#239

可编程

外设中断#239

注:

表2-1和2-2中的“编号”有着特殊的意义,一是特殊功能寄存器IPSR中会记录当前正在服务的异常并给出了它的编号;二是优先级完全相同的多个异常同时挂起时,则先响应异常编号最小的那一个。

    一个发生的异常如果不能被立即响应,就称它被“挂起”,值得一提的是,对于被挂起的中断/异常,中断/异常信号不必由其产生者保持,NVIC的挂起状态寄存器会来保持这个信号。

所以哪怕后来挂起的中断源释放了中断请求信号,曾经的中断请求也不会丢失。

    除了复位、NMI和硬Fault三个异常具有固定的优先级外,其它所有异常和中断的优先级都是可以编程的。

这就涉及到优先级配置寄存器。

Cortex-M3优先级配置寄存器共8位,所以可以有256级的可编程优先级。

但是大多数Cortex-M3芯片都会精简设计。

    LPC177x/8x使用了优先级配置寄存器的5位,所以有32级可编程优先级。

复位后,对于所有优先级可编程的异常,其优先级都被初始化为0(最高优先级)

2.1设置异常/中断的优先级

2.1.1系统异常优先级设置

    SHPR1-SHPR3寄存器用于设置有可编程优先级的系统异常,可设置的优先级为0到31。

SHPR1-SHPR3可按字节访问。

为了提高软件效率,CMSIS简化了SCB寄存器的表述。

在CMSIS中,字节数组SHP[0]到SHP[12]对应于寄存器SHPR1至SHPR3。

表2-3:

SHPR1寄存器的位分配

名称

功能

[31:

24]

PRI_7

保留

[23:

16]

PRI_6

系统处理程序6的优先级,用法Fault

[15:

8]

PRI_5

系统处理程序5的优先级,总线Fault

[7:

0]

PRI_4

系统处理程序4的优先级,存储器管理Fault

表2-3:

SHPR2寄存器的位分配

名称

功能

[31:

24]

PRI_11

系统处理程序11的优先级,SVCall

[23:

0]

-

保留

表2-4:

SHPR3寄存器的位分配

名称

功能

[31:

24]

PRI_15

系统处理程序15的优先级,SysTick异常

[23:

16]

PRI_14

系统处理程序14的优先级,PendSV

[15:

0]

-

保留

注:

每个PRI_N域为8位宽,但是处理器仅实现每个域的位[7:

3],位[2:

0]读取值为零并忽略写入值。

2.1.2外设中断优先级设置

     LPC177x/8x微处理器的中断优先寄存器IPR0~IPR10用于设置外设中断优先级,控制41个外设中断。

每个IPRx可以按字节访问,在CMSIS中,字节数组IP[0]到IP[40]对应于寄存器IPR0~IPR10。

2.1.3系统异常/外设中断优先级设置C代码

1:

/**

2:

*@briefSetthepriorityforaninterrupt

3:

*

4:

*@paramIRQnThenumberoftheinterruptforsetpriority

5:

*@parampriorityTheprioritytoset

6:

*

7:

*Setthepriorityforthespecifiedinterrupt.Theinterrupt

8:

*numbercanbepositivetospecifyanexternal(devicespecific)

9:

*interrupt,ornegativetospecifyaninternal(core)interrupt.

10:

*

11:

*Note:

Theprioritycannotbesetforeverycoreinterrupt.*/

12:

static__INLINEvoidNVIC_SetPriority(IRQn_TypeIRQn,uint32_tpriority)

13:

{

14:

if(IRQn<0){/*setPriorityforCortex-M3SystemInterrupts*/

15:

SCB->SHP[((uint32_t)(IRQn)&0xF)-4]=((priority<<(8-__NVIC_PRIO_BITS))&0xff);

16:

}

17:

else{/*setPriorityfordevicespecificInterrupts*/

18:

NVIC->IP[(uint32_t)(IRQn)]=((priority<<(8-__NVIC_PRIO_BITS))&0xff);

19:

}

20:

}

    其中,参数IRQn为中断ID号,可以为负,也可以为正。

当IRQn为负时,设置系统异常的优先级,当IRQn大于等于0时,设置外设中断优先级。

__NVIC_PRIO_BITS是指使用到的优先级配置寄存器的位数,LPC177x/8x使用了5位。

为什么要使用(8-__NVIC_PRIO_BITS)呢?

这是因为优先级配置寄存器是高位对齐的(MSB),这主要方面不同CPU间的移植。

参数priority为要设置的优先级值,为0~31,数值越低,表示优先级越大。

LPC177x/8x的中断ID为:

系统异常ID:

标号

中断ID

描述

NonMaskableInt_IRQn

-14

不可屏蔽中断

MemoryManagement_IRQn

-12

Cortex-M3内存管理中断

BusFault_IRQn

-11

Cortex-M3总线Fault中断

UsageFault_IRQn

-10

Cortex-M3用法Fault中断

SVCall_IRQn

-5

Cortex-M3SVCall中断

DebugMonitor_IRQn

-4

Cortex-M3调试监视中断

PendSV_IRQn

-2

Cortex-M3PendSV中断

SysTick_IRQn

-1

Cortex-M3系统Tick中断

外设中断ID:

标号

中断ID

描述

标号

中断ID

描述

WDT_IRQn

0

看门狗

EINT3_IRQn

21

外中断3

TIMER0_IRQn

1

定时器0

ADC_IRQn

22

AD转换

TIMER1_IRQn

2

定时器1

BOD_IRQn

23

欠压检测

TIMER2_IRQn

3

定时器2

USB_IRQn

24

USB

TIMER3_IRQn

4

定时器3

CAN_IRQn

25

CAN

UART0_IRQn

5

UART0

DMA_IRQn

26

通用DMA

UART1_IRQn

6

UART1

I2S_IRQn

27

I2S

UART2_IRQn

7

UART2

ENET_IRQn

28

以太网

UART3_IRQn

8

UART3

MCI_IRQn

29

SD/MMC卡I/F

PWM1_IRQn

9

PWM1

MCPWM_IRQn

30

电机控制PWM

I2C0_IRQn

10

I2C0

QEI_IRQn

31

正交编码接口

I2C1_IRQn

11

I2C1

PLL1_IRQn

32

PLL1锁存

I2C2_IRQn

12

I2C2

USBActivity_IRQn

33

USB活动

Reserved0_IRQn

13

保留

CANActivity_IRQn

34

CAN活动

SSP0_IRQn

14

SSP0

UART4_IRQn

35

UART4

SSP1_IRQn

15

SSP1

SSP2_IRQn

36

SSP2

PLL0_IRQn

16

PLL0锁存

LCD_IRQn

37

LCD

RTC_IRQn

17

RTC

GPIO_IRQn

38

GPIO

EINT0_IRQn

18

外中断0

PWM0_IRQn

39

PWM0

EINT1_IRQn

19

外中断1

EEPROM_IRQn

40

EEPROM

EINT2_IRQn

20

外中断2

 

 

 

2.2设置异常/中断的优先级组

    Cortex-M3的异常/中断是可以抢占的,高抢占优先级中断可以抢占低抢占优先级中断。

NVIC中有个名字叫做“应用程序中断及复位控制寄存器(AIRCR)”的寄存器,该寄存器的bit[10:

8]称为优先级分组(PRIGROUP)段,表示的值为0~7,分别对应8个不同的抢占优先级设置。

比如优先级分组段为0时,则8位优先级配置寄存器(LPC177x/8x只使用了其中的5位)的bit[7:

1]表示抢占优先级,bit[0:

0]表示非抢占优先级;再比如优先级分组段为1时,则8位优先级配置寄存器的bit[7:

2]表示抢占优先级,bit[1:

0]表示非抢占优先级,依次类推。

    复位后,优先级分组(PRIGROUP)段默认值为0,也就是则8位优先级配置寄存器(LPC177x/8x只使用了其中的5位)的bit[7:

1]表示抢占优先级,bit[0:

0]表示非抢占优先级。

而LPC177x/8x只使用了8位优先级配置寄存器其中的bit[7:

3],所以对于LPC177x/8x微处理器而言,复位后默认32级优先级全部为可抢占优先级。

2.2.1设置优先级寄存器组的C代码

1:

/**

2:

*@briefSetthePriorityGroupinginNVICInterruptController

3:

*

4:

*@paramPriorityGroupisprioritygroupingfield

5:

*

6:

*Settheprioritygroupingfieldusingtherequiredunlocksequence.

7:

*Theparameterpriority_groupingisassignedtothefield

8:

*SCB->AIRCR[10:

8]PRIGROUPfield.Onlyvaluesfrom0..7areused.

9:

*Incaseofaconflictbetweenprioritygroupingandavailable

10:

*prioritybits(__NVIC_PRIO_BITS)thesmallestpossibleprioritygroupisset.

11:

*/

12:

static__INLINEvoidNVIC_SetPriorityGrouping(uint32_tPriorityGroup)

13:

{

14:

uint32_treg_value;

15:

/*onlyvalues0..7areused*/

16:

uint32_tPriorityGroupTmp=(PriorityGroup&0x07);

17:

18:

reg_value=SCB->AIRCR;/*readoldregisterconfiguration*/

19:

/*clearbitstochange*/

20:

reg_value&=~(SCB_AIRCR_VECTKEY_Msk|SCB_AIRCR_PRIGROUP_Msk);

21:

/*Insertwritekeyandpriortygroup*/

22:

reg_value=(reg_value|

23:

(0x5FA<

24:

(PriorityGroupTmp<<8));

25:

SCB->AIRCR=reg_value;

26:

}

    其中,参数PriorityGroup为要设置的优先级分组(PRIGROUP)段的值,取值范围为0~7.由于操作AIRCR寄存器需要访问钥匙,所以要把0x05FA写入到该寄存器的bit[31:

16]中,否则写入的值会被忽略。

    需要注意的是,在一个设计好的产品中,如

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > PPT模板 > 其它模板

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1