在LPC1114内部有一个特别的守时器——体系守时器(SysTick),它坐落Cortex-M0内核里边,是ARM内核的一部分,首要用来给操作体系供给时刻片轮转的守时,一般固定为10ms的守时,所以中文也称它为“嘀哒”守时器。在不跑操作体系时,能够把它当作一般守时器来用,一般用来进行程序延时。在前面的第一个演示示例中就用到过,下面就来评论一下怎么运用SysTick来供给延时。
体系守时器也坐落“私有外设总线”(Private peripheral bus)内,其地址为0xE000E010~0xE000E01F。下面先来看一下SysTick的内部结构,如下图所示。
从上图中能够看出,SysTick守时器的位长度是24位,即最长的计数次数为16777216次,且计数为倒数计数方法,递减到0时发生中止请求。计数的脉冲可直接取体系时钟,也可取半体系时钟。下表给出了和SysTick相关的寄存器。
{
__IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
__IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
__IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
__I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
} SysTick_Type;
SysTick守时器组的基址为0xE000E000,所以要将基址指针强制转换为上述结构体,还要加上下面的界说。
#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */
void SysTick_Handler(void)
{
体系守时中止服务程序部分
}
接下来评论一下体系守时器的初始值设置,因为守时的时长由体系时钟频率、体系时钟挑选和载入的初始值一起决议。假定体系时钟为48MHz,默许状况下SysTick的CLKSOURCE值为0,即挑选半体系时钟频率。这样,输入给守时器计数的时钟便是48/2=24MHz,计数周期为1/(24MHz)=1/24us,则计24次便是1us的守时,但实际上SysTick选用的是倒数计数方法,即从最大值顺次递减计数直到0发生溢出信号。所以24次计数实际上是0~23次,即最大值要减1,即24-1=23。一起要注意,因为计数位宽是24位,所以最大计数值不能超过2的24次方(即16777216),由此,可得出微秒级的初始值核算公式,如下:
LOAD=((24*us)-1),其间us取值规模1~699000
同理可得出毫秒级的初始值核算公式:
LOAD=((24000*ms)-1),其间ms取值规模1~699
上升到一般状况,守时初始值可用下面的公式来核算:
上式中,体系时钟SysClk的单位是MHz,CLKSOURCE的值是0或1,得到的是微秒等级的守时,要注意LOAD的值不能大于16777216。
下面来看一下前面第一个演示示例中的延时部分,代码如下:
static volatile uint32_t TimeTick = 0; //设置全局变量
void SysTick_Handler(void)
{
TimeTick++; //体系守时中止中,全局变量加1
}
void delay_ms(uint32_t ms)
{
SysTick->LOAD = (((24000)*ms)-1); //载入初始值
SysTick->VAL = 0;//写当时值寄存器使其清零
SysTick->CTRL |= ((1<<1)|(1<<0)); //翻开中止,发动守时器,挑选关体系时钟
while(!TimeTick);
TimeTick = 0; //当守时时刻届时,全局变量清零
SysTick->CTRL =0;//封闭守时器
}
可见上述守时是毫秒等级的,最长可守时699ms。
至此,第一个演示示例中的全部内容就都评论完了,可见在LPC1114中要完成一个简略的十二个LED替换闪耀,涉及到的内容仍是许多的。下面再来看一个流水灯的比如,要求完成一个12位的流水灯,时刻距离为100ms。假定LED选用共阳接法接在GPIO2端口,参阅代码如下:
#include
//===================体系守时器中止服务程序============================
void SysTick_Handler(void)
{
uint32_t temp;//界说暂时中心变量
temp = LPC_GPIO2->DATA;//读取当时端口2的值
temp = ~temp; //把中心变量进行取反
temp<<=1; //把中心变量进行左移一位
temp = ~temp; //再次把中心变量进行取反
LPC_GPIO2->DATA = temp; //把左移后的量赋给端口2
if(temp==0xFFF) //假如左移到头,则从头开始
{
LPC_GPIO2->DATA = 0xFFE;
}
}
//========================体系守时器初始化=============================
void SysTick_init(void)
{
SysTick->LOAD = (((24000)*100)-1);//设置100ms的守时
SysTick->VAL = 0; //计数清零
SysTick->CTRL |= ((1<<1)|(1<<0)); //答应中止,挑选半体系时钟,发动守时器
}
//============================主函数==================================
int main(void)
{
LPC_GPIO2->DIR = 0xFFF; //设置端口2为输出方向
LPC_GPIO2->DATA = 0xFFE;//端口2最低位输出0,点亮最末一个LED
SysTick_init();//调用体系守时器
while(1)
{
;//空循环
}
}
把程序编译后下载到LPC1114中,给体系上电,可看到接到端口2上的12个LED在闪耀活动。