ARM架构与编程——异常与中断实战:SysTick异常

文章介绍了如何利用Cortex-M处理器内置的SysTick定时器创建周期性中断,以此控制LED灯的闪烁。首先设置了SysTick的控制和状态寄存器、重载值寄存器以及当前值寄存器,然后通过设置时钟源和计数值来实现1秒一次的中断。在中断处理函数中,切换LED的状态并清除异常。此外,还展示了相关的初始化代码和异常处理函数。
摘要由CSDN通过智能技术生成

实战_SysTick异常

本节课程使用CPU自带的SysTick定时器,让它产生周期性的中断,用来操作LED。

1.1 SysTick操作

Cortex-M处理器内部集成了一个小型的、名为SysTick的定时器。可以使用它来为操作系统提供系统时钟,也可以把它当做一般的定时器。
之所以在处理器内增加这样的定时器,是为了提高软件的可以移植性。
它是一个24位的定时器,向下计数。
在时钟源的驱动下,计数值到达0时,可以触发异常。然后我们就可以定义异常处理函数,每当触发异常时,就可以去执行函数中的操作。
它的框图如下:
在这里插入图片描述
在本程序中,只需要设置这几个寄存器即可:
我们通过定义一个结构体来操作这些寄存器

typedef struct
{
   
  volatile unsigned int CTRL;            /*!< Offset: 0x000 (R/W)  SysTick Control and Status Register */
  volatile unsigned int LOAD;            /*!< Offset: 0x004 (R/W)  SysTick Reload Value Register */
  volatile unsigned int VAL;             /*!< Offset: 0x008 (R/W)  SysTick Current Value Register */
  volatile unsigned int CALIB;           /*!< Offset: 0x00C (R/ )  SysTick Calibration Register */
} SysTick_Type;

#define SysTick_BASE        (0xE000E000 +  0x0010UL) 
#define SYSTICK_FRE   (8000000)

1.SysTick->CTRL
时钟源选择:
在这里插入图片描述
时钟源有两个,所以还要选择时钟源,这时我们需要操作如下几位

  • bit2 设置为1,选择时钟来源为内部处理器的时钟;
  • bit1 设置为1,使能异常
  • bit0 设置为0,使能定时器
/* 3.选择时钟源,使能systick,使能异常 */
// 分别设置bit2,bit1,bit0
   SysTickInit->CTRL = (1<<2) | (1<<1) | (1<<0);

2.SysTick->VAL
设置计数器VAL的值
在这里插入图片描述
已知基地址为:(0xE000E000 + 0x0010UL) ;我们通过定义一个宏来操作这个地址#define SysTick_BASE (0xE000E000 + 0x0010UL)
计数值count的计算:

1s钟产生1次异常
晶振8MHz,计时器count值为 val = 1/T ;
T = 1/8MHz
1s钟计数器的填充值应该为:val = 1/ 1/8M = 8000000

我们也通过定义一个宏来操作计数值:#define SYSTICK_FRE (8000000)

SysTickInit->VAL = SYSTICK_FRE;

3.SysTick->LOAD
LOAD自动重装寄存器也需要设置对应的重装值
在这里插入图片描述

 /* 2.设置LOAD寄存器,重新加载值 */
    SysTickInit->LOAD = SYSTICK_FRE;

1.2 清除SysTick异常

最后,当我们设置完上述寄存器后,还需要清除这个异常转态,让程序跳过异常,继续向下执行
在这里插入图片描述
清除systick的挂起状态
在这里插入图片描述
我们也通过宏定义来设置bit25

/* 清除异常状态 ;设置SCB中的ICSR为1*/
    SCB->ICSR |= SCB_ICSR_PENDSTCLR_Msk;

1.3 通过systick异常来控制LED闪烁

代码实现:

  • start.s

                PRESERVE8
                THUMB


; Vector Table Mapped to Address 0 at Reset
                AREA    RESET, DATA, READONLY
				EXPORT  __Vectors
				;IMPORT HardFault_Handler
				
				IMPORT SysTick_Handler
					
					
__Vectors       DCD     0                  
                DCD     0x08000009; //Reset_Handler              ; Reset Handler
				DCD     0                ; NMI Handler
                DCD     0          ; Hard Fault Handler
                DCD     0          ; MPU Fault Handler
                DCD     0           ; Bus Fault Handler
                DCD     0         ; Usage Fault Handler
                DCD     0                          ; Reserved
                DCD     0                          ; Reserved
                DCD     0                          ; Reserved
                DCD     0                          ; Reserved
                DCD     0                ; SVCall Handler
                DCD     0           ; Debug Monitor Handler
                DCD     0                          ; Reserved
                DCD     0             ; PendSV Handler
                DCD     SysTick_Handler            ; SysTick Handler

				AREA    |.text|, CODE, READONLY

; Reset handler
Reset_Handler   PROC
				EXPORT  Reset_Handler             [WEAK]
                IMPORT  mymain

				IMPORT SystemInit
				IMPORT uart_init
				IMPORT SysTickInit
				IMPORT LedInit

				LDR SP, =(0x20000000+0x10000)
				
				BL SystemInit
				
				BL uart_init
				
				BL SysTickInit
				BL LedInit
				
				
		
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值