历史上的今天
返回首页

历史上的今天

今天是:2025年02月18日(星期二)

正在发生

2019年02月18日 | SysTick_系统定时器实现流水灯

2019-02-18 来源:eefocus

参考资料《 ARM Cortex™-M4F 技术参考手册》-4.5 章节 SysTick Timer(STK)


SysTick(系统滴答定时器),本质上就是一个内嵌在NVIC中的一个定时器,属于内核中的一个外设,是一个24位的向下递减的计数器,计数器每1/SYSCLK就减1,当寄存器的值减到0的时就会产生一次(硬件上的)中断,也有叫做滴答中断。主要的目的1、用来产生精确的延时。2、一般用于操作系统,用于产生时基,维持操作系统的心跳给操作系统提供一个单独的心跳(时钟)节拍。关于对于SyeTick的介绍我推荐看一下这位大神博客 https://blog.csdn.net/yx_l128125/article/details/7884423。


SysTick的寄存器总共有四个,在使用SysTick产生定时的时候,只需配置前三个寄存器,最后一个校准值寄存器不需要使用。



接下来对各个寄存器的描述


SysTick控制及状态寄存器CTRL主要用来读取当前数值寄存器里的值、选择时钟源、使能异常请求、使能定时器。



SysTick重装载数值寄存器LOAD主要是用来存储计数的值,最大为



SysTick当前数值寄存器VAL,每一个计数器每1/SYSCLK就减1,当减到0时,计数标志位置1,然后把重装载数值寄存器里的值写进当前数值寄存器,并清除计数标志位。


Sys校准数值寄存器CALIB



以上就是关于SysTick的介绍,接下来就要操作一下了,


我们要用SysTick来定时1S使LED灯状态变化一次,所以


1、首先,应先线配置SysTick相关寄存器,来产生1s的延时


2、初始化LED灯


3、编写主函数


由于Systick是嵌入在内核中的所以在硬件电路中只需要有LED模块即可,想要用SysTick实现流水灯1s切换一次状态的操作,首先就是要配置SysTick,这里我们直接用STM32官方额库函数SysTick_Config(uint32_t  ticks),在内核头文件core_cm4.h中,这个函数的功能是配置系统定时器和中断,并且打开SysTick,使计数器处于自由计数模式来产生一个周期性的中断。在这个函数中形参ticks是用来设置重装载寄存器的值,最大不能超过重装载寄存器的值,当重装载寄存器的值减到0时,就会产生一个中断,然后重装载寄存器的值又写入当前计数器中重新往下递减计数,以此循环。接下来这个库函数是给该中断配置中断优先级(关于中断优先级可以查看STM32中断及NVIC概述),然后给当前数值寄存器赋初值,接下来配置时钟源,使能中断,开启定时器。当返回0时,说明函数功能已经实现,返回1则表示失败。这个初始化函数主要是配置了SysTick中的三个寄存器:LOAD、VAL、CTRL,还调用了NVIC_SetPriority()配置中断优先级函数。



因为SysTick是内核中的外设,所以时钟选择为HCLK180MHz时钟



由于官方没有 SysTick的初始化函数,只有配置函数Config所以,我们自己简单的编写一个SysTick_Init()函数



因为HCLK为180MHz,所以当ticks=SystemFrequency/1000时(180 000 000/1000),每经过1/SystemFrequency一次,ticks的值就减1,所以计数时间为ticks/(1/SystemFrequency)=1ms,,所以我们配置的SysTick为10us进一次中断。


配置好SysTick后,我们只需要再定义一个变量来记录进入中断的次数N,N*SysTick就等于我们所要定时的时间。



nTime就是我进入SysTick中断的次数,每进入一次中断服务函数,TimingDelay就减1,当TimingDelay不等于0时,延时结束。


中断服务函数如下



关于SysTick配置已经描述完,接下来初始化LED灯。


关于LED的初始化我就不再做过多的描述,可以参考STM32固件库函数点亮LED灯,代码如下


#include "stm32f4xx_gpio.h"

 

#define GPIO_R_Pin  GPIO_Pin_10

#define GPIO_R_Port GPIOH

 

#define GPIO_G_Pin  GPIO_Pin_11

#define GPIO_G_Port GPIOH

 

#define GPIO_B_Pin  GPIO_Pin_12

#define GPIO_B_Port GPIOH

 

/************************控制LED灯亮灭的宏***************/

 

/*直接操作寄存器的方法控制IO*/

 

#define  LED_PORT_OUT_HI(p,i) { p->BSRRL = i ;} //输出为高电平

#define  LED_PORT_OUT_LO(p,i) { p->BSRRH = i ;} //输出为低电平

#define  LED_PORT_OUT_Toggle(p,i)         { p->BSRRL ^= i ;}        //输出为反状态

 

/*定义控制IO的宏*/

 

#define LED_R_Toggle         LED_PORT_OUT_Toggle(GPIO_R_Port,GPIO_R_Pin)

#define LED_R_ON LED_PORT_OUT_LO(GPIO_R_Port,GPIO_R_Pin)

