FireBLE

FireBLE 是一个面向于打造智能生活的开源平台,以BLE(Bluetooth Low Energy)技术为核心,拥有超低的功耗、不俗的处理能力和广泛的应用场合,专注于更智能、高效率的工作模式,让生活在科技中更安全、方便、快捷。也许您一个不经意的想法与FireBLE擦出的火花,会在这片原野上燎出火焰,甚至燃烧整个世界。

TIMER 驱动

更新时间:2017-08-08 阅读:2505

前言

定时器做为单片机开发中最基本的一个驱动,为系统提供了许多方便的操作和精确的时间节拍。QN902x拥有4个定时器,其中TIMER0/1为32位的定时器,TIMER2/3为16位定时器。定时器有定时、计数、捕获、比较等等功能。

初始化

系统初始化、GPIO初始化以及定时器引脚配置

    SystemInit();
 
    /* Initialize GPIO (sets up clock) */
    gpio_init(NULL);
    /* Set all pin to output */
    gpio_set_direction_field(LED_PINS, (uint32_t)GPIO_OUTPUT);
    gpio_write_pin_field(LED_PINS, (uint32_t)GPIO_HIGH);
 
 
    // Timer io configurate
    timer_io_config();

定时器的IO初始化,QN9021由于兼顾封装体积,所以IO有所缩减,引脚配置与QN9020会有一些差别。

void timer_io_config(void)
{
    // pin mux
    syscon_SetPMCR0(QN_SYSCON, P07_SW_CLK_PIN_CTRL       
                             | P06_SW_DAT_PIN_CTRL
                             | P00_UART0_TXD_PIN_CTRL      
                             | P17_UART0_RXD_PIN_CTRL   
                             | P03_TIMER0_ECLK_PIN_CTRL //P0.3 timer0, used for pwm and caputure
                             | P10_TIMER2_ECLK_PIN_CTRL //P1.0 timer2, used for pwm and caputure
                             | P11_TIMER1_ICP0_PIN_CTRL //P1.1 timer1, used for pwm and caputure
                             );
    syscon_SetPMCR1(QN_SYSCON, P23_TIMER3_ICP0_PIN_CTRL //P2.3 timer3, used for pwm and caputure      
                             );
// pin pull ( 00 : High-Z,  01 : Pull-down,  10 : Pull-up,  11 : Reserved )
    syscon_SetPPCR0(QN_SYSCON, 0xAAAA5AAA);
    syscon_SetPPCR1(QN_SYSCON, 0x2AAAAAAA);
}

定时器示例

定时器共有定时中断实验、PWM输出实验、事件时间捕获实验、事件计数捕获实验和捕获事件实验。

定时器定时中断实验

本实验为为定时中断实验,分别对不同的定时器设定不同的初始值,定时器在时间到达后触发中断,在回调函数中进行LED的亮灭取反,使4个LED按照不同的频率闪烁。 定时器0/1作为32位定时器,精度比较高,时间间隔较短,分频系数较小。

    timer_init(QN_TIMER0, led0_link);
    timer_config(QN_TIMER0, TIMER_PSCAL_DIV, TIMER_COUNT_US(1000, TIMER_PSCAL_DIV));
    timer_enable(QN_TIMER0, MASK_ENABLE);
 
    timer_init(QN_TIMER1, led1_link);
    timer_config(QN_TIMER1, TIMER_PSCAL_DIV, TIMER_COUNT_US(2000, TIMER_PSCAL_DIV));
    timer_enable(QN_TIMER1, MASK_ENABLE);

定时器2/3作为16位定时器,精度比较低,时间间隔较长,分频系数较大。

    timer_init(QN_TIMER2, led2_link);
    timer_config(QN_TIMER2, 10, TIMER_COUNT_MS(3, 10));
    timer_enable(QN_TIMER2, MASK_ENABLE);
 
    timer_init(QN_TIMER3, led3_link);
    timer_config(QN_TIMER3, 10, TIMER_COUNT_MS(4, 10));
    timer_enable(QN_TIMER3, MASK_ENABLE);

定时器PWM输出实验

