QN902X在KEIL中使用定时器中断流程记录

仅以此篇,记录蓝牙BLE(QN902x)开发过程中,使用ke_timer_set ((p_ke_timer_set)(_ke_timer_set))的流程;

首先,我们要使用这个函数,必须先了解它能干什么,需要什么条件才能使用

第一步:找到函数原型(盘它)

/**
 ****************************************************************************************
 * @brief Set a timer.
 *
 * The function first cancel the timer if it is already existing, then
 * it creates a new one. The timer can be one-shot or periodic, i.e. it
 * will be automatically set again after each trigger.
 * 这个函数首先取消已经存在的定时器,然后创建一个新的。定时器可以是一次性的,也可以是周期性的,也就 
 * 是说每次触发后会自动设置一次
 * When the timer expires, a message is sent to the task provided as
 * argument, with the timer id as message id.
 * 当计时器到期时,一个消息被发送到任务提供的参数,与计时器id作为消息id
 * The timer is programmed in time units (TU is 10ms).
 * 定时器编程的时间单位(TU是10ms)
 * @param[in] timer_id      Timer identifier (message identifier type).
 * @param[in] task_id       Task identifier which will be notified
 * @param[in] delay         Delay in time units.
 ****************************************************************************************
 */
typedef void (*p_ke_timer_set)(ke_msg_id_t const timer_id, ke_task_id_t const task, uint16_t const delay);

使用示例:ke_timer_set(DEVICE_TIMER,TASK_APP,1);

从上面的示例中,可以分析出使用这个函数需要一个ID参数(上面定义中的参数原型是:ke_msg_id_t const timer_id),一个TASK参数,一个延时时间参数(这个时间代表的是  从此处开始,延时这个时间后执行这个函数里面的代码!)

第二步:定义应用程序消息接口

何为应用程序消息接口?

根据蓝牙BLE特有的性质,这个应用程序消息接口也就是消息ID(示例中的第一个参数:DEVICE_TIMER),有了这个ID,就能找到ID对应的定时器响应函数;所以接下来我们要去定义这个ID以及它对应的响应函数了。

如何定义这个ID?

进入app_task.h这个文件里:

/// App Message Interface 应用程序消息接口
enum
{
    /// Debug UART received data
    APP_SYS_UART_DATA_IND = KE_FIRST_MSG(TASK_APP),
    APP_ADV_INTV_UPDATE_TIMER,
    APP_SYS_RCO_CAL_TIMER,
    APP_SYS_32K_XTAL_WAKEUP_TIMER,

    APP_SYS_TIME_CHECK_TIMER,
    //add by john for krait
#if  (defined(KRAIT_9021_EVB)||defined(KRAIT_9020_EVT))
    APP_KBS_SEND_DATA_DELAY_TIMER,
    APP_KBS_BLE_CONN_WAIT_TIMER,

    KRAIT_TIMEOUT_TIMER,
		RESTART_OV788,
		UVC_START,
		TEST_TIMEOUT_TIMER,
#ifdef OV_DELAY_TIMER
    KRAIT_OV_DELAY_TIMER,
#endif
#endif	
    APP_HTPT_PERIOD_MEAS_TIMER,
    APP_HTPT_IDLE_CONNECTION_TIMEOUT_TIMER,

    APP_PROXR_ALERT_STOP_TIMER,
    APP_BLPS_PRESSURE_TIMER,
    APP_HRPS_TIMER,
    APP_TIPS_CURRENT_TIME_TIMER,
    APP_SCPPS_SCAN_REFRESH_TIMER,
    APP_BASS_BATT_LEVEL_TIMER,
    APP_GLPS_MEAS_SEND_TIMER,
    APP_RSCPS_MEAS_SEND_TIMER,
    APP_CSCPS_MEAS_SEND_TIMER,
    APP_PASPS_UPDATE_ALERT_STATUS_TIMER,
    APP_PASPS_UPDATE_RINGER_TIMER,

    APP_HOGPD_BOOT_KB_IN_REPORT_TIMER,
    APP_HOGPD_BOOT_MOUSE_IN_REPORT_TIMER,
    APP_HOGPD_REPORT_TIMER,
    APP_MSG_MAX,
		YUNQI_THREAD_1_TIMER,
		YUNQI_THREAD_2_TIMER,
		YUNQI_THREAD_3_TIMER,
		YUNQI_THREAD_4_TIMER,
		YUNQI_THREAD_5_TIMER,
		YUNQI_AUDIO_TIMER,
//designed by self
		DEVICE_TIMER,
};

在这个枚举里面添加自己定义的ID,我这里定义的是DEVICE_TIMER,就是设备定时器的意思。

现在定义好了ID,如何添加这个ID对应的中断响应函数呢?

第三步:添加ID对应的中断响应函数

进入app_task.c这个文件里:

/* default State handlers definition. 默认状态处理程序定义*/
const struct ke_msg_handler app_default_state[] =
{
    xxxx
    .
    .
    .
    .
    .
    .
    #if BLE_QPP_SERVER
    {QPPS_DISABLE_IND,                  	(ke_msg_func_t) app_qpps_disable_ind_handler},
    {QPPS_ERROR_IND,                    	(ke_msg_func_t) app_qpps_error_ind_handler},
    {QPPS_DATA_SEND_CFM,                	(ke_msg_func_t) app_qpps_data_send_cfm_handler},
    {QPPS_CFG_INDNTF_IND,               	(ke_msg_func_t) app_qpps_cfg_indntf_ind_handler},
    {QPPS_DAVA_VAL_IND,         	        (ke_msg_func_t) app_qpps_data_ind_handler},
    {QPPS_CREATE_DB_CFM,                	(ke_msg_func_t) app_qpps_create_db_cfm_handler},
	//Task_DIY
	{DEVICE_TIMER,							(ke_msg_func_t) motor_timer_handler},
#endif
    xxxx
    .
    .
    .
    .
    .
    .
};

在const struct ke_msg_handler app_default_state[] 这个数组中添加以下数据:

        数据格式:{    ID    ,    ID对应的响应函数    }

参考上述格式写出我们ID对应的响应函数,此处我编写的代码如下:

{DEVICE_TIMER,                            (ke_msg_func_t) motor_timer_handler},

到这一步了,应该知道如果我们执行了语句ke_timer_set(DEVICE_TIMER,TASK_APP,1);

我们的程序就会在10ms后调用motor_timer_handler()这个中断响应函数,具体响应函数怎么编写,就可以根据实际的需求而定了

第四步:编写定时器中断响应函数

int motor_timer_handler(ke_msg_id_t const msgid, void const *param,
                ke_task_id_t const dest_id, ke_task_id_t const src_id)
{
	/*
    需要实现的功能代码
    */
  
  //在响应函数中重复调用ke_timer_set(DEVICE_TIMER,TASK_APP,1)语句,是为了实现每10ms执行一次此函数,你也可以删除此语句,那么程序会执行一次就退出
  ke_timer_set(DEVICE_TIMER,TASK_APP,1);//10ms后调用

  return (KE_MSG_CONSUMED);//这一步是为了释放定时器资源
}

至此,QN902x的蓝牙定时器中断功能就可以愉快的使用了。

#include #include //自定义头文件,KeyScan用于键盘扫描。 #include //用于I2C总线。 #define uchar unsigned char #define uint unsigned int unsigned char b[7]={50,58,9,1,15,6,15},clock1[2]={0,12},clock2[2]={0,0}; //b[7]的元素含义:秒,分,时,星期,日,月,年 clock的元素含义:分,时。 code unsigned char tab[11]={0x03,0xf3,0x25,0x0d,0x99,0x49,0x41,0x1f,0x01,0x09,0x00}; //数码管0-9的编码列表,0x00点亮全部管。 code unsigned char tab2[2]={0x6d,0xff}; //ox6d: 表示三横图标。 unsigned char time[7]; //时间设置函数的参数。 void delay(unsigned int cnt); //延时函数声明。 unsigned char getkey1(); //unsigned char getkey2(); //读键盘函数声明。 void tim(void); //中断函数声明。 void KeyDelay(unsigned int KeyJsTime); //键盘扫描延时函数声明。 void display(uchar bit7,uchar bit6,uchar bit5,uchar bit4, uchar bit3,uchar bit2,uchar bit1,uchar bit0); //数码管显示函数。 void ReadTime(unsigned char TIME[7]); //DS1307读时间函数。 void SetTime(unsigned char TIME[7]); //设置时间初值函数。 void SwitchRTC(unsigned char SWITCH); //时间修改的使能函数:SWITCH=1禁止修改时间,SWITCH=0可以修改时间。 uchar dis_num_h; //显示记录数据的组别十位 uchar dis_num_l; //显示记录数据的组别个位 uchar dis_min_h; //要显示的分的十位; uchar dis_min_l; //要显示的分的个位; uchar dis_sec_h; //要显示的秒的十位; uchar dis_sec_l; //要显示的秒的个位; uchar dis_dsec; //要显示的0.1秒; uchar min=0x00; //防止意外,赋初值。分······· uchar sec=0x00; //秒 uchar dsec=0x00; //十分之一秒。 uchar en,i,clocken1=0,clocken2=0; main() { unsigned char quzhi,xianshi,symbol=0x55,set,set1=0x55,ce; unsigned char c[30]; unsigned char num,num1,j,k,stop=1; //注意stop必须先赋初值1。 PLLCON&=0xf8; //设置频率为12.582912MHz TMOD=0x01; //选定定时器及其工作模式。 TH0=0xce; //赋初值:52736,则总共的计数次数为:65536-52736=12800,即12.8毫秒。 TL0=0x00; IE=0x82; //中断控制,10000010,EA=1开总中断,ET0=1:定时器0中断允许。0x82:1000 0010 I2CCON=0xE8; //开启I2C总线通信,具体含义参阅ADuC848英文版说明资料。 SetTime(b); //设定初始时间。 SwitchRTC(1); //调用时间保持函数。 while(1) //设置死循环,实现循环执行。 { ReadTime(time); //调用读时间函数,读取当前的时间,并保留在time数组。 if(((clock1[0]==time[1])&&(clock1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值