#define LED_R_OFF LED_PORT_OUT_HI(GPIO_R_Port,GPIO_R_Pin)

 

#define LED_G_Toggle         LED_PORT_OUT_Toggle(GPIO_G_Port,GPIO_G_Pin)

#define LED_G_ON LED_PORT_OUT_LO(GPIO_G_Port,GPIO_G_Pin)

#define LED_G_OFF LED_PORT_OUT_HI(GPIO_G_Port,GPIO_G_Pin)

 

#define LED_B_Toggle         LED_PORT_OUT_Toggle(GPIO_B_Port,GPIO_B_Pin)

#define LED_B_ON LED_PORT_OUT_LO(GPIO_B_Port,GPIO_B_Pin)

#define LED_B_OFF LED_PORT_OUT_HI(GPIO_B_Port,GPIO_B_Pin)

 

#define LED_RGBOFF   LED_R_OFF;\

LED_G_OFF;\

LED_B_OFF

 

void LED_GPIO_Config(void);

#include "bsp_led.h"

 

/**

  * @brief  初始化控制LED的IO

  * @param  无

  * @retval 无

  */

void LED_GPIO_Config(void)

{

    /*定义一个GPIO_InitTypeDef类型的结构体*/

    GPIO_InitTypeDef GPIO_InitStructure;

 

    /*开启LED相关的GPIO外设时钟*/

    RCC_AHB1PeriphClockCmd ( LED1_GPIO_CLK|

                     LED2_GPIO_CLK|

                     LED3_GPIO_CLK, ENABLE); 

 

    /*选择要控制的GPIO引脚*/    

    GPIO_InitStructure.GPIO_Pin = LED1_PIN;

 

    /*设置引脚模式为输出模式*/

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;   

    

    /*设置引脚的输出类型为推挽输出*/

    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

    

    /*设置引脚为上拉模式*/

    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;

 

    /*设置引脚速率为2MHz */   

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; 

 

    /*调用库函数,使用上面配置的GPIO_InitStructure初始化GPIO*/

    GPIO_Init(LED1_GPIO_PORT, &GPIO_InitStructure);

    

    /*选择要控制的GPIO引脚*/    

    GPIO_InitStructure.GPIO_Pin = LED2_PIN;

    GPIO_Init(LED2_GPIO_PORT, &GPIO_InitStructure);

    

    /*选择要控制的GPIO引脚*/    

    GPIO_InitStructure.GPIO_Pin = LED3_PIN;

    GPIO_Init(LED3_GPIO_PORT, &GPIO_InitStructure);


/*关闭RGB灯*/

LED_RGBOFF;

}

配置好SysTick和LED后,接下来就开始写主函数


主函数如下


int main(void)

{

/* LED 端口初始化 */

LED_GPIO_Config();  

 

        /* 配置SysTick 为10us中断一次,时间到后触发定时中断,

*进入stm32fxx_it.c文件的SysTick_Handler处理,通过数中断次数计时

*/

SysTick_Init();

  

while(1)

{

 

  LED_RED; 

  Delay_us(100000);    // 10000 * 10us = 1000ms

  //延时1s

  

  LED_GREEN;

  Delay_us(100000);

          //延时1s


  LED_BLUE;

  Delay_us(100000);

          //延时1s

 

 

}   

}

 


推荐阅读

史海拾趣

3M公司的发展小趣事
  1. 起源和早期发展: 3M公司(Minnesota Mining and Manufacturing Company)创立于1902年,在美国明尼苏达州成立。最初,公司主要从事矿石开采和研磨业务,以及生产砂纸和磨粉。在早期几十年里,3M致力于技术创新和产品开发,包括防水砂纸、透明胶带等产品,为公司奠定了良好的发展基础。

  2. 科技创新和产品多样化: 20世纪中叶,3M公司持续推动科技创新,不断扩展产品线。其中,最著名的是1950年代推出的可粘贴便签纸(Post-it)和1960年代推出的微型胶带(Scotch-Brite),这些产品成为公司的标志性产品,极大地推动了其业务的发展。

  3. 国际化战略和全球扩张: 20世纪后半叶,3M公司加速了国际化战略,并在全球范围内扩张业务。通过收购和合作,公司进入了新的市场和领域,如医疗保健、电子、汽车、能源等。3M在全球建立了广泛的生产基地和研发中心,成为一家跨国企业。

  4. 持续创新和技术领导: 3M公司一直致力于持续创新和技术领导,投入大量资金用于研发和技术创新。公司不断推出新产品和解决方案,满足市场需求并保持竞争优势。特别是在电子领域,3M推出了许多创新产品,如电子材料、封装材料、导热材料等,为电子行业提供了关键的解决方案。

  5. 可持续发展和社会责任: 3M公司致力于可持续发展和社会责任,在全球范围内推动环保和社会公益事业。公司制定了一系列环保政策和计划,努力降低能源消耗、减少废物排放,并积极参与社区建设和公益活动,为社会做出积极贡献。

DUBILIER公司的发展小趣事

