中断版(访问密码: 1666)
效果如下图,
延时版 (访问密码: 1666)
效果如下图,
延时版本:不需要开启定时器。
可以配置时钟源,在使用滴答计时器进行延时时,使能滴答计时器 ,使用完毕后,需要失能计时器。
延时us时,需要如下配置 :
1、在装载寄存器LOAD中装载预期值
2、将计数器VAL清空
3、使能控制寄存器CTRL,开启计时
4、读取寄存器状态,判断计时完成
5、失能控制寄存器CTRL,关闭计时
/* 功 能: 延时nus
* 输 入: nus 要延时的us数.
* 输 出:
* 返 回:
* 备 注:
*/
void HW_SysTick_Delay_us(uint32_t nus)
{
if(nus == 0) return;
uint32_t temp;
SysTick->LOAD=nus*fac_us; //时间加载
SysTick->VAL=0x00; //清空计数器
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //开始倒数
do
{
temp=SysTick->CTRL; //读取控制寄存器与状态寄存器
}while((temp&0x01)&&!(temp&(1<<16))); //等待时间到达
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器
SysTick->VAL =0X00; //清空计数器
}
/* 功 能: 延时nus
* 输 入: nms 要延时的ms数.
* 输 出:
* 返 回:
* 备 注:
1、SysTick->LOAD为24位寄存器,所以,最大延时为:nms<=0xffffff*8*1000/SYSCLK
2、SYSCLK单位为Hz,nms单位为ms,对72M条件下,nms<=1864
*/
void HW_SysTick_Delay_ms(uint16_t nms)
{
if(nms == 0) return;
uint32_t temp;
SysTick->LOAD=(u32)nms*fac_ms; //时间加载(SysTick->LOAD为24bit)
SysTick->VAL =0x00; //清空计数器
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //开始倒数
do
{
temp=SysTick->CTRL;
}while((temp&0x01)&&!(temp&(1<<16))); //等待时间到达
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器
SysTick->VAL =0X00; //清空计数器
}
//
传参计数范围?
需要注意滴答计数器支持多少位数据
103芯片,支持24位计数器
故最大延时为:nms<=0xffffff*8*1000/SYSCLK = 1864.135 (SYSCLK = 72M)
1、滴答计数器时钟源支持最大频率为系统时钟的1/8,
故滴答计数器时钟源 = SYSCLK / 8(即1s,计数为SYSCLK / 8)
2、24位计数器
故计数器计数范围为0-0xFFFFFF(6个4位数据,即为6个F)
3、此处计算ms级最大值,
从s级到ms级,存在1000倍比例
故nums =1/时钟源(单位:s/计数值) * 0xFFFFFF(单位:计数值) = 1.864135(单位:s)
= 1.864135(单位:s)* 1000(单位:ms/s)
= 1864.135(单位:ms)
/* 功 能: 延时nus
* 输 入: nms 要延时的ms数.
* 输 出:
* 返 回:
* 备 注:
在 HW_SysTick_Delay_ms 最大值基础上,允许更大延时范围
*/
void HW_SysTick_Delay_ms_all(uint64_t nms)
{
uint64_t ns = nms / 1000;
uint64_t _nms = nms % 1000;
for(uint64_t i = 0;i < ns;i++)
{
HW_SysTick_Delay_ms(1000);
}
HW_SysTick_Delay_ms(_nms);
}