当前位置:   article > 正文

ESP8266_06---------------定时器_esp8266 定时器

esp8266 定时器

一、软件定时器:

1.软件定时器:
        是用程序模拟出来的定时器,它的特点是不会受到我们硬件资源不足的限制,在你的 CPU 和内存足够的情况下可以设置成百上千个软件定时器,但是它的缺点就是做不到特 别的准确,因为他是软件模拟的,当我们的 CPU 被别的事情抢占,如中断发生 等,会导致定时时间的不稳定性,因此不能使用在我们对时间要求特别严格的场合。
2.要用到的函数:
 1.关闭软件定时器:
  1. void os_timer_disarm (os_timer_t *ptimer)
  2. //ptimer 为 os_timer_t 类型结构体,需要我们提前定义
2.注册定时器回调函数:
  1. void os_timer_setfn(os_timer_t *ptimer,os_timer_func_t *pfunction,void *parg)
  2. //os_timer_t *ptimer:定时器结构体
  3. //os_timer_func_t *pfunction:定时回调函数
  4. //void *parg:回调函数的参数
3.使能毫秒定时器:
  1. void os_timer_arm(os_timer_t *ptimer, uint32_t milliseconds, bool repeat_flag)
  2. //os_timer_t *ptimer:定时器结构体
  3. //uint32_t milliseconds:定时时间,单位:ms
  4. //如未调用 system_timer_reinit,可支持范围 5 ~ 0x68D7A3
  5. //如调用了 system_timer_reinit,可支持范围 100 ~ 0x689D0
  6. //bool repeat_flag:定时器是否重复 0:不重复定时器 1:重复定时
4.  当需要使用微秒定时器时需要重新初始化定时器:
  1. void system_timer_reinit(void)
  2. //注意 system_timer_reinit 需要在程序最开始调用, user_init 的第一句。
5.  使能微秒定时器(不建议使用):
  1. void os_timer_arm_us (os_timer_t *ptimer, uint32_t microseconds, bool repeat_flag)
  2. //os_timer_t *ptimer:定时器结构体
  3. //uint32_t microseconds:定时时间,单位 us,最小 0x64,最大 0xFFFFFFF
  4. //bool repeat_flag:是否重复定时,0:不重复定时,1:重复定时

3.程序的编写:

我们程序的功能是:每隔500ms打印"hello"

我们需要自己编写软件定时器的驱动文件os_timer.c和os_timer.h,然后将他们分别添加到app/driverapp/include/driver下,刷新工程。

1.os_timer.h:

  1. #ifndef __OS_TIMER_H
  2. #define __OS_TIMER_H
  3. #include "ets_sys.h"
  4. #include "osapi.h" //系统函数
  5. #include "user_interface.h"
  6. void OS_Timer_1_Cb(void);
  7. void OS_Timer_Init(uint32_t ms,bool repeat_flag);
  8. #endif /* OS_TIMER_H */

2.os_timer.c:

  1. #include "./driver/os_timer.h"
  2. os_timer_t os_timer_1;//定义软件定时器结构体变量
  3. //软件定时器回调函数
  4. void OS_Timer_1_Cb(void)
  5. {
  6. os_printf("hello\n");
  7. }
  8. //软件定时器配置初始化
  9. void OS_Timer_Init(uint32_t ms,bool repeat_flag)
  10. {
  11. os_timer_disarm(&os_timer_1);//关闭软件定时器
  12. os_timer_setfn(&os_timer_1,(os_timer_func_t*)OS_Timer_1_Cb,NULL);//注册软件定时器回调函数
  13. os_timer_arm(&os_timer_1,ms,repeat_flag);//打开软件定时器,设置定时周期,设置是否自动重装
  14. }

