SysTick方式实现LED流水灯效果

systick_init()函数
systick_init 函数代码如下:
/*************************************************************************
* 函 数 名 : systick_init
* 函数功能 : systick 初始化,systick 的时钟固定为 ahb 时钟的 1/8
* 输 入 : sysclk:系统时钟频率
* 输 出 : 无
**************************************************************************/
void systick_init(u8 sysclk)
{
systick_clksourceconfig(systick_clksource_hclk_div8);
fac_us=sysclk/8; //sysclk的8分频 保存1us所需的计数次数
fac_ms=(u16)fac_us*1000; //每个 ms 需要的 systick 时钟数
}
systick_init 函数形参 sysclk 表示的系统时钟大小,默认配置我们使用的系统时钟是 72m,所以调用这个函数时,形参值即为 72。函数内部调用了一个库函数 systick_clksourceconfig,此函数用来对 systick 定时器时钟的选择,我们使用的systick定时器时钟是系统时钟的8 频 ,所以参数是systick_clksource_hclk_div8。如果使用系统时钟作为 systick 定时器时钟,那么参数即为 systick_clksource_hclk。这个函数在 misc.c 库文件内,如何查找我们前面介绍过方法。
下面的两条语句是用来求取systick定时器在1us时间内和1ms时间内的计数次数。
delay_us()函数
delay_us 函数代码如下:
/**********************************************************************
* 函 数 名 : delay_us
* 函数功能 : us 延时,
* 输 入 : nus:要延时的 us 数
注 意 :nus 的 值 , 不 要 大 于 798915us( 最 大 值 即
2^24/fac_us@fac_us=21)
* 输 出 : 无
**********************************************************************/
void delay_us(u32 nus)
{
u32 temp;
systick->load=nus*fac_us; //时间加载
systick->val=0x00; //清空计数器
systick->ctrl|=0x01 ; //开始倒数
do
{
temp=systick->ctrl;
}while((temp&0x01)&&!(temp&(1 systick->val =0x00; //清空计数器
}
①将需要延时多少 us 的计数值加载到 systick 的 load 寄存器中,fac_us值是延时 1us 所需的计数值。
②清空当前计数值寄存器 val。
③打开 systick 定时器,定时器开始向下递减计数。
④ctrl 寄存器的第 16 位是 systick 递减到 0 的标志位,如果递减到 0,此为置 1,通过读取该位来判断延时是否完成,从而退出 while 循环。
⑤关闭 systick 定时器。
⑥清空当前计数值寄存器 val。
delay_ms()函数
delay_ms 函数代码如下:
/*************************************************************
* 函 数 名 : delay_ms
* 函数功能 : ms 延时,
* 输 入 : nms:要延时的 ms 数
注意:nms 的值,systick->load 为 24 位寄存器,
不要大于 0xffffff*8*1000/sysclk
对 72m 条件下,nmsload=(u32)nms*fac_ms; // 时 间 加 载
(systick->load 为 24bit)
systick->val =0x00; //清空计数器
systick->ctrl|=0x01 ; //开始倒数
do
{
temp=systick->ctrl;
}while((temp&0x01)&&!(temp&(1 systick->val =0x00; //清空计数器
}
此函数功能与 delay_us 基本一样,只不过这里是延时 ms。要注意的是,systick 定 时 器 是 24 位 的 , 其 计 数 最 大 值 为 0xffffff , 时 间 为nms<=0xffffff*8*1000/sysclk,sysclk 是系统时钟为 72m,所以最大延时为1864ms。如果需要延时大于 1.864s,可以调用多个 delay_ms 函数即可。
主函数
在 main.c 文件中前面引入了工程中所需的头文件,可以打开工程查看,这里我们主要看下 main 函数,代码如下:
/**************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
***************************************************************/
int main()
{
systick_init(72);
led_init();
while(1)
{
led1=0;
led2=1;
delay_ms(500); //精确延时 500ms
led1=1;
led2=0;
delay_ms(500); //精确延时 500ms
}
}
主函数实现的功能比较简单,首先对 systick 定时器进行初始化配置,选择系统时钟 8 分频作为 systick 的时钟,然后初始化 led,这个初始化过程前面已经介绍过,大家也可以进入这个函数内查看。最后进入 while 循环语句,对 pc0和 pc1 管脚进行位操作,里面也调用了 delay_ms 延时函数,这时候的延时是非常精确的。
将工程程序编译下载到开发板内, 可以看到 led 模块的 2 个指示灯实现了流水灯效果。

将dv/dt从45V/ns降至5V/ns而不带来过长开/关延迟方案
三极管的工作原理
AI技术红利,究竟被谁吃掉?
三星Galaxy S21系列取消附送充电器耳机
从内核构架和制作工艺着手,了解工业互联网中低功耗设计
SysTick方式实现LED流水灯效果
华为nova3i评测 一款定位主流的高颜值新秀
基于Winsock控件的远程环境在线监测系统设计与实现
IRS2092集成电路制作D类功率放大器的注意事项,Notes of IRS2092 Class D Power Amplifier
中外科学家联合发布巨幅宇宙二维天图:10万亿像素 包含20亿天体
嵌入式系统的硬件架构说明
无线测温装置无线温度传感器提高监测系统的智能化和自动化水平
RJ45连接器的8个引脚功能(引脚定义图解)
射频/微波设计工具
让键盘侠禁言:10 月 1 日起,网上发帖、跟帖、发弹幕全都得实名认证
如何快速的完成器件参数检验工作
PNP与NPN晶体管的检测方法
关于以Cortex-A8内核为基础的嵌入式实验平台方案设计详解
啤酒机如何实现液体流量控制
NeoPixel的基本工作方式