怎么用定时器实现1s的延时Systick做一秒钟延时不占用CPU-STM32-F0/F1/F2专区

下次自动登录
现在的位置:
& 综合 & 正文
STM32中,systick具体延时时间计算
/****************************************************************************
STM32单片机SysTick系统滴答定时器实验程序
*****************************************************************************/
_SYSTICK_H
_SYSTICK_H
#include "SysTick.h"
SYSTICK_CSR
(*((volatile unsigned long *) 0xE000E010))//控制寄存器
SYSTICK_LOAD
(*((volatile unsigned long *) 0xE000E014))//重载寄存器
SYSTICK_VAL
(*((volatile unsigned long *) 0xE000E018))//当前值寄存器
SYSTICK_CALRB (*((volatile unsigned long *) 0xE000E01C)) //校准值寄存器
unsigned long SysTick_D//全局变量
//配置寄存器
void SysTick_InitStructReadCmd(void)
SYSTICK_VAL = 0;
//当前值寄存器清零
SYSTICK_LOAD = SystemCoreClock / 1000000; //重要部分就在这里
系统 / 100000
SYSTICK_CSR |= 0x06;
//先关闭SysTick使能用的时候在打开
//中断服务程序
void SysTick_Hangler(void)
SYSTICK_VAL = 0;
//当前值寄存器清零
if(SysTick_Delay != 0x00)//判断延时SysTick_Delay 是否等于0
SysTick_Delay--;//减到0结束
//延时函数
void Delay_10us(unsigned long Countlinef)
SYSTICK_CSR |= 0x07;
//启动SysTick使能
SysTick_Delay = C
//把延时变量赋值SysTick_Delay全局变量
while(SysTick_Delay != 0);
//判断延时时间是否到
SYSTICK_CSR |= 0x06;
//时间到关闭 SysTick使能用的时候在打开
int main(void)
SystemInit(); //注意这么是把系统时钟设初始化为 72M主频,这里是必须的
SysTick_InitStructReadCmd();
GPIOD-&BSRR = 0x;
Delay_10us(1000000) //实现1ms延时
GPIOD-&BRR
//====================================END=============================================//
好了我们开始讲解程序1us是怎么实现的,我们使用时钟源为APB时钟,APB系统频率陪配置为72MHZ
SYSTICK_LOAD = SystemCoreClock / 1000000; SysTick重载初值重要的地方就在这里
1:SystemCoreClock 这个是什么意思,跟踪库函数找到如下:
#ifdef SYSCLK_FREQ_HSE
uint32_t SystemCoreClock
= SYSCLK_FREQ_HSE;
#elif defined SYSCLK_FREQ_24MHz
uint32_t SystemCoreClock
= SYSCLK_FREQ_24MHz;
#elif defined SYSCLK_FREQ_36MHz
uint32_t SystemCoreClock
= SYSCLK_FREQ_36MHz;
#elif defined SYSCLK_FREQ_48MHz
uint32_t SystemCoreClock
= SYSCLK_FREQ_48MHz;
#elif defined SYSCLK_FREQ_56MHz
uint32_t SystemCoreClock
= SYSCLK_FREQ_56MHz;
#elif defined SYSCLK_FREQ_72MHz
uint32_t SystemCoreClock
= SYSCLK_FREQ_72MHz;
#else /*!& HSI Selected as System Clock source */
uint32_t SystemCoreClock
= HSI_VALUE;
/*这里不难看出,我们初始化SystemInit(); 是系统已经把SystemCoreClock配置成72M下面就不难理解了,
先看一下计算公式:T = TICKS * (1/f);
T : 为要计时的总时间。
TICKS :为SYSTICK_LOAD 的输入参数。
(1/f)为使用时钟源的时钟周期,f为时钟源的时钟频率
使用时钟源为AHB时钟, 频率被配置72M;
把SYSTICK_LOAD重载寄存器赋值为 SystemCoreClock / 1000000;呵呵呵大家
发现了什么,就是 / 1000000 = 72;大家都应该知道了72个时钟周期
中断一次,大家接着看(1/f)是时钟周期的时间。1/72M = 0.;
1us诞生了,0. = 1;1us哈哈哈大家明白了吧。
//野火资料出问题的地方 ticks=SystemFrequency / 10 000 =720,相当于: / 10000 ;这里少了一个0
结果等于 = 7200 不等于720看资料看的纠结哈哈哈。
这个程序折磨我1个星期,没有吃好睡好,搞明白后我就马上做上笔记那给大家分享。
//讲得简单易懂,当然精确定时还是要定时器的
以上转自:
【上篇】【下篇】STM32 利用systick 精确延时 nms
/*****************************************************************************
* File Name : _delay.h
* Author : shifu
* Version :
* Date : 09/20/2008
********************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __SYSTICK_DELAY_H
#define __SYSTICK_DELAY_H
/* Includes ------------------------------------------------------------------*/
#include "stm32f10x_systick.h"
/* SysTick clock countflag bit */
#define SysTick_CountFlag_Bit (u32)0x
/* SysTick flag */
#define Count_Not_Arrived (u32)0x0
#define Count_Arrived (u32)0x
/* CTRL TICKINT Mask */
#define CTRL_TICKINT_Enable ((u32)0x)
#define CTRL_TICKINT_Disable ((u32)0xFFFFFFFD)
/* Exported functions ------------------------------------------------------- */
void ST_Delay_Ms(u16 ms);
//***************************************************************************
// Function Name : systick_delay.c
// Deion : delay x ms 必须在AHB 设置以后使用
// Input : ms
// Output : None
// Return : None
//***************************************************************************
#include"systick_delay.h"
void ST_Delay_Ms(u16 ms)
u32 statusreg = Count_Not_A
//检查参数是否超过最大值0xffffff/,在AHB 72MHz时 最长时间0xffffff/9000
if(ms & 1864) ms = 1864;
//不产生异常中断请求
SysTick-&CTRL &= CTRL_TICKINT_D
//时钟选择 HCLK/8
SysTick-&CTRL &= SysTick_CLKSource_HCLK_Div8;
//装入计数值
SysTick-&LOAD = (u32)(ms * 9000);
//开始计数
SysTick-&CTRL |= SysTick_Counter_E
//检查标志位,等待延迟
while((statusreg & SysTick_CountFlag_Bit) == Count_Not_Arrived)
statusreg = SysTick-&CTRL;
//停止计数
SysTick-&CTRL &= SysTick_Counter_D
//清除计数
SysTick-&VAL = SysTick_Counter_C
原文链接:
责任编辑:
声明:该文观点仅代表作者本人,搜狐号系信息发布平台,搜狐仅提供信息存储空间服务。
今日搜狐热点stm32有问题,上知乎。知乎作为中文互联网最大的知识分享平台,以「知识连接一切」为愿景,致力于构建一个人人都可以便捷接入的知识分享网络,让人们便捷地与世界分享知识、经验和见解,发现更大的世界。查看: 5436|回复: 6
(求助!!)3.5库的时钟初始化与SYSTICK实现延时的问题
主题帖子精华
初级会员, 积分 68, 距离下一级还需 132 积分
在线时间8 小时
&3.5库的时钟初始化与SYSTICK实现延时的问题
新手求助。。。
使用3.5的库,根据描述。。库中默认为外部8mhz。我也就没设置。。然后进行systick初始化。。和延时函数定义。。但下到板子里。。定时不准。。已开始以为是延时函数的问题,后来把systick的初始化包括延时函数都放到原子哥历程中延时准确。。说明延时这块没问题。。
是不是默认的时钟初始化有问题啊?谁能帮我说说。。库中默认的始终初始化直接用有什么问题吗?请高手帮我讲讲。。时钟的初始化。。都纠结我好多天了。。。
这我的程序,写的应该是延时一秒的,可实际却3秒左右。。。。大家帮忙看看。。到底咋回事啊。。。。。
#include "stm32f10x.h"
&// 声明结构体
&GPIO_InitTypeDef GPIO_InitS //此句话定义了一个名字叫GPIO_InitStructure的结构体
/*void SysTick_Configuration(void)
&SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);//设置时钟源为HCLK
&//2.0库设置方法。。。
//void us_delay(u32 n)
// SysTick_SetReload(72000*n);
// SysTick_CounterCmd(SysTick_Counter_Clear);
// SysTick_CounterCmd(SysTick_Counter_Enable);
//& flag=SysTick_GetFlagStatus(SysTick_FLAG_COUNT);
// }while(flag!=1);
// SysTick_CounterCmd(SysTick_Counter_Disable);
void delay_init()
&SysTick-&CTRL&=0
& ms=(u16)us*1000;
void delay_us(u32 n)
&SysTick-&LOAD=n*
&SysTick-&VAL=0x00;
&SysTick-&CTRL=0x01;
// {temp=(SysTick-&CTRL)&&16;
// }while(temp!=1);
&&temp=SysTick-&CTRL;
&while(temp&0x01&&!(temp&(1&&16)));//等待时间到达
&SysTick-&CTRL=0x00;
&SysTick-&VAL=0x00;
void delay_ms(u16 n)
&SysTick-&LOAD=(u32)n*
&SysTick-&VAL=0x00;
&SysTick-&CTRL=0x01;
// {temp=(SysTick-&CTRL)&&16;
// }while(temp!=1);
&&temp=SysTick-&CTRL;
&while(temp&0x01&&!(temp&(1&&16)));//等待时间到达
&SysTick-&CTRL=0x00;
&SysTick-&VAL=0x00;
&void GPIO_Configuration(void)
& GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 ;&&&& //第二个引脚
& GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; && //推挽输出
& GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
& &GPIO_Init(GPIOD,&GPIO_InitStructure);
int main(void)
& &//使能线上时钟,
& RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);//使能IO口A和D
& GPIO_Configuration ();//GPIO初始化
& delay_init(72);
& while (1)
&& GPIO_ResetBits(GPIOD,GPIO_Pin_2);& //D2口置位即输出高电平
&& delay_ms(1000);
&& GPIO_SetBits (GPIOD,GPIO_Pin_2);
&&& delay_ms(1000);
主题帖子精华
初级会员, 积分 86, 距离下一级还需 114 积分
在线时间2 小时
还没用过库,以前操作寄存器的时候,因为一点点操作失误,导致延时是本意的9倍
主题帖子精华
初级会员, 积分 68, 距离下一级还需 132 积分
在线时间8 小时
回复【2楼】wcjaglzf:
---------------------------------
我刚开始学。。一开始也不想用库。。。想先自己造作寄存器。。。觉的这样学得踏实。。。可是。。。刚开始。。。始终初始化就给我难住了。。有个RCCdeinit。。就在造=操作RCC寄存器是要复位默认值那个函数。。。我不知道该怎么写,看了原子哥的程序。。我也不知道为什么要那么写。。查了好久。。也没头绪。。。后来决定。。用库了,用库。。又发现个问题,2.0+的3.0+的。。不一样。。纠结了好久,决定用3.5.。。刚写完点亮LED的程序,本来挺高兴的。打算继续。。可这延时给我郁闷找了。。。哎....谁来帮帮我啊!&&T_T
主题帖子精华
金钱128996
在线时间1151 小时
回复【楼主位】wx:
---------------------------------
默认时钟为8M,如果不PLL,那就只有8M的频率,你的delay_init应该为delay_init(8);才对
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺:
主题帖子精华
初级会员, 积分 68, 距离下一级还需 132 积分
在线时间8 小时
回复【4楼】正点原子:
---------------------------------
指的是默认外部8M,然后库中给设置为倍频到72M的。。。我也试了你说的。。改成init(8)。。但也不是一秒。。。说明不是8M...麻烦您再帮我想想。。谢谢了。。是不是AHB设置的问题啊。。。新手。。看库有点吃力。。
主题帖子精华
金钱128996
在线时间1151 小时
回复【5楼】wx:
---------------------------------
那你参考一下我们开发板例程里面的库函数版本的实现吧。
里面也有延时初始化。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺:
主题帖子精华
初级会员, 积分 68, 距离下一级还需 132 积分
在线时间8 小时
回复【6楼】正点原子:
---------------------------------
结个贴!问题解决了。。不是程序的问题。。。。是keil设置C++选项的时候。。宏错了。。。应该是STM32F10X_MD。。。。对于同样适用3.5库的朋友们一定要注意啊!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!&同样谢谢原子哥的解答!!很感谢您能不厌其烦的为我们新手说明!
Powered by【STM32F411 Nucleo试用体验】+systick定时器 - STM32/STM8技术论坛 -
中国电子技术论坛 -
最好最受欢迎电子论坛!
后使用快捷导航没有帐号?
【STM32F411 Nucleo试用体验】+systick定时器
18:11:06  
& &Cortex序列内核系统都提供1个24位SysTick定时器、可以作为普通的定时器使用,在有RTOS的系统,一般都用它来做TICK时钟。SysTick定时器被捆绑在NVIC中,用于产生SYSTICK异常。Systick 部分内容属于NVIC控制部分,一共有4个寄存器,名称和地址分别是:STK_CSR,& && &&&0xE000E010&&--&&控制寄存器
STK_LOAD,& &&&0xE000E014&&--&&重载寄存器
STK_VAL,& && &&&0xE000E018&&--&&当前值寄存器
STK_CALRB,& &0xE000E01C&&--& &校准值寄存器1,STK_CSR寄存器
图片1.png (77.23 KB, 下载次数: 0)
18:10 上传
第0位:ENABLE,Systick 使能位 (0:关闭Systick功能;1:开启Systick功能)
第1位:TICKINT,Systick 中断使能位 (0:关闭Systick中断;1:开启Systick中断)
第2位:CLKSOURCE,Systick时钟源选择 (0:使用HCLK/8 作为Systick时钟;1:使用HCLK作为Systick时钟)
第3位:COUNTFLAG,Systick计数比较标志,如果在上次读取本寄存器后,SysTick 已经数到了0,则该位为1。如果读取该位,该位将自动清零2,STK_LOAD&&重载寄存器:
图片2.png (63.38 KB, 下载次数: 0)
18:10 上传
Systick是一个递减的定时器,当定时器递减至0时,重载寄存器中的值就会被重装载,继续开始递减。STK_LOAD&&重载寄存器是个24位的寄存器最大计数0xFFFFFF。3,STK_VAL当前值寄存器:
图片3.png (64.48 KB, 下载次数: 0)
18:10 上传
也是个24位的寄存器,读取时返回当前倒计数的值,写它则使之清零,同时还会清除在SysTick 控制及状态寄存器中的COUNTFLAG 标志。4,STK_CALRB&&校准值寄存器:
图片4.png (94.67 KB, 下载次数: 0)
18:10 上传
这个寄存器,一般不使用,如果需要深入的研究,可以去查阅资料。上述资料在网上查阅的,放在这里跟大家分享。下面我使用它来做普通的定时器。初始化为1MS定时器中断。通过LED周期性变化来验证结果。1,LED初始化参照前面章节。2,SysTick初始化:
图片5.png (13.07 KB, 下载次数: 0)
18:10 上传
HAL_NVIC_SetPriority这个函数是修改中断优先级的,一般默认就可以。
图片6.png (18.13 KB, 下载次数: 0)
18:10 上传
这里就初始化了SysTick时钟,使能了中断。
图片7.png (9.5 KB, 下载次数: 0)
18:10 上传
图片8.png (8.35 KB, 下载次数: 0)
18:10 上传
这个是中断处理函数。初始化完成,到验证的时候了。通过HAL_GetTick()函数读取uwTick计数值,实现led闪烁。
图片9.png (1.26 KB, 下载次数: 0)
18:10 上传
图片10.png (13.06 KB, 下载次数: 0)
18:10 上传
编译下载,结果得到验证。
工程师职场
Powered by
供应链服务
版权所有 (C) 深圳华强聚丰电子科技有限公司}

我要回帖

更多关于 lua实现延时 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信