历史上的今天
返回首页

历史上的今天

今天是:2025年04月23日(星期三)

正在发生

2018年04月23日 | STM32精确延时(非中断,非ST库函数)

2018-04-23 来源:eefocus

     前天学了下stm的systick,发现还满好用的,可以用来精确定时.以前在用CVAVR的时候发现里面的delay.h非常好用.于是,利用stm32的SysTick做了个精确的延时头函数.


     SysTick的配置在void delay_init(u8 SYSCLK);里面输入的参数SYSCLK是你配置的系统时钟,比如72M,我就调用delay_init(72);然后就完成了对SysTick的初始化设置.在后面调用delay_ms(u32 Nms);delay_us(u32 Nus);就可以得到很准确的延时.


注意:


1,delay_us(u32 Nus);在Nus值很小的时候,误差比较大,我仿真的时候delay_us(1);实际上得到的是延时了1.5us左右.理论上Nus的值越大,越准确.


2,delay_ms(u32 Nms);的参数不能太大!更具你系统时钟来确定.72M的时候Nms的最大值是1864.在其他晶振(<72M)条件下,该值会变大.计算方法:Nms<=0xffffff*8/SYSCLK.


    在包括了这个头函数之后可以得到很准确的延时,也不会产生中断,其他中断可以打断delay_us,delay_ms的执行.


#ifndef __DELAY_H

#define __DELAY_H       

//使用SysTick的普通计数模式对延迟进行管理

//包括delay_us,delay_ms  

//正点原子@SCUT

//2008/12/13  

static u8  fac_us=0;//us延时倍乘数

static u16 fac_ms=0;//ms延时倍乘数

//初始化延迟函数

void delay_init(u8 SYSCLK)

{

SysTick->CTRL&=0xfffffffb;//选择内部时钟 HCLK/8

fac_us=SYSCLK/8;      

fac_ms=(u16)fac_us*1000;

}            

//延时Nms

//注意Nms的范围

//Nms<=0xffffff*8/SYSCLK

//对72M条件下,Nms<=1864 

void delay_ms(u16 nms)

{    

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

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

while(!(SysTick->CTRL&(1<<16)));   //等待时间到达 

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

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

}   

//延时us           

void delay_us(u32 Nus)

SysTick->LOAD=Nus*fac_us;       //时间加载      

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

while(!(SysTick->CTRL&(1<<16)));//等待时间到达 

SysTick->CTRL=0X00000000;       //关闭计数器

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

}  

#endif


另外的一种方法 :


/*---------------------------------

延时模块函数

说明:只需在工程中加入delay.c和delay.h

文件,即可用 Delayms(__IO uint32_t nTime);

Delayus(__IO uint32_t nTime)

-----------------------------------*/

#ifndef __DELAY_H

#define __DELAY_H

#include "stm32f10x.h"

/*--------------------------------- 

描 述:参数1即为1ms,1000即为1s;只有几

us的误差;

-----------------------------------*/

extern void Delayms(__IO uint32_t nTime);


/*---------------------------------

描 述:参数1即为1us,1000即为1ms;只有几

us的误差;

-----------------------------------*/

extern void Delayus(__IO uint32_t nTime);

/*---------------------------------

函数名:延时调整形式的delaynus函数, 

描 述:参数1即为1us,1000即为1ms;

-----------------------------------*/

extern void delay_nus(unsigned long n);

/*---------------------------------

函数名:延时调整形式的delaynms函数, 

描 述:参数1即为1ms,1000即为1s;

-----------------------------------*/

extern void delay_nms(unsigned long n);

#endif


C 函数


/*---------------------------------

延时模块函数

说明:只需在工程中加入delay.c和delay.h

文件,即可用 Delayms(__IO uint32_t nTime);

Delayus(__IO uint32_t nTime)

-----------------------------------*/

#include"delay.h"

static __IO uint32_t TimingDelay;

/* Private function prototypes -----------------------------------------------*/

/*---------------------------------

函数名:ms延时函数 

描 述:参数1即为1ms,1000即为1s;只有几

us的误差;

-----------------------------------*/

void Delayms(__IO uint32_t nTime) 

while(SysTick_Config(SystemCoreClock/1000)); 

TimingDelay = nTime;

while(TimingDelay != 0);

SysTick->CTRL=0x00; //关闭计数器 

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

}

/*---------------------------------

函数名:us延时函数 

描 述:参数1即为1us,1000即为1ms;只有几

us的误差;

-----------------------------------*/

void Delayus(__IO uint32_t nTime)

while(SysTick_Config(SystemCoreClock/1000000)); 

TimingDelay = nTime;

while(TimingDelay != 0);

SysTick->CTRL=0x00; //关闭计数器 

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

}

/*---------------------------------

函数名:延时辅助函数 

描 述: 

-----------------------------------*/

void TimingDelay_Decrement(void)

{

if (TimingDelay != 0x00)

TimingDelay--;

}

}

/*---------------------------------

函数名:systick的中断函数 

描 述:参数1即为1us,1000即为1ms;只有几

us的误差;

-----------------------------------*/

void SysTick_Handler(void)

{

TimingDelay_Decrement();

}

/*---------------------------------

函数名:延时调整形式的delaynus函数, 

描 述:参数1即为1us,1000即为1ms;

-----------------------------------*/

void delay_nus(unsigned long n)

{

unsigned long j;

while(n--)

{

j=12;

while(j--);

}

}