本实验为使用定时器做PWM输出的实验,配置参数与PWM的配置参数一致。

    //P0.3 will output pwm wave with period for 1000us and pulse for 500us 
    timer_init(QN_TIMER0, NULL);
    timer_pwm_config(QN_TIMER0, TIMER_PSCAL_DIV, TIMER_COUNT_US(1000, TIMER_PSCAL_DIV), TIMER_COUNT_US(500, TIMER_PSCAL_DIV));
    timer_enable(QN_TIMER0, MASK_ENABLE);
 
    //P1.1 will output pwm wave with period for 2000us and pulse for 1000us
    timer_init(QN_TIMER1, NULL);
    timer_pwm_config(QN_TIMER1, TIMER_PSCAL_DIV, TIMER_COUNT_US(2000, TIMER_PSCAL_DIV), TIMER_COUNT_US(1000, TIMER_PSCAL_DIV));
    timer_enable(QN_TIMER1, MASK_ENABLE);
 
    //P2.6 will output pwm wave with period for 4ms and pulse for 2ms
    timer_init(QN_TIMER2, NULL);
    timer_pwm_config(QN_TIMER2, 10, TIMER_COUNT_MS(4, 10),  TIMER_COUNT_MS(2, 10));
    timer_enable(QN_TIMER2, MASK_ENABLE);
 
    //P2.3 will output pwm wave with period for 6ms and pulse for 3ms
    timer_init(QN_TIMER3, NULL);
    timer_pwm_config(QN_TIMER3, 10, TIMER_COUNT_MS(6, 10),  TIMER_COUNT_MS(3, 10));
    timer_enable(QN_TIMER3, MASK_ENABLE);

定时器事件时间捕获实验

定时器捕获模式比较复杂,首先需要初始化TIMERx并且设置回调函数,以获取时间发生的时间。设置定时器为时间捕获模式INCAP_TIMER_MOD,此时,定时器会在P0.3的上升沿(下降沿,需要进入函数timer_capture_config中设置)产生中断并且计时,在之后每一个上升沿来临时,在回调函数中保存计时的值,并且开始新的计数。这样可以在回调函数中取出两个事件发生的时间间隔,适用于规律的发生时间。

    /*
     * Capture timer mode is to capture trigger event, and record the time-stamp.
     *
     * Make sure the macro TIMER0_CAP_MODE is INCAP_TIMER_MOD. 
     *
     * Timer0 will capture the P0.3 rising edge, and each rising edge will trigger 
     * the callback function, as the same time the counter value will transmit to 
     * timer0_env.count.
     * 
     * Other timers are similar to this.
     */
    timer_init(QN_TIMER0, timer0_callback);
    timer_capture_config(QN_TIMER0, INCAP_TIMER_MOD, 0, 0, 0);
    timer_enable(QN_TIMER0, MASK_ENABLE);

定时器事件计数捕获实验

该实验设置定时器为设置定时器为时间捕获模式INCAP_COUNTER_MOD,在每五次P0.3的上升沿发生后,产生中断并且记录计数值。

    /*
     * Capture event mode is to calculate the time of happened specified event with 
     * specified numbers.
     *
     * Make sure the macro TIMER0_CAP_MODE is INCAP_COUNTER_MOD. 
     *
     * Timer0 will count the time during 5 times rising edge of P0.3. After that, the 
     * callback function will be called, as the same time the time value will transmit to 
     * timer0_env.count.
     * 
     * Other timers are similar to this.
     */
    timer_init(QN_TIMER0, timer0_callback);
    timer_capture_config(QN_TIMER0, INCAP_COUNTER_MOD, 100, 0, 5);
    timer_enable(QN_TIMER0, MASK_ENABLE);

定时器捕获事件计数实验

该实验配置定时器为捕获事件计数模式INCAP_COUNTER_MOD,该模式下在1000ms内,对P0.3的上升沿进行计数,1000ms后触发中断,在回调函数中取出事件发生次数的值。

    /*
     * Capture conter mode is used to count the numbers of a special event during a specified period.
     * 
     * Make sure the macro TIMER0_CAP_MODE is INCAP_EVENT_MOD. 
     *
     * Timer0 will count the numbers of rising edge during 1000ms with P0.3, and each rising 
     * edge will trigger the callback function, as the same time the counter value will transmit 
     * to timer0_env.count.
     * 
     * Other timers are similar to this.
     */
    timer_init(QN_TIMER0, timer0_callback);
    timer_capture_config(QN_TIMER0, INCAP_EVENT_MOD, 100, TIMER_COUNT_MS(1000, 100), 0);
    timer_enable(QN_TIMER0, MASK_ENABLE);