damiaa 发表于 2017-10-15 17:07

CH554评测】第三篇 测试一下定时器

<div class='showpostmsg'> 本帖最后由 damiaa 于 2017-10-16 09:28 编辑

                                             CH554评测】第三篇 测试一下定时器

定时器,是单片机的必需品,无任定时,还是做PWM,还是测量时间间隔等都要用到.
CH554有两个16位定时器,Timer0/1。Timer2.下面只讨论定时器0和1.
相关寄存器:
TH18DhTimer1 计数高字节xxh
TH08ChTimer0 计数高字节xxh
TL18BhTimer1 计数低字节xxh
TL08AhTimer0 计数低字节xxh
TMOD89hTimer0/1 方式寄存器00h
TCON88hTimer0/1 控制寄存器00h
每个定时器有三个寄存器,一个是计数的,一个是模式设置的,还一个是控制的。这就是基本三元素。

定时/计数器 0/1 控制寄存器(TCON):
位名称访问   描述                                                                              
7   TF1    RW    Timer1 溢出中断标志位,进入定时器 1 中断后自动清零
6   TR1    RW    Timer1 启动/停止位,置 1 启动,由软件置位或者清零
5   TF0    RW    Timer0 溢出中断标志位,进入定时器 0 中断后自动清零
4   TR0    RW    Timer0 启动/停止位,置 1 启动,由软件置位或者清零
3   IE1   RW   INT1 外部中断 1 的中断请求标志位,进入中断后自动清零
2   IT1   RW   INT1 外部中断 1 触发方式控制位,该位为 0 选择外部中断为低电平触发;该位为 1 选择外部中断为下降边沿触发
1   IE0   RW   INT0 外部中断 0 的中断请求标志位,进入中断后自动清零
0   IT0   RW   INT0 外部中断 0 触发方式控制位,该位为 0 选择外部中断为低电平触发;该位为 1 选择外部中断为下降边沿触发
这里TCON只有4位给了定时器,其他的给外部中断用的,
定时/计数器 0/1 方式寄存器(TMOD):
位名称      访问      描述
7bT1_GATERW 门控使能位,控制 Timer1 启动是否受外部中断信号 INT1 的影响。该位为 0 则定时/计数器 1 是否启动与 INT1 无关;该位为 1
                         则只有 INT1 引脚为高电平并且 TR1 为 1 时才能启动
6bT1_CTRW    定时或者计数方式选择位,该位为 0 工作于定时方式;该位为 1工作于计数方式,使用 T1 引脚的下降沿作为时钟
5bT1_M1RW定时/计数器 1 模式选择高位
4bT1_M0RW定时/计数器 1 模式选择低位
3bT0_GATERW门控使能位,控制 Timer0 启动是否受外部中断信号 INT0 的影响。该位为 0 则定时/计数器 0 是否启动与 INT0 无关;该位为 1
                        则只有 INT0 引脚为高电平并且 TR0 为 1 时才能启动
2bT0_CTRW   定时或者计数方式选择位,该位为 0 工作于定时方式;该位为 1工作于计数方式,使用 T0 引脚的下降沿作为时钟
1bT0_M1RW定时/计数器 0 模式选择高位
0bT0_M0RW定时/计数器 0 模式选择低位

bTn_M1 ,bTn_M0
0             0         模式 0:13 位定时/计数器 n,计数单元由 TLn 的低 5 位和 THn 组成,TLn 的高 3 位无效。计数从 13 位全为 1 变成全为 0 时,设置溢出标志 TFn,并需重置初值
0             1         模式 1:16 位定时/计数器 n,计数单元由 TLn 和 THn 组成。计数从 16 位全为 1变成全为 0 时,设置溢出标志 TFn,并需重置初值
1             0         模式 2:8 位重载定时/计数器 n,计数单元使用 TLn,THn 作为重载计数单元。计数从 8 位全为 1 变成全为 0 时,设置溢出标志 TFn,并自动从 THn 加载初值
1             1         模式 3:如果是定时/计数器 0,那么定时/计数器 0 被分成 2 个部分 TL0 和 TH0,TL0 作为 8 位定时/计数器使用,占用 Timer0 的全部控制位;而 TH0 也做另一个
                         8 位定时器使用,占用 Timer1 的 TR1、TF1 和中断资源,并且此时 Timer1 仍然可用,只是不能使用启动控制位 TR1 和溢出标志位 TF1。如果是定时/计数器 1,那
                         么进入模式 3 将停止定时/计数器 1。

关于程序


D:\touch\ch554\CH554EVT\EVT\EXAM\Timer目录里有个例子,跑跑?main.c中调用以下几个在Timer.c中定义的函数初始化和期待定时器(我们这里用定时器1)
#ifdef T1_INT
    printf("T1 Test ...\n");
    mTimer1Clk12DivFsys();                                                         //T1定时器时钟设置      
    mTimer_x_ModInit(1,2);                                                   //T1 定时器模式设置
    mTimer_x_SetData(1,0x6464);                                                       //T1定时器赋值 这里用100 系统时钟为12M,12分频后刚好1US,这样定时器就是100US,加上定时器里面1万次闪动一下。刚好1秒。
    mTimer1RunCTL(1);                                                          //T1定时器启动               
    ET1 = 1;                                                                   //T1定时器中断开启               
    EA = 1;
    while(1);
