打印
[STM8]

【转】STM8S之定时器1的精确延时

[复制链接]
1512|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
说书先生|  楼主 | 2017-2-24 12:35 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式


四、实验前提
1、在进行本文步骤前,请先阅读以下博文:
暂无


2、在进行本文步骤前,请先实现以下博文:

暂无


五、基础知识

1、STM8S的定时器最快能定时多少时长?

答:由于STM8S是16M晶振,定时器最快可以1分频,因此它的定时器频率也是16M。

它定时最快时间是1/16M,也就是1/16us,但是香瓜实测低于50us的定时频率很容易影响代码的正常运行。

因此STM8S的定时频率最快是50us。


六、实验步骤

1、工程中添加自己写的定时器驱动

1)写一个定时器驱动timer1.c(存放在工程的USER文件夹中)


[cpp] view plain copy


  • //******************************************************************************         
  • //name:         timer1.c         
  • //introduce:    定时器驱动      
  • //author:       甜甜的大香瓜        
  • //changetime:   2016.05.16      
  • //email:        897503845@qq.com      
  • //******************************************************************************  
  • #include "timer1.h"  
  •   
  • /*********************内部变量************************/   
  • static u32 gTimer1_Delay;   
  •   
  • //******************************************************************************         
  • //name:             TIMER1_Init         
  • //introduce:        定时器1初始化      
  • //parameter:        none         
  • //return:           none        
  • //author:           甜甜的大香瓜               
  • //email:            897503845@qq.com            
  • //changetime:       2016.05.16                  
  • //******************************************************************************   
  • void TIMER1_Init(void)  
  • {  
  •   TIM1_TimeBaseInit(0,TIM1_COUNTERMODE_UP,800,0);     //1分频,向上计数,每50us定时中断一次, 重复计数器值为0     
  •   TIM1_ARRPreloadConfig(ENABLE);  
  •   TIM1_ITConfig(TIM1_IT_UPDATE , ENABLE);  
  •   TIM1_Cmd(ENABLE);  
  • }  
  •   
  • //******************************************************************************         
  • //name:             TIMER1_Decrement         
  • //introduce:        定时器减1      
  • //parameter:        none         
  • //return:           none        
  • //author:           甜甜的大香瓜               
  • //email:            897503845@qq.com            
  • //changetime:       2016.05.09                  
  • //******************************************************************************   
  • void TIMER1_Decrement(void)  
  • {  
  •   if(gTimer1_Delay != 0x00)  
  •   {   
  •     gTimer1_Delay--;  
  •   }  
  • }  
  •   
  • //******************************************************************************         
  • //name:             TIMER1_Delay50Us         
  • //introduce:        定时器延时50微秒      
  • //parameter:        none         
  • //return:           none        
  • //author:           甜甜的大香瓜               
  • //email:            897503845@qq.com            
  • //changetime:       2016.05.16                  
  • //******************************************************************************   
  • void TIMER1_Delay50Us(u32 nTime)  
  • {  
  •   gTimer1_Delay = nTime;  
  •   
  •   while(gTimer1_Delay != 0);  
  • }  


2)写一个定时器驱动头文件timer1.h(存放在工程的USER文件夹中)


[cpp] view plain copy


  • //******************************************************************************         
  • //name:         timer1.h         
  • //introduce:    定时器驱动的头文件      
  • //author:       甜甜的大香瓜        
  • //changetime:   2016.05.10      
  • //email:        897503845@qq.com      
  • //******************************************************************************  
  • #ifndef __TIMER1_H  
  • #define __TIMER1_H  
  •   
  • /*********************头文件************************/   
  • #include "stm8s.h"  
  •    
  • /*********************外部函数声明************************/   
  • void TIMER1_Init(void);  
  • void TIMER1_Decrement(void);  
  • void TIMER1_Delay50Us(u32 nTime);  
  •   
  • #endif  


3)工程中添加timer1.c



4)添加定时器驱动的路径


[cpp] view plain copy


  • $PROJ_DIR$\..\USER  

注意USER文件夹是与“Project”、“FWlib”文件夹同级的自定义文件,用于存放香瓜写的代码。


2、修改中断服务函数

1)添加头文件(stm8s_interruput.c中)


[cpp] view plain copy


  • #include "timer1.h"  


2)修改中断服务函数(stm8s_interruput.c中)


[cpp] view plain copy


  • #pragma vector=0xD  
  • __interrupt void TIM1_UPD_OVF_TRG_BRK_IRQHandler(void)  
  • {  
  •   TIMER1_Decrement();  
  •   TIM1_ClearITPendingBit(TIM1_IT_UPDATE);  
  • }  

在中断服务函数里不停地减gTimer1_Delay这个全局变量。



3、应用层中调用

1)添加头文件(main.c中)


[cpp] view plain copy


  • #include "timer1.h"  


2)初始化(main.c的main函数中)

[cpp] view plain copy


  • //开启定时器  
  • TIMER1_Init();   
  •   
  • //开全局中断   
  • asm("rim");     

初始化定时器后要记得开全局中断。

3)测试延时1S(main.c的main函数中)


[cpp] view plain copy


  • //延时1S  
  • TIMER1_Delay50Us(20000);  


七、实验结果

仿真,在“TIMER1_Delay50Us”函数前后设置断点,可发现执行时长为1S。或者用示波器观察更为准确。

因此,实验成功。


沙发
yiyigirl2014| | 2017-2-24 21:26 | 只看该作者
在定时器里定时一个全局变量,在delay里读取后,然后做差,得到要等待的那个计数值。当然了,要考虑计数的位置,下一个数应该是比现在的这个大还是小。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

71

主题

191

帖子

0

粉丝