历史上的今天
返回首页

历史上的今天

今天是:2024年10月08日(星期二)

正在发生

2021年10月08日 | 正点原子关于STM8S精确延时函数

2021-10-08 来源:eefocus

已经写完了STM8S的系统文件(同stm32一样,包括sys.c,delay.c和uart.c三个文件)
这里先分享delay.c和delay.h.


本来想仿效STM32用一个定时器来做,无奈STM8S提供的是一个8位定时器,真是食之无味了...


算来算去,用这个8位的定时器横竖都不好做延时,用16位的定时器嘛又怕浪费.真不知道st的人怎么想的.


这个8位的基本定时器,连ucosii的滴答时钟都不好提供...(24Mhz下,最大只能1.3ms左右中断一次,16Mhz则是2ms左右)


难不成多次中断,触发一次任务切换?
所以,表示蛋疼的很,无奈只能想用汇编的方式来实现精确延时了.
研究了几天,终于小有成就.汇编写了一个us级延时函数,还算比较准.
24M和8M时,差别有点多,24M时STM8S要插入一个flash等待周期,这样st说是可以提供20MIPS的性能,但是我迷糊了...到底此时的指令周期如何算?st没有提到.


最后测试发现,大概是19Mhz的指令运行速度,也就是单周期指令,执行时间在24M时钟频率下约为1/19Mhz 秒.单根据我的计算公式,得不到19这个值,于是只能取近似了,按理说20比较准,不过实测16会准确一些.故采用了16,然后导致的结果就是延时变快了.


比如延时100ms,实际上可能是92ms左右.

而8Mhz时,差别有点多,表示不太理解,因为根据我的设计,刚好是8个周期的,应该是延时准确才对,但事实并非如此.


下面是各时钟频率下的延时准确性(测试时使用的延时至少>10us):
 //92%  @24Mhz
//98%   @16Mhz
//98%   @12Mhz
//86%   @8Mhz


可以看到,12M和16M条件下有比较高的准确度,24M稍微差点(主要是偏快). 


一般应用,这样的精度,应该都可以满足使用了,源码下面附上,如有改进意见,欢迎提出,开源才能集思广益,而后才能精益求精.

delay.h代码如下:

#ifndef  __DELAY_H
#define  __DELAY_H
#include "sys.h"
////////////////////////////////////////////////////////////////////////////////  
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK 
//使用汇编代码进行精确延时处理
//包括delay_us,delay_ms
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//修改日期:2013/6/25
//版本:V1.0
//版权所有,盗版必究。
//Copyright(C) 广州市星翼电子科技有限公司 2009-2019
//All rights reserved
//******************************************************************************
//V1.0 20130625
//支持不同时钟频率
//提供delay_us,delay_ms两个延时函数. 
////////////////////////////////////////////////////////////////////////////////

void delay_init(u8 clk); //延时函数初始化
void delay_us(u16 nus);  //us级延时函数,最大65536us.
void delay_ms(u32 nms);  //ms级延时函数
#endif

delay.c代码如下:

#include "delay.h"
////////////////////////////////////////////////////////////////////////////////  
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK 
//使用汇编代码进行精确延时处理
//包括delay_us,delay_ms
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//修改日期:2013/6/25
//版本:V1.0
//版权所有,盗版必究。
//Copyright(C) 广州市星翼电子科技有限公司 2009-2019
//All rights reserved
//******************************************************************************
//V1.0 20130625
//支持不同时钟频率
//提供delay_us,delay_ms两个延时函数. 
////////////////////////////////////////////////////////////////////////////////


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