3.user_main.c:

  1. #include "ets_sys.h"
  2. #include "user_config.h"//用户配置
  3. #include "eagle_soc.h"//GPIO函数,宏定义
  4. #include "c_types.h" //变量类型
  5. #include "osapi.h" //系统函数
  6. #include "user_interface.h"
  7. #include "./driver/os_timer.h"//软件定时器
  8. /******************************************************************************
  9. * FunctionName : user_rf_cal_sector_set
  10. * Description : SDK just reversed 4 sectors, used for rf init data and paramters.
  11. * We add this function to force users to set rf cal sector, since
  12. * we don't know which sector is free in user's application.
  13. * sector map for last several sectors : ABCCC
  14. * A : rf cal
  15. * B : rf init data
  16. * C : sdk parameters
  17. * Parameters : none
  18. * Returns : rf cal sector
  19. *******************************************************************************/
  20. uint32 ICACHE_FLASH_ATTR
  21. user_rf_cal_sector_set(void)
  22. {
  23. enum flash_size_map size_map = system_get_flash_size_map();
  24. uint32 rf_cal_sec = 0;
  25. switch (size_map) {
  26. case FLASH_SIZE_4M_MAP_256_256:
  27. rf_cal_sec = 128 - 5;
  28. break;
  29. case FLASH_SIZE_8M_MAP_512_512:
  30. rf_cal_sec = 256 - 5;
  31. break;
  32. case FLASH_SIZE_16M_MAP_512_512:
  33. rf_cal_sec = 512 - 5;
  34. break;
  35. case FLASH_SIZE_16M_MAP_1024_1024:
  36. rf_cal_sec = 512 - 5;
  37. break;
  38. case FLASH_SIZE_32M_MAP_512_512:
  39. rf_cal_sec = 1024 - 5;
  40. break;
  41. case FLASH_SIZE_32M_MAP_1024_1024:
  42. rf_cal_sec = 1024 - 5;
  43. break;
  44. case FLASH_SIZE_64M_MAP_1024_1024:
  45. rf_cal_sec = 2048 - 5;
  46. break;
  47. case FLASH_SIZE_128M_MAP_1024_1024:
  48. rf_cal_sec = 4096 - 5;
  49. break;
  50. default:
  51. rf_cal_sec = 0;
  52. break;
  53. }
  54. return rf_cal_sec;
  55. }
  56. void ICACHE_FLASH_ATTR
  57. user_rf_pre_init(void)
  58. {
  59. }
  60. //毫秒延时函数
  61. void ICACHE_FLASH_ATTR
  62. delay_ms(u32 ms)
  63. {
  64. for(;ms>0;ms--){
  65. os_delay_us(1000);//1ms
  66. }
  67. }
  68. /******************************************************************************
  69. * FunctionName : user_init
  70. * Description : entry of user application, init user function here
  71. * Parameters : none
  72. * Returns : none
  73. *******************************************************************************/
  74. void ICACHE_FLASH_ATTR
  75. user_init(void)
  76. {
  77. uart_init(9600,9600);
  78. os_printf("\r\nESP8266软件定时器\r\n");
  79. OS_Timer_Init(500,1);//500ms,重装载
  80. }

4.运行结果:

二、硬件定时器 :

1.硬件定时器:
      全名为硬件中断定时器,它不像软件定时器由程序模拟实现,而是由我们的 ESP8266 上的硬件模块实现,也是就说在厂家设计 ESP8266 这一款芯片的时候就已经将我们的硬件定时器设计到芯片内部了,同时,我们的硬件定时器由中断触发,保证了定时器的准确性。
2.使用时的注意事项:
     1.我们的硬件定时器中断使用的是哪种中断源?如果我们使用的是 NMI 中断源,那么我们的硬件定时器将为最高优先级,可打断其他中断;如果我们使用的是 FRC1 中断源,那么该定时器将无打断其他中断。
     2.  如果我们的硬件定时器使用 NMI 中断源,且设置为自动重装载,也就是 重复定时,那么我们在使能硬件定时器的时候设置的定时时间必须大于100(也就是 hw_timer_arm() 函数的参数必须大于 100 )。
     3.  我们的硬件定时器不可以和 PWM 驱动同时使用,因为二者使用的是同一个硬件定时器。
     4.为 了 保 证 中 断 服 务 函 数 快 速 响 应 , 中 断 服 务 函 数 不 要 ICACHE_FLASH_ATTR 宏修饰。
     5.使用硬件定时器时,请勿调用 wifi_set_sleep_type(LIGHT_SLEEP);开启自动睡眠模式,因为在睡眠期间 CPU 会停止运行,将导致不能响应 NMI中断。
3.要用到的函数:
   1.初始化硬件定时器:
   
  1. void hw_timer_init (FRC1_TIMER_SOURCE_TYPE source_type,u8 req)
  2. //FRC1_TIMER_SOURCE_TYPE source_type:中断源设置。
  3. //0:FRC1_SOURCE:使用 FRC1 中断源;
  4. //1:NMI_SOURCE:使用 NMI 中断源。
  5. //u8 req:设置是否重装载。
  6. //0:不自动重装载;
  7. //1:自动重装载。
   2.注册定时器中断服务函数:
  1. void hw_timer_set_func(void(* user_hw_timer_cb_set)(void))
  2. //void (* user_hw_timer_cb_set)(void):定时器回调函数(中断服务函数)
  3.使能硬件中断定时器:
  1. void hw_timer_arm(uint32 val)
  2. //uint32_t val:定时时间
  3. /*
  4. 注意:在自动重装载模式,如果是 NMI 中断源,取值范围:
  5. 100-0x199999μs(100us - 1,677,721us)如果是 FRC1中断源,
  6. 取值范围:50-0x199999μs(50us-1,677,721us)。在非自动重装载模式,
  7. 取值范围:10 - 0x199999μs
  8. */

4.程序的编写:
    程序的功能:每隔500ms打印"hello HWTimer"
