Hi3861的micropython移植之Timer 原创 精华

再见南丫岛
发布于 2022-3-13 22:26
浏览
1收藏

1、移植的准备

Timer主要用于定时触发事件使用。移植相对容易。需要#include "hi_timer.h"中的相关函数。

2、machine_timer_obj_t定义

typedef struct _machine_timer_obj_t {
    mp_obj_base_t base;
    mp_obj_t timeout_cb;
    uint32_t mode;
    uint32_t period;
    hi_u32 g_timer_handle;  
    struct _machine_timer_obj_t *next;
} machine_timer_obj_t;

定义hi_u32 g_timer_handle用于存储定时器handle

3、创建Timer定时器

STATIC mp_obj_t machine_timer_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
    machine_timer_obj_t *self = m_new_obj(machine_timer_obj_t);
    self->base.type = &machine_timer_type;
    hi_u32 ret;
    ret = hi_timer_create(&self->g_timer_handle);
    if (ret != HI_ERR_SUCCESS) {
        mp_raise_ValueError("timer create fail");
    }
    // Add the timer to the linked-list of timers
    self->next = MP_STATE_PORT(machine_timer_obj_head);
    MP_STATE_PORT(machine_timer_obj_head) = self;
    return MP_OBJ_FROM_PTR(self);
}

4、开启定时器

STATIC mp_obj_t machine_timer_start(mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
    machine_timer_obj_t *self = (machine_timer_obj_t *)args[0];
    int mode = 0;

    enum {
        ARG_mode,
        ARG_period,
        ARG_callback,
    };
    static const mp_arg_t allowed_args[] = {
        { MP_QSTR_mode,         MP_ARG_INT, {.u_int = 0} },
        { MP_QSTR_period,       MP_ARG_INT, {.u_int = 0xffffffff} },
        { MP_QSTR_callback,     MP_ARG_OBJ, {.u_obj = mp_const_none} },
    };

    mp_arg_val_t dargs[MP_ARRAY_SIZE(allowed_args)];
    mp_arg_parse_all(n_args - 1, args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, dargs);
    
    if (4 == n_args) {
        self->mode = dargs[ARG_mode].u_int;
        self->period = dargs[ARG_period].u_int;
        self->timeout_cb = dargs[ARG_callback].u_obj;
    } else {
        mp_raise_ValueError("invalid format");
    }

    error_check(self->period > 0, "Set timeout value error");

    int res = hi_timer_start(self->g_timer_handle,self->mode,self->period,timer_event_handler,(void*)self);
    if (res != HI_ERR_SUCCESS) {
        mp_raise_ValueError("timer start fail");
    }
    return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_timer_start_obj, 1, machine_timer_start);

5、关闭定时器

STATIC mp_obj_t machine_timer_stop(mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
    machine_timer_obj_t *self = (machine_timer_obj_t *)args[0];
    int ret = hi_timer_stop(self->g_timer_handle);
    if (ret != HI_ERR_SUCCESS) {
        mp_raise_ValueError("timer stop fail");
    }
}
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_timer_stop_obj, 1, machine_timer_stop);

6、定时器的回调

STATIC void timer_event_handler(void *arg) {
    machine_timer_obj_t *self = arg;
    //printf("machine_pin_isr_handler = %d\r\n",self->pin);
    mp_sched_schedule(self->timeout_cb, MP_OBJ_FROM_PTR(self));
}

回调的使用和Pin的类似。

7、python的使用


from machine import Timer
import time

def callback_periodic(obj): # defined  preiodic mode timeout callback
    print("Timer callback periodic test")

def callback_oneshot(obj): # defined  ont shot mode timeout callback
    print("Timer callback oneshot test")

print("start")

timer = Timer() # Create Timer object, driver support timer1/timer2/timer3
timer.start(timer.PERIODIC, 1000, callback_periodic) # Initialize the Timer device object
# Set Timer mode to preiodic mode, set timeout to 1 seconds and set callback fucntion
time.sleep(5)# Execute 5 times timeout callback in the delay time
timer.start(timer.ONE_SHOT, 1000, callback_oneshot) # Reset initialize the Timer device object
# Set Timer mode to one shot mode, set timeout to 1 seconds and set callback fucntion
time.sleep(5) # Execute 1 times timeout callback in the delay time
timer.deinit()  # Stop and close Timer device object

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
4
收藏 1
回复
举报
1条回复
按时间正序
/
按时间倒序
千云山庄
千云山庄

太赞了,功德无量

回复
2022-3-15 14:58:10
回复
    相关推荐