流水灯如何实现?
思路不妨和熟悉的数字逻辑电路做比较,比如需要从右往左依次点亮,那么将clk(晶振50MHz)分频,使用计数器,不断计数到预定时间(比如1s),
然后将output用Led_Disp输出。而MCU中也是一样的逻辑,并且它已经设置好了一个定时器(24bit)(或者说计数器),自动地从0开始计数,到预定值清零,
我们所需的只是调用它,而不需要重新写一个计数器。
实现方法:
1.将SysTick的频率改为指定的1s,但是要知道,SysTick是给MCU很多资源使用的时钟,一般使用72MHz或者80MHz,如果为了点灯把它设置为1Hz,会极大
降低Mcu工作速度,得不偿失。
2.将SysTick的频率设置到一定值(很高的频率,但是同时是一些整数倍的关系),这样为人为写一个变量,每次都递增,(也就是一个计数器),到预定值之
后执行操作,也能实现功能。
SysTick 简介 SysTick—系统定时器是属于 CM3 内核中的一个外设,内嵌在 NVIC 中。系统定时器是一个 24bit的向下递减的计数器,计数器每计数一次的时间为 1/SYSCLK, 一般我们设置系统时钟 SYSCLK等于 72M。当重装载数值寄存器的值递减到 0 的时候,系统定时器就产生一次中断,以此循环往复。 因为 SysTick 是属于 CM3 内核的外设,所以所有基于 CM3 内核的单片机都具有这个系统定时器,使得软件在 CM3 单片机中可以很容易的移植。系统定时器 一般用于操作系统,用于产生时基,维持操作系统的心跳。(这是依照CM3内核介绍的systick,m4内核还没了解) 寄存器相关
操作方法:
具体的sys_configure可以直接使用cubemx生成,有空的话之后再读一下库函数。之后在startup.stm32g4xx.s中找到中断函数命名,再找到定义位置,
然后将原有中断函数注释,自己编写中断服务函数。
void SysTick_Handler(void) { Sys_Clkcount++; if(Sys_Clkcount==1000) { Sys_Clkcount=0; ucLed <<= 1; if(ucLed==0) ucLed=1; Led_Disp(ucLed); } }
这样就可以在main的循环体中,由于产生中断而进入中断服务函数,在ucLed的不断移位下,实现从0x01到ox80。
END