查看: 7396|回复: 51

【CurieTimerZero】一个额外的定时器

[复制链接]
  • TA的每日心情
    开心
    2017-7-3 15:02
  • 签到天数: 56 天

    [LV.5]常住居民I

    发表于 2017-3-23 00:34 | 显示全部楼层 |阅读模式
    本帖最后由 甲基红橙黄绿蓝 于 2017-5-1 22:28 编辑

    概述:

    CurieTimerOne是Arduino101的定时器库。可用于定时中断和PWM。实际上ARC核心有两个定时器:Timer0是系统定时器,Timer1在CureTimerOne中为用户所使用。本帖将Timer0作为另一个定时器,编写库CurieTimerZero,实现和Timer1相同的功能。





    目的:        编写一个Arduino 101可用的额外的定时器库CurieTimerZero,并提供下载和使用说明。





    可行性分析:


    我阅读了相关库的代码,发现Timer0用于以下这几个函数:
    • delay                               延时若干毫秒
    • delayMicroseconds        延时若干微秒
    • delayTicks                       延迟若干个Tick,每个Tick是1/32微秒
    • millis                               获取101已经运行的时间,单位为毫秒
    • micros                                 获取101已经运行的时间,单位为微秒

    如果把Timer0为用户使用,这些函数就不能用了。其中delay的替代方案是软件实现(运行空循环),下面的delaySoft可以替代delay函数。而millis和micros函数是没有替代方案的。无法与CurieTimerZero共用。

    kittenblock中小学创客名师推荐的图形化编程软件

    
    void delaySoft(volatile uint32_t us){
      for(;us>0;us--)
        for(volatile uint32_t i=0;i<2456;i++);
    }
    








    CurieTimerZero 实现过程:


    经过对各种库、寄存器的一番研究,终于折腾出了CurieTimerZero库,与CurieTimerOne完全一样,也能进行定时中断和PWM输出。
    我编写的文件包括CurieTimerZero.h和CurieTimerZero.cpp。我不建议大家把它封装成库放在Arduino IDE的library下,因为它与Arduino的那几个内置函数是矛盾的,这有悖于Arduino的“通用硬件平台”的精神。我的建议是,只在需要使用更多定时器的场合,把这两个文件加入你的项目即可。





    CurieTimerZero 使用方法:
    首先,你需要下载本帖末尾的.zip包。下载库和示例代码请看本帖最后面的附件!该附件包括两个库文件CurieTimerZero.cpp和CurieTimerZero.h以及一个测试文件TimerZeroTest.ino。
    当你的一个Arduino 101程序需要用到额外的定时器时,把里面的CurieTimerZero.h和CurieTimerZero.cpp复制进你的项目目录,如下图:
    timerzero_show.png
    比方说你的项目主文件为TimerZeroTest.ino,则在TimerZeroTest.ino中#include "CurieTimerZero.h"  就可以。用法和CurieTimerOne库相同,具体例程请参考下文。






    两个例程:

    此处给出定时中断和PWM两个例程,其中需要的CurieTimerZero.h库请前往本帖最后下载
    1、定时中断:
    以下程序用两个定时器配合,实现了一个“呼吸闪灯”的效果。Timer0每50ms反转一次LED的电平、Timer0每51ms反转一次LED的电平。每经过一个周期,二者错开1ms,最后效果是:LED第一次亮持续1ms,第二次亮持续2ms,以此类推……  产生了“呼吸闪灯的效果”。

    kittenblock中小学创客名师推荐的图形化编程软件

    
    #include "CurieTimerOne.h"
    #include "CurieTimerZero.h"
    
    // 该函数把板载LED灯反转
    void timeInterrupt(){
      static uint8_t toggle = 0;
      digitalWrite(13, toggle);
      toggle = !toggle;
    }
    
    void setup() {
      pinMode(13,OUTPUT);
      // 启动Timer0作为定时中断器,每50毫秒执行一次timerInterrupt函数
      CurieTimerZero.start(50000, &timeInterrupt);
      // 启动Timer1作为定时中断器,每51毫秒执行一次timerInterrupt函数
      CurieTimerOne.start (51000, &timeInterrupt);
    }
    
    void loop() {
    }
    
    



    2、PWM
    以下程序使用两个定时器同时地,不互相干扰地分别在12号和13号引脚输出PWM。你可以把一个LED灯插在12号引脚上,观察到它与板载LED的闪烁节奏完全不合,这仅用一个定时器是无法实现的。

    kittenblock中小学创客名师推荐的图形化编程软件

    
    #include "CurieTimerOne.h"
    #include "CurieTimerZero.h"
    
    void setup() {
      // Timer0在 13 号引脚输出周期0.5秒,占空比20%的PWM信号
      CurieTimerZero.pwmStart(13, 20.0, 500000);    // Timer1在 12 号引脚输出周期0.8秒,占空比70%的PWM信号
      CurieTimerOne.pwmStart (12, 70.0, 800000);
    }
    
    void loop() {
    }
    








    问题报告:


    根据题主进行的测试,目前为止只有delay、delayMicroseconds、delayTicks、millis、micros函数无法和该库共用。而串口、GPIO、PWM、IMU、BLE都未受到CurieTimerZero库的影响。若有人出现其他库不能用的情况,可以在回帖里告知我。
    (注:此处的PWM是指3、5、6、9号引脚上的不可调频率的PWM,即analogWrite函数,它与CurieTimerOne和CurieTimerZero是互不干扰的)





    下载:
    游客,如果您要查看本帖隐藏内容请回复












    打赏作者鼓励一下!

    2人打赏

  • TA的每日心情
    开心
    2017-7-3 15:02
  • 签到天数: 56 天

    [LV.5]常住居民I

     楼主| 发表于 2017-3-23 16:46 | 显示全部楼层

    有什么问题吗?
    打赏作者鼓励一下!
  • TA的每日心情
    开心
    2016-12-9 13:12
  • 签到天数: 1 天

    [LV.1]初来乍到

    发表于 2017-3-24 13:45 | 显示全部楼层
    3Q for sharing.
  • TA的每日心情

    2017-12-1 18:12
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2017-6-6 13:34 | 显示全部楼层
    感谢楼主的分享,学习到不少的东西。

    该用户从未签到

    发表于 2017-7-25 15:28 | 显示全部楼层
    不错,赞赞赞赞赞赞赞
    您需要登录后才可以回帖 登录 | 立即注册  

    本版积分规则

    热门推荐

    博哥零基础教你玩转ESP8266(十三) ESP8266WiFiGeneric库
    博哥零基础教你玩转ESP826
    帖子导航帖 博哥零基础教你玩转ESP8266(一) 重识ESP8266 博哥零基础教你玩转ESP8266
    求助!WeMos D1 WiFi怎么接0.96寸OLED?(ㄒoㄒ)
    求助!WeMos D1 WiFi怎么
    求助!WeMos D1 WiFi怎么接0.96寸OLED?(ㄒoㄒ) 想用WeMos D1 WiFi接收服务器的数据然
    串口发送16进制指令求助
    串口发送16进制指令求助
    我准备串口发出16进制指令到我的外置设备 代码如下图 我分别监控ARDUINO的tx口和USB口
    一文教你选择Arduino开发板,小白进
    一文教你选择Arduino开发
    笔者在2016年接触了Arduino,跳了万条坑,行了千里弯,到今天也算是Arduino的一
    大神们!1602显示屏上的MQ2浓度示数不是实时监测的何解
    大神们!1602显示屏上的MQ
    本人小白,刚刚接触arduino,长时间的查阅资料后,通过复制修改代码接线实现了DHT11实
    Copyright   ©2015-2016  Arduino中文社区  Powered by©Discuz!   ( 蜀ICP备14017632号-3 )
    快速回复 返回顶部 返回列表