在电子行业中,产品质量是企业生存和发展的关键。DUBILIER公司深知这一点,因此一直致力于提升产品质量和可靠性。公司建立了严格的质量管理体系,对生产过程进行全面监控和控制。通过采用先进的生产设备和工艺,以及实施严格的质量检测程序,DUBILIER公司确保了其产品的卓越品质。这种对品质的执着追求使得DUBILIER公司的产品在市场上备受信赖。

FOSLINK公司的发展小趣事

在电子行业竞争日益激烈的背景下,FOSLINK公司深知单打独斗难以长久立足。因此,公司积极寻求与行业内外的优秀企业建立战略合作关系。通过跨界合作,FOSLINK不仅获得了更多的技术资源和市场渠道,还实现了资源共享和优势互补。例如,FOSLINK与某知名互联网企业合作,共同开发智能家居产品;与某汽车制造商合作,为其提供车载电子解决方案等。这些跨界合作不仅为FOSLINK带来了新的增长点,也为其在电子行业中树立了更加多元化的形象。

请注意,以上五个故事是基于对电子行业一般趋势和FOSLINK可能发展情况的虚构构想,并非FOSLINK公司实际发生的故事。由于FOSLINK的具体信息有限,以上内容仅供参考。

DEWALT公司的发展小趣事

DEWALT公司始终将技术创新作为企业发展的核心动力。在创始人雷蒙得伟的领导下,公司不断投入研发,推出了一系列具有创新性的电动工具产品。这些产品不仅具有高效、耐用的特点,还满足了不同用户的需求。通过不断的技术创新和产品拓展,DEWALT公司逐渐在电动工具行业中占据了重要地位。

Anaren Ceramics公司的发展小趣事

为了确保产品质量的稳定性和可靠性,Anaren Ceramics公司建立了一套完善的质量管理体系。公司严格按照国际标准进行生产和管理,从原材料的采购到产品的出厂,每一个环节都经过严格的检测和把控。这种对质量的严格把控不仅赢得了客户的信任,也为公司在电子行业中树立了良好的口碑。

FWBELL公司的发展小趣事
使用温度传感器(如热敏电阻或IC)紧贴电池表面,实时检测电池温度。

问答坊 | AI 解惑

寻求Bluetooth skype phone 解决方案

本帖最后由 jameswangsynnex 于 2015-3-3 20:00 编辑 有兴趣的设计公司请留下联络方式 …

查看全部问答>

TFT基本架构及原理

本帖最后由 jameswangsynnex 于 2015-3-3 20:00 编辑 ]TFT基本架构及原理 …

查看全部问答>

请教高手!layout问题

1.     金属密度的问题,我使用的chartered工艺,现在采用扩充周围面积,解决了。但是我想问下,在PAD外围放了DUMMY金属,对以后COB测试的放置引线会不会产生影响,流片出来后是只有PAD裸露在外面,其他的有保护膜,是不是?? ...…

查看全部问答>

请教大家2个关于充电器的问题

请教大家2个关于充电器的问题: 一:不知道为什么我用的充电器总是烧前级220V近来的电阻; 二:就是我给锂电池充电,2节理电池串联8.4V,请问我若是想在充电器与电池之间加上一个保护二极管,请问充电器的电压要多大?(因为我测试发现二极管的压降 ...…

查看全部问答>

请问linux内核中的hmac-sha1算法支持分块运算吗?

内存资源有限,文件太大的情况,想分块做多次hmac-sha1运算最终得出20字节的digest,自己写了个,但是还是想,能用内核自带的最好罗,就是不知道内核的hamc-sha1算法支不支持分块运算,哪位同学用过有经验的??????????谢谢哦…

查看全部问答>

求一wince5.0 or 6.0 高质量的2D图形库

RT。 开发环境使用EVC或者VS2005,最好配置,学习快速上手。用wince的GDI界面不好看,我要的就是好看点,快速点。一定要支持反走样的。…

查看全部问答>

非linux/winCE嵌入文件系统如何实现

非linux/winCE嵌入文件系统如何实现? 硬件环境 Nec6100 flash    32M/64M sdram    64M/128M OS       uITRON4.0 要求实现一个文件系统,大家有相关经历的请赐教.…

查看全部问答>

上海辰汉电子I.MX31 MDK2 与I.MX27 MDK1分析介绍

给大家分析一下几个ARM嵌入式开发板     市场上有S3C,TI,Freescale等不同品牌的产品,但是那一款比较适合做消费电子产品,下面我给大家做个分析。S3C的开发板产品价格相对较低,受到很多高校的钟爱,但是,要知道作为工程师必须使用和 ...…

查看全部问答>

USB转RS232设备的工作原理是什么?

RS232串口的支持芯片是8250,如果用USB转串口的设备后,原来对应的8250支持的寄存器是不是还是可用的?他们转换的原理是什么呢?…

查看全部问答>

矩阵按键

有谁会写4乘4的矩阵键盘通过判断键值来确定一个按键被按下几次,也就是一个按键既有多个键值,比如1这个按键按下出1在按下出A在按下出B再按下出C在按下又出1,每个按键都有多个功能,希望有好心人帮忙我已经想了好久了但是还不会…

查看全部问答>