实现软件的短时间延迟
利用 Cortex-M3 内核包含的 SysTick 时钟代替 Delay(N) ,实现延时N毫秒的精确值。
SysTick 为一个24位递减计数器,SysTick 设定初值并使能后, 每经过1个系统时钟周期,计数值就减1。计数到0时,SysTick计数器自动重装初值并继续计数,同时内部的 COUNTFLAG 标志会置位,触发中断(如果中断使能)。
在 STM32 的应用中,使用 Cortex-M3 内核的 SysTick 作为定时时钟,设定每一毫秒产生一次中断,在中断处理函数里对N减一,在 Delay(N) 函数中循环检测N是否为0,不为0则进行循环等待;若为0则关闭 SysTick 时钟,退出函数。延迟时间将不随系统时钟频率改变。
应用举例:
//条件:外部晶振为8MHz,系统时钟为72MHz,SysTick的频率9MHz,SysTick产生1ms的中断。
//初始化相关模块:
SysTick_SetReload(9000); // 设定SysTick达到1ms计数结束
SysTick_ITConfig(ENABLE); // 使能SysTick中断
//中断处理:
void SysTickHandler(void)
{
if (TimingDelay != 0x00) //全局变量TimingDelay必须定义为volatile
TimingDelay--;
}
//延时代码:
void Delay(u32 nTime)
{
SysTick_CounterCmd(SysTick_Counter_Enable); // 使能SysTick计数器
TimingDelay = nTime; // 读取延时时间
while(TimingDelay != 0); // 判断延时是否结束
SysTick_CounterCmd(SysTick_Counter_Disable);// 关闭SysTick计数器
SysTick_CounterCmd(SysTick_Counter_Clear); // 清除SysTick计数器
}
//应用代码:
Delay(300); // 延时300ms
PVD使用
在应用开发中,通常都要考虑到当系统电压下降或掉电状况,一旦出现该状况应对控制系统加以保护。故在程序中需要加入对系统电压的监控。当供电电压降低到某一电压值时,需要系统进入特别保护状态,执行紧急关闭任务:对系统的一些数据保存起来,同时对外设进行相应的保护操作。
常用设计思路:使用ADC对工作电压进行监控,MCU每隔一段时间读取ADC的转换值,并进行比较,判别电压是否下降到安全电压以下,电压正常时程序进行其他 任务的运行;电压异常时程序进行保护模式,对相关寄存器、外设进行保护操作。这种方法会占用MCU的处理时间,同时使用ADC增加了系统的功耗。
STM32内部自带一个可编程电压监测器(PVD),用于对VDD的电压进行监控。对应的电源控制寄存器中的PLS[2:0]位可用来设定监控电压的阀值,通过对外部电压进行比较来监控电源。
电源控制 / 状态寄存器(PWR_CSR)中的PVDO标志用来表明VDD是高于还是低于PVD的电压阀值。当VDD下降到PVD阀值以下和 / 或当VDD上升到PVD阀值之上时,根据外部中断第16线的上升 / 下降边沿触发设置,就会产生PVD中断。在中断处理程序中执行紧急关闭任务:将MCU的寄存器、内存的数据保存起来,同时对外设进行相应的保护操作。
应用举例:
//系统启动后启动PVD,并开启相应的中断
PWR_PVDLevelConfig(PWR_PVDLevel_2V8); // 设定监控阀值
PWR_PVDCmd(ENABLE); // 使能PVD
EXTI_StructInit(&EXTI_InitStructure);
EXTI_InitStructure.EXTI_Line = EXTI_Line16; // PVD连接到中断线16上
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; // 使用中断模式
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Raising; // 电压低于阀值时产生中断
EXTI_InitStructure.EXTI_LineCmd = ENABLE; // 使能中断线
EXTI_Init(&EXTI_InitStructure); // 初始化中断控制器
/*
EXTI_InitStructure.EXTI_Trigger 的赋值可选项:
¾EXTI_Trigger_Rising---表示电压从高下降到低于设定阀值时产生中断;
¾EXTI_Trigger_Falling---表示电压从低上升到高于设定阀值时产生中断;
¾EXTI_Trigger_Rising_Falling---表示电压上升或下降越过设定阀值时都产生中断。
*/
//当工作电压低于设定阀值时,将产生一个中断,在中断程序中进行相应的处理:
void PVD_IRQHandler(void)
{
EXTI_ClearITPendingBit(EXTI_Line16);
… … // 用户添加紧急处理代码处
}