查看: 5763|回复: 48

【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共用。

    [C++] 纯文本查看 复制代码
    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,以此类推……  产生了“呼吸闪灯的效果”。
    [C++] 纯文本查看 复制代码
    #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的闪烁节奏完全不合,这仅用一个定时器是无法实现的。
    [C++] 纯文本查看 复制代码
    #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 | 显示全部楼层
    不错,赞赞赞赞赞赞赞
    您需要登录后才可以回帖 登录 | 立即注册  

    本版积分规则

    热门推荐

    体验OneNET,登录就送好礼
    体验OneNET,登录就送好礼
    OneNET--中国移动物联网开发平台,解决协议适配、海量连接、数据存储、设备管理等物
    初学arduino求助
    初学arduino求助
    大佬们,我想问一下,我现在想做一个程序:按下开关持续时间t,延迟7.77t后点亮led0.
    Arduino模拟USB鼠标
    Arduino模拟USB鼠标
    [md]### 模拟鼠标控制 下面将使用摇杆模块和Arduino Leonardo模拟USB鼠标。 [/md] [s
    ATK-esp8266WiFi模块
    ATK-esp8266WiFi模块
    我的esp8266模块以前烧进去过一次,半年没玩了。重新烧就提示错误了[/backcolor] 这是
    Arduino MEGA 与UNO 通过nRF24L模块通讯
    Arduino MEGA 与UNO 通过n
    之前在深水宝很“实惠”的店铺买了一些原件,随手砍了esp8266以及nRF24L*3 因为缺
    Copyright   ©2015-2016  Arduino中文社区  Powered by©Discuz!   ( 蜀ICP备14017632号-3 )
    快速回复 返回顶部 返回列表