//延时函数初始化
//为确保准确度,请保证时钟频率最好为4的倍数,最低8Mhz
//clk:时钟频率(24/16/12/8等) 
void delay_init(u8 clk)
{
 if(clk>16)fac_us=(16-4)/4;//24Mhz时,stm8大概19个周期为1us
 else if(clk>4)fac_us=(clk-4)/4; 
 else fac_us=1;
}
//延时nus
//延时时间=(fac_us*4+4)*nus*(T)
//其中,T为CPU运行频率(Mhz)的倒数,单位为us.
//准确度:
//92%  @24Mhz
//98%  @16Mhz
//98%  @12Mhz
//86%  @8Mhz
void delay_us(u16 nus)
{  
__asm(
"PUSH A         n"  //1T,压栈
"DELAY_XUS:     n"   
"LD A,fac_us    n"   //1T,fac_us加载到累加器A
"DELAY_US_1:    n"  
"NOP            n"  //1T,nop延时
"DEC A          n"  //1T,A--
"JRNE DELAY_US_1 n"  //不等于0,则跳转(2T)到DELAY_US_1继续执行,若等于0,则不跳转(1T).
"NOP            n"  //1T,nop延时
"DECW X         n"  //1T,x--
"JRNE DELAY_XUS n"   //不等于0,则跳转(2T)到DELAY_XUS继续执行,若等于0,则不跳转(1T).
"POP A          n"  //1T,出栈
); 

//延时nms  
//为保证准确度,nms不要大于16640.
void delay_ms(u32 nms)
{
 u8 t;
 if(nms>65)
 {
  t=nms/65;
  while(t--)delay_us(65000);
  nms=nmse;
 }
 delay_us(nms*1000);
}

推荐阅读

史海拾趣

AC Interface Inc公司的发展小趣事

ABC Electronics Inc. 深知人才是企业发展的核心动力。因此,公司高度重视人才培养和引进工作。一方面,公司建立了完善的人才培养机制,通过内部培训、轮岗锻炼等方式提升员工的技能和素质;另一方面,公司积极引进具有创新精神和国际视野的高端人才,为公司的技术创新和市场拓展提供了有力支撑。这些人才战略的实施,为公司的长远发展奠定了坚实基础。

这些故事虽然是以虚构的ABC Electronics Inc.为例,但其中的情节和策略在电子行业中是普遍存在的。如果AC Interface Inc是一个真实存在的公司,它的发展轨迹可能也会涉及这些方面。当然,具体的故事还需要根据公司的实际情况来创作。

BLACK&DECKER公司的发展小趣事

BLACK&DECKER在技术创新方面一直走在行业前列。公司不断投入研发资源,推动电动工具技术的进步。例如,1979年,BLACK&DECKER发布了第一台手提式充电吸尘器Dustbuster,这一创新产品迅速成为市场上的热销产品,并推动了整个吸尘器行业的发展。此外,BLACK&DECKER还积极参与行业标准的制定工作,通过制定严格的产品质量标准和安全规范,为整个电子行业的健康发展做出了贡献。

兵字(BingZi)公司的发展小趣事

随着市场的不断变化和客户需求的日益多样化,兵字公司意识到,要想在市场中保持领先地位,就必须不断进行技术创新。于是,公司投入大量研发资源,成功研发出了小型精密互感器。这一创新产品不仅填补了市场空白,还为公司带来了可观的收益。同时,兵字公司也凭借这一技术突破,进一步巩固了在电子元器件领域的领先地位。

FOX [Fox Electronics]公司的发展小趣事

为了进一步扩大市场份额和增强技术实力,Fox Electronics在近年来进行了多起战略并购和合作。公司通过收购具有核心竞争力的中小型企业,快速获取了新技术、新产品和客户资源。同时,Fox Electronics还与行业内的知名企业和研究机构建立了长期合作关系,共同开展技术研发和市场推广。这些并购与合作不仅加速了公司的业务扩张,还提升了其在全球电子行业的影响力。

General Instrument公司的发展小趣事
对于计算机、服务器等需要持续供电的设备,突然断电可能导致数据丢失。
Ercona Corp公司的发展小趣事
如果以上步骤无法解决问题,建议寻求专业电工的帮助进行排查和处理。

问答坊 | AI 解惑

晒板子28335

28335电力电子与电力传动专用控制板 …

查看全部问答>

机电领域中伺服电机的选择原则

提出的选择原则是将电机特性与负载特性分离开 ,并用图解的形式表示 ,这种表示方法使得驱动 装置的可行性检查和不同系统间的比较更方便 ,另外 ,还提供了传动比的一个可能范围.…

查看全部问答>

获取芯币的另一个小诀窍

快速获得芯币的另一种方法,就是与博客紧密结合。规则如下,请大家详细阅读啊! 1、注册博客 + 20 芯币 2、在论坛签名中注明自己博客地址  +5 芯币    3、博客个人信息注册完全,其中上传电子相片  +5芯币 4、 ...…

查看全部问答>

一本dsp2812的好书

最近刚刚从图书馆借到一本新书《dsp控制技术实践》。中国电力出版社出版,2009.5出版的。专门讨论dsp2812的片子的使用,比ti的中文手册薄多了,看起来挺舒服的。推荐给大家。…

查看全部问答>

LED行业竞争白热化,各大厂商拿什么取胜呢?打扰了。

LED行业竞争白热化,各大厂商拿什么取胜呢?打扰了。…

查看全部问答>

请问这几句汇编具体的意思是什么?

GBLS        MainEntry MainEntry        SETS        \"Main\"         IMPORT        $MainEntry MainEntry不是已经在第一行就已经定 ...…

查看全部问答>

MC2833/MC3363如何编程

这是朋友的一个毕业设计题目。别的部分没什么特别。但是,这个课题使用了MC2822/MC3363这一对摩托罗拉的音频收发芯片来实现无线收发。我的毕业设计用的是nRF24L01,所以我很习惯性用这个去套它的思路。可是我在网上查了查,似乎没有找到关于它的编程 ...…

查看全部问答>

关于QEI的问题

最近正在学习luminary,用的是周立功的easyArm8962的板子,在qei的实验例程中有这么两句话:SysCtlPeripheralEnable(SYSCTL_PERIPH_QEI);GPIODirModeSet(GPIO_PORTC_BASE, GPIO_PIN_4 | GPIO_PIN_6,   GPIO_DIR_MODE_HW);GPIODirModeSet( ...…

查看全部问答>

Smart Debug网络与串口调试工具(原创)

最新版本号: 1.0.1.111031        更新日期: 2011.10.26 下载地址1 http://stu.cidp.edu.cn/SmartDebug.rar 下载地址1 下载地址2 http://www.vdisk.cn/down/index/8990713A3710 下 ...…

查看全部问答>

希望大家帮帮忙

不好意思 有件事情麻烦大家 老师布置了一项作业之前设计原理图时没看要求 搞错了 现在时间有点急希望大家有能人帮我设计一个原理图 要求如下: 九、彩灯控制器一 要求:1.有八只LED,L0……L72.显示顺序如下表3.显示间隔为0.25S,0.5S,1S,2S ...…

查看全部问答>