/*---------------------------------

函数名:延时调整形式的delaynms函数, 

描 述:参数1即为1ms,1000即为1s;

-----------------------------------*/

void delay_nms(unsigned long n)

{

while(n--)

delay_nus(1030);

}


推荐阅读

史海拾趣

ELEKTRO-PLAST NASIELSK公司的发展小趣事

近年来,随着数字化技术的快速发展和应用普及,电子行业也迎来了数字化转型的浪潮。ELEKTRO-PLAST NASIELSK公司紧跟时代步伐,积极推进数字化转型工作。公司引入先进的数字化设备和系统提升生产效率和质量水平;同时加强信息化建设,实现数据共享和协同办公;此外还通过电子商务平台拓展销售渠道和服务范围。数字化转型不仅提升了公司的竞争力还为客户提供了更加便捷高效的服务体验。

Electric Imp Inc.公司的发展小趣事

随着第一款产品的成功,Electric Imp Inc.公司开始积极拓展市场。公司与多家知名厂商建立了合作关系,将物联网设备管理平台应用于智能家居、工业自动化、智慧城市等领域。同时,公司还加强了与高校、科研机构的合作,共同研发新技术、新产品。这些努力使得公司在物联网领域的影响力逐渐扩大。

Cretex Companies Inc公司的发展小趣事

随着公司实力的增强,Cretex开始将目光投向国际市场。他们积极参与国际电子展会,与全球各地的合作伙伴建立联系。通过引进国外先进的技术和管理经验,Cretex的产品质量和服务水平得到了进一步提升。同时,公司还针对不同国家和地区的市场需求,推出定制化的电子产品,赢得了更多客户的青睐。

ACL staticide公司的发展小趣事

为了降低成本、提高生产效率,Cretex开始对产业链进行整合与优化。他们与上游供应商建立长期稳定的合作关系,确保原材料的稳定供应和质量可靠。同时,公司还加强了对下游客户的服务与支持,通过提供个性化的解决方案和优质的售后服务,增强了客户黏性。这些举措使得Cretex在激烈的市场竞争中保持了领先地位。

DIALIGHT公司的发展小趣事

DIALIGHT公司一直专注于工业LED照明领域的发展。他们深入了解工业空间照明的需求和挑战,设计了一系列专为工业应用而定制的LED照明产品。这些产品不仅易于安装和维护,而且能在恶劣的环境下持续使用。此外,DIALIGHT还提供集成系统解决方案,帮助客户降低能源成本、维护成本和碳足迹,同时提高设施的安全性和生产力。通过不断创新和优质服务,DIALIGHT在工业LED照明领域赢得了广泛的认可和信赖。

Herth+Buss Fahrzeugteile GmbH & Co KG公司的发展小趣事
能有效区分人体与其他物体的红外线辐射,减少误报。

问答坊 | AI 解惑

ADI和LSI双双退出手机芯片业务 彰显DSP产业大转型

LSI将手机芯片业务出售给了英飞凌,ADI也将手机芯片业务出售给了MTK,并可能退出包括Blackfin处理器在内的整个DSP业务。另外,英飞凌和Broadcom成了诺基亚的新宠。在手机芯片这个最大的DSP应用市场,四大传统DSP芯片供应商(TI、Freescale、ADI和Ag ...…

查看全部问答>

求二极管选型手册

rt 最好还可以按类别分开的 谢谢了…

查看全部问答>

VHDL学习资料

看了这些,包你会写点了...…

查看全部问答>

急!关于zigbee无线模块的问题

大家好,我现在正在做关于zigbee实现矿井管理的设计,我想问问在井下的节点中用S3C44B0X处理器和cc2420实现行吗?他们容易连接电路图吗?软件编程是不是很复杂啊?急需解决,谢谢!…

查看全部问答>

一个在51上nor flash的读写问题。谢谢大家。

问题如下,我使用nor flash作为存储器。向flash写入数据,再读出来,以此验证读写操作是否正确。但是现在的问题是:我向flash写入0x80一下的数据再读出来,都很好。例如:写入0x14,那么读出来就是0x14.都没有问题。但是一旦到了0x80那么读出来的数 ...…

查看全部问答>

如何购买周立功开发板EasyARM2131

本人住湛江,想购买周立功开发板EasyARM2131,却没有门路,请大家提供一下,谢谢。。。。。。。…

查看全部问答>

嵌入式板块里的斑竹?

你好, 毕业之后,这两年一直呆在工厂,没有时间上网。所以eeworld也很少来了。 以前也不是搞这一块的,现在该行从事了这一行,发现eeworld也有这样一个板块,很开心!~只是奇怪的是,虽然目前wince流行,但是ucos等也都是有各自的前景,弄来一个 ...…

查看全部问答>

LoadLibrary的问题

小弟在LoadLibrary上碰到点问题,不知何顾。 过程是这样的 我的开发环境是CE6和VS2005 创建了一个Smart Device的动态连接库,但是在loadlibrary的时候 总是返回失败,板卡厂家提供的Driver有些是以动态连接库提供的,我loadlibrary,也返回失败 ...…

查看全部问答>

从SD卡读出数据到TFT显示

采用数据重定向来实现,但是TFT不刷屏。。。…

查看全部问答>

信道模拟问题

请问有没有大神用成型滤波法来实现瑞利信道模拟技术,想问下你们用fft/ifft是采用什么结构类型的,求大神帮忙一下,有悬赏哦…

查看全部问答>