本帖最后由 ypp庸 于 2020-3-14 19:25 编辑
菜鸟上路,看了原子哥21讲的视频来输出一下关于SysTick的用法
一、概述
SysTick定时器是系统滴答定时器,一个24位的倒计时计数定时器; 倒数到0时,将从RELOAD寄存器中自动重装载定时初值 只要不清除对应的使能位,定时器就永不停息,即使是在睡眠模式下也工作。
二、相关寄存器 SysTick有4个寄存器。CTRL、LOAD、VAL、CALIB; (CALIB未用到) 2.1 Systick -> CTRL 状态和控制寄存器
位16: 当计数器倒数到0时,该位会自动置1。 【注:可用来判断计数器完成】 位2:时钟源选择位 0=外部时钟源 1=内部时钟源 位1:请求中断位 0=SysTick倒数到0时无动作 1=倒数到0时,产尘SysTick异常请求 位0:使能位
2.2 SysTick ->LOAD 重装载数值寄存器
2.3 SysTick ->VAL 当前值寄存器
三、频率选择 3.1、时钟的选择 本延时函数采用的是外部时钟源。所以该是时钟频率是系统时钟频率的八分之一,即72MHz / 8 =9 Mhz 3.2、如何延时1us 时钟频率为9Mhz,即1秒计数9M次 即一次计数用了 1/9000000 s = 1/9000 ms = 1/9us 一次计数用了1/9us 所以1us 计数了9次 3.3、如何延时1ms 计数9000 即为延时1ms
四、编程思路 4.1 Delay初始化 选择时钟源 关闭定时器 4.2 延时函数 设置重装载值 计数器清0 使能SysTick 等待计数完毕 关闭定时器 计数器清0
五、示例代码 5.1 寄存器版 #include "delay.h" #define val_us 9 #defne val_ms 9000 Delay_Init(void) { SysTick -> CTRL &= ~(1<<2) ; //选择时钟源 把第二位设置为0 SysTick -> ENABLE &= ~(1<<0); //关闭定时器 }
Delay_us(u32 num) { u32 temp; SysTick -> LOAD = num * val_us ; //设置重装载值 SysTick -> VAL = 0 ; //VAL清零 SysTick -> CTRL |= (1<<0); //打开使能 第0位 设置为1 do{ temp =SysTick -> CTRL; }while( (temp & 0x01) &&! (temp & (1<<16)) ); //等待计数完成 判断第16位是否为1 SysTick -> CTRL &= &= ~(1<<0); // 关闭使能 第第0位 设置为0 SysTick -> VAL = 0; }
Delay_ms(u16 num) { u32 temp; SysTick -> LOAD = num * val_ms ; //设置重装载值 SysTick -> VAL = 0 ; //VAL清零 SysTick -> CTRL |= (1<<0); //打开使能 第第0位 设置为1 do{ temp =SysTick -> CTRL; }while( (temp & 0x01) &&! (temp & (1<<16)) ); //等待计数完成 判断第16位是否为1 SysTick -> CTRL &= &= ~(1<<0); // 关闭使能 第第0位 设置为0 SysTick -> VAL = 0; }
5.2 库函数版 #include "delay.h" #define val_us 9 #defne val_ms 9000 Delay_Init(void) { SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; }
Delay_us(u32 num) { u32 temp; SysTick->LOAD = val_us * num,; //设置重装载值 SysTick->VAL = 0x00; //清空计数器 SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; //使能systick 开始倒计时 do{ temp = SysTick->CTRL; }while( (temp & 0x01) &&! (temp & (1<<16))); //等待计时完毕 SysTick->VAL &= 0x00; SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; }
Delay_ms(u16 num) { u32 temp; SysTick->LOAD = val_ms * num,; //设置重装载值 SysTick->VAL = 0x00; //清空计数器 SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; //使能systick 开始倒计时 do{ temp = SysTick->CTRL; }while( (temp & 0x01) &&! (temp & (1<<16))); //等待计时完毕 SysTick->VAL &= 0x00; SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; }
}
|