SYD8821 TIMER模块使用说明【TIMER4测试】

SYD8821是具有全球领先低功耗(RX 2.4mA @-94.5dBm灵敏度,TX 4.3mA @0dBm输出功率)的蓝牙低功耗SOC芯片,在极低电流下实现了优异的射频性能,搭配176kB SRAM,512kB flash,非常适合中高阶可穿戴、智能家居、物联网等低功耗应用具体可咨询:http://www.syd-tek.com/


SYD8821 TIMER模块使用说明


    这里除了timer0被协议栈占用外,剩下的timer1-timer4都可以被用户代码使用

   注意:SYD8821的计数器是递增计数器,也就是说这里设置的初值是定时器的溢出值(最大值),读回来的计数值是从0到溢出值之间。

   注意:timer0~timer3是16bit的计数器,也就是说timer0~timer3最多能够计数2s,而timer4位24bit的计数器,也就是说timer4最多能够记1024秒。

   这里硬件连接图如下:


    这里打开工程:“\SYD8821_SDK\Source Code\SYD8821\TIMER\Keil”可看到主函数如下:

int main()
{    
    uint8_t *buff;
    uint16_t buff_size=0;
    __disable_irq();

    // Select External XO
    sys_32k_clock_set(SYSTEM_32K_CLOCK_XO);
    // Set MCU Clock 64M
    sys_mcu_clock_set(MCU_CLOCK_64_MHZ);
    // RC bumping
    sys_mcu_rc_calibration();
  
    LED_KEY_Module_Init();
    UART_Module_Init();
    Timer_Module_Init();   //timer初始化
    
    __enable_irq();
    
    
    while(1)
    {
        gpo_toggle(LED4);
        
        if(timer1s_inting)
        {
            timer1s_inting = 0;
            gpo_toggle(LED7);
            uart_write(1,"SYD8821 TIMER1 1s TEST\r\n", 26);
            
        }
        。。。。。。。。。。。。。。。。。。
    }        
}

注意:这里选择SYSTEM_32K_CLOCK_XO(外部32.768KHz晶振)作为时钟源,这样定时器的周期才能够准确,当然,这里也可以用内部32.768KHz RC晶振做为时钟源,但是内部RC振荡器必须以一定的周期(3分钟左右)进行校准

其中初始化函数Timer_Module_Init源码如下:

void Timer_Module_Init(void)
{
    timer_disable(TIMER_1);    //使能定时器之前先失能定时器
    timer_enable(TIMER_1, timer1_callback, 32768, 1);//32768 = 1S  16384 = 500ms
  NVIC_EnableIRQ(TIMER1_IRQn);
}

注意:这里在使能定时器之前先失能定时器,否则在仿真的时候中断没能够上报上来

这里设置的定时器计数初值为32768,时钟源是32.768KHz,也就是说这里将产生1S的中断

逻辑分析仪看到的波形如下:


这里上传本博客源码:https://download.csdn.net/download/chengdong1314/10337404


TIMER4测试

这里用timer1和timer4同时设置相同的参数

void Timer_Module_Init(void)
{
    timer_disable(TIMER_1);
    timer_enable(TIMER_1, timer1_callback, 32768*2, 1);//32768 = 1S  16384 = 500ms
  NVIC_EnableIRQ(TIMER1_IRQn);
    timer_disable(TIMER_4);
    timer_enable(TIMER_4, timer4_callback, 32768*2, 1);//32768 = 1S  16384 = 500ms
  NVIC_EnableIRQ(TIMER4_IRQn);

}

可以看到timer1的波形和timer4的波形是不一样的,timer1的明显不对,timer4的波形是正确的两秒:


为了规范代码这里修改timer的驱动和相关头文件:

TIMER_CTRL_TYPE修改如下:

/* ============================ timer =========================== */
typedef struct {
    /* 0x00~ 0x03*/
    __IO  uint32_t    TIMER_ENABLE:1;
    __IO  uint32_t    RSVD00:31;    
    union{
        struct{
            /* 0x04~ 0x07*/
            __IO  uint32_t    TIMER_RELOAD_VAL:16;
            __IO  uint32_t    RSVD01:16;
            /* 0x08~ 0x0B*/    
            __IO  uint32_t    TIMER_COUNTER:16;
            __IO  uint32_t    RSVD02:16;
        };
        struct{
        /* 0x04~ 0x07*/
        __IO  uint32_t    TIMER4_RELOAD_VAL:24;
        __IO  uint32_t    RSVD011:8;
        /* 0x08~ 0x0B*/    
        __IO  uint32_t    TIMER4_COUNTER:24;
        __IO  uint32_t    RSVD021:8;
        };
  };
    /* 0x0C~ 0x17*/    
    __IO  uint32_t    RSVD03[3];
    /* 0x18~ 0x1B*/    
    __IO  uint32_t    INTERRUPT_OUT:1;
    __IO  uint32_t    RSVD04:31;    
    /* 0x1C~ 0x1F*/    
    __IO  uint32_t    TIMER_INTERRUPT_ENABLE:1;
    __IO  uint32_t    RSVD05:31;    
    /* 0x20~ 0x23*/    
    __IO  uint32_t    TIMER_INTERRUPT_DISABLE:1;
    __IO  uint32_t    RSVD06:31;    

}TIMER_CTRL_TYPE;

timer_enable修改如下:

uint8_t timer_enable(TIMER_ID id, TIMER_IRQ_CALLBACK_TYPE callback, int interval, int int_enable)
{
    if (is_timer_enabled(id) || id >= TIMER_NUM)
        return 0;
    
    cb[id] = callback;
        if(id==TIMER_4)ctrl[id]->TIMER4_RELOAD_VAL = interval;
        else ctrl[id]->TIMER_RELOAD_VAL = interval;
    
    if (int_enable)
        ctrl[id]->TIMER_INTERRUPT_ENABLE = 1;
    else
        ctrl[id]->TIMER_INTERRUPT_DISABLE = 1;
    
    ctrl[id]->TIMER_ENABLE = 1;
    
    return 1;
}

这里上传本节博文的源代码(工程在“\Source Code\SYD8821_other\TIMER4\Keil”):https://download.csdn.net/download/chengdong1314/10376685



猜你喜欢

转载自blog.csdn.net/chengdong1314/article/details/79873113