将driver_lib/driver中的 hw_timer.c 添加到 app/driver 下,我们需要使用这里的函数创建自己的硬件驱动 hw_timer_driver.c hw_timer_driver.h ,然后将他们分别添加到 app/driver 和 app/include/driver下,刷新工程。

1.hw_timer_driver.h:

  1. #ifndef __HW_TIMER_DRIVER_H
  2. #define __HW_TIMER_DRIVER_H
  3. #include "ets_sys.h"
  4. #include "osapi.h" //系统函数
  5. #include "user_interface.h"
  6. void HW_Timer_Interrupt(void);
  7. void HW_Timer_Init(uint32_t us);
  8. #endif

2.hw_timer_driver.c:

  1. #include "./driver/hw_timer_driver.h"
  2. //硬件定时器中断服务函数
  3. void HW_Timer_Interrupt(void)
  4. {
  5. os_printf("hello HWTimer\n");
  6. }
  7. //硬件定时器初始化配置函数
  8. void HW_Timer_Init(uint32_t us)
  9. {
  10. if(us<100 || us>1677721)
  11. {
  12. os_printf("us<100 || us>1677721\n");
  13. }
  14. hw_timer_init(1,1);//硬件定时器初始化,使用NMI中断源,重复定时
  15. hw_timer_set_func(HW_Timer_Interrupt);//注册硬件定时器中断服务函数
  16. hw_timer_arm(us);//使能中断定时器并设置定时时间
  17. os_printf("HW_Timer OK !\n");
  18. }

3.user_main.c:

  1. #include "ets_sys.h"
  2. #include "user_config.h"//用户配置
  3. #include "eagle_soc.h"//GPIO函数,宏定义
  4. #include "c_types.h" //变量类型
  5. #include "osapi.h" //系统函数
  6. #include "user_interface.h"
  7. #include "./driver/hw_timer_driver.h"
  8. /******************************************************************************
  9. * FunctionName : user_rf_cal_sector_set
  10. * Description : SDK just reversed 4 sectors, used for rf init data and paramters.
  11. * We add this function to force users to set rf cal sector, since
  12. * we don't know which sector is free in user's application.
  13. * sector map for last several sectors : ABCCC
  14. * A : rf cal
  15. * B : rf init data
  16. * C : sdk parameters
  17. * Parameters : none
  18. * Returns : rf cal sector
  19. *******************************************************************************/
  20. uint32 ICACHE_FLASH_ATTR
  21. user_rf_cal_sector_set(void)
  22. {
  23. enum flash_size_map size_map = system_get_flash_size_map();
  24. uint32 rf_cal_sec = 0;
  25. switch (size_map) {
  26. case FLASH_SIZE_4M_MAP_256_256:
  27. rf_cal_sec = 128 - 5;
  28. break;
  29. case FLASH_SIZE_8M_MAP_512_512:
  30. rf_cal_sec = 256 - 5;
  31. break;
  32. case FLASH_SIZE_16M_MAP_512_512:
  33. rf_cal_sec = 512 - 5;
  34. break;
  35. case FLASH_SIZE_16M_MAP_1024_1024:
  36. rf_cal_sec = 512 - 5;
  37. break;
  38. case FLASH_SIZE_32M_MAP_512_512:
  39. rf_cal_sec = 1024 - 5;
  40. break;
  41. case FLASH_SIZE_32M_MAP_1024_1024:
  42. rf_cal_sec = 1024 - 5;
  43. break;
  44. case FLASH_SIZE_64M_MAP_1024_1024:
  45. rf_cal_sec = 2048 - 5;
  46. break;
  47. case FLASH_SIZE_128M_MAP_1024_1024:
  48. rf_cal_sec = 4096 - 5;
  49. break;
  50. default:
  51. rf_cal_sec = 0;
  52. break;
  53. }
  54. return rf_cal_sec;
  55. }
  56. void ICACHE_FLASH_ATTR
  57. user_rf_pre_init(void)
  58. {
  59. }
  60. //毫秒延时函数
  61. void ICACHE_FLASH_ATTR
  62. delay_ms(u32 ms)
  63. {
  64. for(;ms>0;ms--){
  65. os_delay_us(1000);//1ms
  66. }
  67. }
  68. /******************************************************************************
  69. * FunctionName : user_init
  70. * Description : entry of user application, init user function here
  71. * Parameters : none
  72. * Returns : none
  73. *******************************************************************************/
  74. void ICACHE_FLASH_ATTR
  75. user_init(void)
  76. {
  77. uart_init(9600,9600);
  78. os_printf("\r\nESP8266硬件定时器\r\n");
  79. HW_Timer_Init(500000);//500ms
  80. }

5.运行结果:

如需源码请在评论区留下邮箱地址!!! 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/398031
推荐阅读
相关标签
  

闽ICP备14008679号