#endif   

顺便说一下:这个例子中系统时钟是12M,CfgFsys( ); 这个函数确定的,如果要更改,到里面去改,就是CLOCK_CFG的低三位配置系统时钟 前面要先写SAFE_MOD = 0x55;SAFE_MOD = 0xAA;               
                   具体看系统时钟配置方面的资料和代码。
Timer.c中有中断响应函数,这里用P1.6,P1.7 LED指示,因为定时时间太短,肉眼无法分辨,就用个静态变量,让每10000次闪一下,刚好凑够1秒。这样就可以看到效果了。
#ifdef T1_INT
/*******************************************************************************
* Function Name: mTimer1Interrupt()
* Description    : CH554定时计数器0定时计数器中断处理函数
*******************************************************************************/
void      mTimer1Interrupt( void ) interrupt INT_NO_TMR1 using 2                //timer1中断服务程序,使用寄存器组2
{                                                                           //方式3时,Timer1停止
    static UINT16 timbuf=0;      
    timbuf++;
    if(timbuf >10000)
    {   
               timbuf=0;
               RXD1 = ~RXD1;
               TXD1 = ~TXD1;//SCK = ~SCK;                  
   }
}
#endif

下面附上HEX文件:
今天用这个为自己做了个定时器,可以定时N个时间,但苦于电路的原因,没有蜂鸣器提示,只好先 用个LED提示,目前没用到小时,也只定时8个时间。
Timer.h中
typedef struct CCLOCK
{
      UINT8 hour;
      UINT8 min;
      UINT8 second;
      UINT8 secondflag;//为了主程序中每秒只判断一次,避免一秒中重复判断
}CLOCK;
Timer.c中
CLOCK thisclock;
CLOCK *pclock =&thisclock;
void clockinc(CLOCK *pclock)
{
      pclock->second++;
      pclock->secondflag++;
      if(pclock->second>=60)
      {      
                pclock->second=0;
                pclock->min++;
                if(pclock->min>=60)
                {
                        pclock->min =0;
                        pclock->hour++;
                        if(pclock->hour >=24) pclock->hour =0;
                }      
      }
}      
void    mTimer1Interrupt( void ) interrupt INT_NO_TMR1 using 2               
{                                                                        
         static UINT16 timbuf=0;      
          timbuf++;
          if(timbuf >10000)
          {   
                  timbuf=0;
                  clockinc(pclock);
         }
}
main.c中
extern CLOCK thisclock;
UINT8 timdata = {2,30, 6,50, 11,10, 15,30, 19,50, 24,10, 28,30, 32,50};//37,10 //如果要用到小时,这里增加小时,比较的时候也增加
//UINT8 timdata = {0,2,30, 0,6,50, 0,11,10, 0,15,30, 0,19,50, 0,24,10, 0,28,30, 0,32,50};//37,10

while(1)
{
          if(thisclock.secondflag)
          {
                thisclock.secondflag =0;
                if(status <8)
                {
                        if((thisclock.min == timdata)&&(thisclock.second==timdata))
                        // if((thisclock.hour == timdata)&&(thisclock.min == timdata)&&(thisclock.second==timdata))//如果要用定时器
                         {
                              RXD1 = 0;//定时时间到闪动一下
                              status++;      
                         }
                         else
                              RXD1 = 1;
                  }
         }
}      
程序代码:后续有机会看是否 改为USB能配置定时。
此内容由EEWORLD论坛网友damiaa原创,如需转载或用于商业用途需征得作者同意并注明出处
















</div><script>                                        var loginstr = '<div class="locked">查看本帖全部内容,请<a href="javascript:;"   style="color:#e60000" class="loginf">登录</a>或者<a href="https://bbs.eeworld.com.cn/member.php?mod=register_eeworld.php&action=wechat" style="color:#e60000" target="_blank">注册</a></div>';
                                       
                                        if(parseInt(discuz_uid)==0){
                                                                                                (function($){
                                                        var postHeight = getTextHeight(400);
                                                        $(".showpostmsg").html($(".showpostmsg").html());
                                                        $(".showpostmsg").after(loginstr);
                                                        $(".showpostmsg").css({height:postHeight,overflow:"hidden"});
                                                })(jQuery);
                                        }                </script><script type="text/javascript">(function(d,c){var a=d.createElement("script"),m=d.getElementsByTagName("script"),eewurl="//counter.eeworld.com.cn/pv/count/";a.src=eewurl+c;m.parentNode.insertBefore(a,m)})(document,523)</script>

asha 发表于 2017-10-15 20:07

{:1_103:}不错

dgg44111 发表于 2017-10-15 20:50

damiaa 发表于 2017-10-15 21:23

asha 发表于 2017-10-15 20:07
不错

谢谢

沁恒USB单片机 发表于 2017-10-16 08:54

:):handshake

damiaa 发表于 2017-10-16 09:26

沁恒USB单片机 发表于 2017-10-16 08:54


:handshake:surrender:
页: [1]
查看完整版本: CH554评测】第三篇 测试一下定时器