研发之路第三条———定时器配置(NRF52832筋膜枪研发)

鄙人才疏学浅,如有看不入眼的代码,烦请各位指教。

既然已经配置了GPIO,那么不来一场有间隔的灯光闪烁,就不妥了。nrf有一些定时器的配置流程,也有具体的实例,坐标:nRF5_SDK_17.0.2_d674dde\examples\peripheral\timer。官方的演示可谓详细之极,一般来说按此配置即可。

/**
 * @brief Handler for timer events.
 */
void timer_led_event_handler(nrf_timer_event_t event_type, void* p_context)
{
    static uint32_t i;
    uint32_t led_to_invert = ((i++) % LEDS_NUMBER);

    switch (event_type)
    {
        case NRF_TIMER_EVENT_COMPARE0:
            bsp_board_led_invert(led_to_invert);
            break;

        default:
            //Do nothing.
            break;
    }
}


/**
 * @brief Function for main application entry.
 */
int main(void)
{
    uint32_t time_ms = 500; //Time(in miliseconds) between consecutive compare events.
    uint32_t time_ticks;
    uint32_t err_code = NRF_SUCCESS;

    //Configure all leds on board.
    bsp_board_init(BSP_INIT_LEDS);

    //Configure TIMER_LED for generating simple light effect - leds on board will invert his state one after the other.
    nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;
    err_code = nrf_drv_timer_init(&TIMER_LED, &timer_cfg, timer_led_event_handler);
    APP_ERROR_CHECK(err_code);

    time_ticks = nrf_drv_timer_ms_to_ticks(&TIMER_LED, time_ms);

    nrf_drv_timer_extended_compare(
         &TIMER_LED, NRF_TIMER_CC_CHANNEL0, time_ticks, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, true);

    nrf_drv_timer_enable(&TIMER_LED);

但是通过浏览驱动库,我们可以找到更简便的办法。坐标:nRF5_SDK_17.0.2_d674dde\components\libraries\timer。

于是,四大战神,出来!

sdk中的简单定时器配置

ret_code_t app_timer_create(app_timer_id_t const *      p_timer_id,
                            app_timer_mode_t            mode,
                            app_timer_timeout_handler_t timeout_handler)
{
    // Check state and parameters
    VERIFY_MODULE_INITIALIZED();

    if (timeout_handler == NULL)
    {
        return NRF_ERROR_INVALID_PARAM;
    }
    if (p_timer_id == NULL)
    {
        return NRF_ERROR_INVALID_PARAM;
    }
    if (((timer_node_t*)*p_timer_id)->is_running)
    {
        return NRF_ERROR_INVALID_STATE;
    }

    timer_node_t * p_node     = (timer_node_t *)*p_timer_id;
    p_node->is_running        = false;
    p_node->mode              = mode;
    p_node->p_timeout_handler = timeout_handler;
    return NRF_SUCCESS;
}

ret_code_t app_timer_start(app_timer_id_t timer_id, uint32_t timeout_ticks, void * p_context)
{
    uint32_t timeout_periodic;
    timer_node_t * p_node = (timer_node_t*)timer_id;

    // Check state and parameters
    VERIFY_MODULE_INITIALIZED();

    if (timer_id == 0)
    {
        return NRF_ERROR_INVALID_STATE;
    }
    if ((timeout_ticks < APP_TIMER_MIN_TIMEOUT_TICKS) || (timeout_ticks > MAX_RTC_COUNTER_VAL))
    {
        return NRF_ERROR_INVALID_PARAM;
    }
    if (p_node->p_timeout_handler == NULL)
    {
        return NRF_ERROR_INVALID_STATE;
    }

    // Schedule timer start operation
    timeout_periodic = (p_node->mode == APP_TIMER_MODE_REPEATED) ? timeout_ticks : 0;

    return timer_start_op_schedule(p_node,
                                   timeout_ticks,
                                   timeout_periodic,
                                   p_context);
}


ret_code_t app_timer_stop(app_timer_id_t timer_id)
{
    timer_node_t * p_node = (timer_node_t*)timer_id;
    // Check state and parameters
    VERIFY_MODULE_INITIALIZED();

    if ((timer_id == NULL) || (p_node->p_timeout_handler == NULL))
    {
        return NRF_ERROR_INVALID_STATE;
    }

    p_node->is_running = false;

    // Schedule timer stop operation
    return timer_stop_op_schedule(p_node, TIMER_USER_OP_TYPE_STOP);
}


ret_code_t app_timer_stop_all(void)
{
    // Check state
    VERIFY_MODULE_INITIALIZED();

    return timer_stop_op_schedule(NULL, TIMER_USER_OP_TYPE_STOP_ALL);
}

来的这四位,究竟是什么高手了?原来是四个很简单的函数,只需要创建名称和定时,简单的调用,平平无奇的语句,已知他们是程序猿的福祉了。

用这四句定时器配置,基本可以满足嵌入式软件所需的内容,不需要繁琐的init和声明。

如果只需要简单的定时器配置,按此要求即可,省去较多繁琐操作。

配置流程

1.首先我们需要新建一个定时器ID,没有什么特殊的,取一个你认得请的名字即可。APP_TIMER_DEF(ID);

/**
 * @brief Create a timer identifier and statically allocate memory for the timer.
 *
 * @param timer_id Name of the timer identifier variable that will be used to control the timer.
 */
#define APP_TIMER_DEF(timer_id) _APP_TIMER_DEF(timer_id)

2.接着,我们看模式如何选择:

/**@brief Timer modes. */
typedef enum
{
    APP_TIMER_MODE_SINGLE_SHOT,                 /**< The timer will expire only once. */
    APP_TIMER_MODE_REPEATED                     /**< The timer will restart each time it expires. */
} app_timer_mode_t;

第一个的意思是,这个定时器只会定时一次,结束后需要重新开启,而第二个则是定时结束后继续定时。

3.最后则是定时结束后触发的事件了。这个就看个人需求了

配置结果

APP_TIMER_DEF(one_time);
app_timer_create(one_time,APP_TIMER_MODE_SINGLE_SHOT,vendor_one_time_func);
APP_TIMER_DEF(more);
app_timer_create(more,APP_TIMER_MODE_REPEATED,vendor_more_func);

既然配置完成了,那么我们就可以用下面两个函数开始或者停止他们了。

void vendor_one_time_func(void * p_context)
{
	nrf_gpio_pin_toggle(10);
}

让这个定时器连接到按键事件中,按下按键后过300ms,将灯反转一次。

#define one_time_ms APP_TIMER_TICKS(300);
void vendor_onetime(void)
{
	app_timer_stop(one_time);
	app_timer_start(one_time,one_time_ms,vendor_one_time_func)
}

接下来就是烧录验证了。

另一种配置流程

#if 1
void Vendor_fgtimer_event_init(void)
{
	#if 1
    uint32_t time_ms = 1; //定时器比较时间
    uint32_t time_ticks;
    uint32_t err_code = NRF_SUCCESS;
    //配置定时器
    nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;
    err_code = nrf_drv_timer_init(&TIMER_FG, &timer_cfg, timer_sysclock_event_handler);
    APP_ERROR_CHECK(err_code);

    time_ticks = nrf_drv_timer_ms_to_ticks(&TIMER_FG, time_ms);
   //触发定时器比较
    nrf_drv_timer_extended_compare(
         &TIMER_FG, NRF_TIMER_CC_CHANNEL1, time_ticks, NRF_TIMER_SHORT_COMPARE1_CLEAR_MASK, true);
//	  nrf_drv_timer_extended_compare(
//         &TIMER_LED, NRF_TIMER_CC_CHANNEL0, 31250, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, true);
    //使能定时器
//   nrf_drv_timer_enable(&TIMER_FG);

    // Enable timer
    nrf_drv_timer_enable(&TIMER_FG);
	#else
	
		app_timer_create(&m_fg_1ms_cnt_timer_id, APP_TIMER_MODE_REPEATED, timer_sysclock_event_handler);
		app_timer_start(m_fg_1ms_cnt_timer_id, APP_TIMER_TICKS(1), NULL);		
	#endif
}
#endif

sdk.config.h中的配置

GPIO和UART也需要配置,之前忘了,在此补上。

再次提醒

先打开SDK.CONFIG.H中的配置,再烧录代码,如果鄙人有缺漏,请指出或询问清风。有需要讨论的也可咨询本人。

研发类型的需求和讨论,如有需要请联系鄙人。公司邮箱:zhongweixiong@kyohoon.com,联系电话:15507589165 钟先生

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值