0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

SysTick方式实现LED流水灯效果。

电子工程师 来源:lq 2019-02-11 15:35 次阅读

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<<16))); //等待时间到达

SysTick->CTRL&=~0x01; //关闭计数器

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 条件下,nms<=1864ms

* 输 出 : 无

**************************************************************/

void delay_ms(u16 nms)

{

u32 temp;

SysTick->LOAD=(u32)nms*fac_ms; // 时 间 加 载

(SysTick->LOAD 为 24bit)

SysTick->VAL =0x00; //清空计数器

SysTick->CTRL|=0x01 ; //开始倒数

do

{

temp=SysTick->CTRL;

}while((temp&0x01)&&!(temp&(1<<16))); //等待时间到达

SysTick->CTRL&=~0x01; //关闭计数器

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 个指示灯实现了流水灯效果。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • led
    led
    +关注

    关注

    242

    文章

    23280

    浏览量

    660967
  • 流水灯
    +关注

    关注

    21

    文章

    433

    浏览量

    59720
  • Systick
    +关注

    关注

    0

    文章

    62

    浏览量

    13096

原文标题:STM32实例-SysTick实现2个LED流水灯效果

文章出处:【微信号:c-stm32,微信公众号:STM32嵌入式开发】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    【正点原子STM32H7R3开发套件试用体验】流水灯

    【正点原子STM32H7R3开发套件试用体验】流水灯 本文介绍了使用 STM32CubeMX 辅助配置 GPIO 及晶振参数,实现流水灯的方法。 工程创建 1.打开 STM32CubeMX 软件
    发表于 12-28 18:51

    低成本单片机方案——触摸流水灯开关控制

    概述本方案旨在提供一种基于低成本单片机的触摸流水灯开关控制解决方案。该方案结合了单片机技术、电容式触摸传感技术和LED驱动技术,实现了通过触摸操作控制流水灯
    的头像 发表于 12-26 16:37 103次阅读
    低成本单片机方案——触摸<b class='flag-5'>流水灯</b>开关控制

    【RA-Eco-RA4E2-64PIN-V1.0开发板试用】RA4E2 实现流水灯操作

    本帖子主要使用RA4E2开发板来实现流水灯的交替电量操作,具体实验现象就是LE1亮LED2灭,LED1灭LED2亮。 好的,下面开始进行操作
    发表于 12-18 12:52

    【RA-Eco-RA4E2-64PIN-V1.0开发板试用】MDK+点灯+流水灯

    ” 文件,在 hal_entry 函数里面编写我们的代码。 直接运行,灯会常亮 流水灯实验,延迟200ms
    发表于 12-15 15:59

    基于51单片机的跑马灯/流水灯系统

    具体实现功能(1)9种LED流水灯模式通过按键进行切换,数码管显示流水灯模式。(2)通过加减按键可以切换每种LED
    的头像 发表于 10-22 14:12 234次阅读
    基于51单片机的跑马灯/<b class='flag-5'>流水灯</b>系统

    FPGA 实验一:流水灯模块

    实现流水灯效果。最初,每个步骤的停留时间是 1秒,然后步骤03按顺序执行便会产生流水效果。步骤4是用来切换模式,步骤5则是根据isTag的内
    发表于 06-10 09:38

    单片机POV LED流水灯制作

    电子发烧友网站提供《单片机POV LED流水灯制作.docx》资料免费下载
    发表于 05-28 14:34 3次下载

    【紫光同创盘古PGX-Nano教程】——(盘古PGX-Nano开发板/PG2L50H_MBG324第三章)键控流水灯实验例程

    灯、按键、拨码开关等。 二:实验目的 由PB0(即开发板S0位置)按键输入,切换LED0~LED7的输出效果。 三:实验原理 实现框架如下: (1)顶层
    发表于 04-29 16:06

    【紫光同创盘古PGX-MINI-4K教程】——(盘古PGX-MINI-4K开发板/PGC4KD-6ILPG144第二章)LED 流水灯实验例程

    载 jtag 调试接口, 预留两组 20PIN 扩展 IO、数码管、按键、led 灯等硬件资源,为用户提供基本的 开发环境。 二:实验目的掌握流水灯原理并实现流水灯 三:实验要求
    发表于 03-26 16:24

    利用systick计时器对LED等延时的时候,for循环中的ms和systick–&gt;LOAD的值为什么不是同一个?

    我们在利用systick计时器对LED等延时的时候,这里的for循环中的ms和我们的systick–>LOAD的值不是同一个,那当for循环结束以后,为啥我的systick–&a
    发表于 03-25 07:57

    如何实现SysTick中断的嵌套自身?

    当前 MSR XPSR,R7 MOV PC, R6 ;BXLR ENDP END 我想通过SysTick的嵌套自身,实现任务的抢占式调度,请问有人知道要怎么弄吗? 上面的汇编是我直接伪造返回现场让
    发表于 03-25 06:20

    【紫光同创盘古PGX-Lite 7K教程】——(盘古PGX-Lite 7K开发板/PGC7KD-6IMBG256第二章)​LED 流水灯实验例程

    流水灯原理并实现流水灯 三:实验要求流水灯:8 个 LED 以 0.5s 间隔接替闪烁 四:实验原理相比上一个
    发表于 03-20 15:07

    51单片机流水灯制作

    流水灯是学习51单片机的一个基本项目,是我们对单片机IO口输出认识的基本项目。当然学会了花样流水灯也很好玩。 下面就分享一种51单片机流水灯制作的方法。 一、流水灯原理图 二、相关知
    的头像 发表于 02-26 10:06 1632次阅读
    51单片机<b class='flag-5'>流水灯</b>制作

    SPICONTROLE 4个HC595移位寄存器设置流水灯时,在SPIIINTIGRATIONED化了的时候,控制的HC595 LED跳了起来如何解决?

    采用 SPICONTROLE 4个HC595移位寄存器,在设置流水灯的时候了,SPICONTROLLES正常,但是在SPIIINTIGRATIONED化了的时候,控制的HC595的LED跳了起来。请问该如何解决。例子比如:初始化时装的时候全部,但是还有几个灯一直是亮的。
    发表于 01-29 08:06

    【紫光同创国产FPGA教程】——(PGL22G第二章)键控流水灯实验例程

    1~ USER_LED8 的输出效果。 三:实验原理 实现框架如下: (1)顶层实现按键切换 LED
    发表于 01-05 11:22