嗨,支持,
我的程序大概的逻辑是外挂ADC每4 ms采一次数据,采集完毕后通过中断告诉14580单片机,单片机开辟一个环形缓冲区来存储ADC的结果,当有5个结果时启动数据发送(通知),数据大小20字节,即每20女士有一包包要发送,发送前先检查GATTC_CMP_EVT的到来,连接间隔设置为10-20ms,实际测试发现,当连接后不发数据的时候,连接时间间隔为规律的18女士(大概),当启动通知时,连接间隔有时为18女士,有时为36女士,有时为54女士,每个连接间隔发送的包也不同,有时1包,有2包时,有时3、4包,这很不科学,连接时间间隔应该是不受任何因素影响的,为什么示波器抓出来的波型显示是这个结果吗?
下面是部分代码:
1.
enum arch_main_loop_callback_ret user_app_on_ble_powered(空白)
{
if(ptr_in != ptr_out) //如果有数据残留在循环数据缓冲区,然后唤醒BLE通知
{
返回KEEP_POWERED;
}
返回GOTO_SLEEP;
}
2.
enum arch_main_loop_callback_ret user_app_on_sytem_powered(空白)
{
uint8_t tempdata [2];
int qrsdata_in;
If (adc_int_is_set) //adc采样完成
{
ads1115_get_adc_result (tempdata);
DATA_FIFO[ptr_in][ADC_VALUE_SIZE * (1+cycle_num)] = tempdata[0];//将adc采样结果存储在环形数据缓冲区中
DATA_FIFO[ptr_in][ADC_VALUE_SIZE * (1+cycle_num)+ 1] = tempdata[1];//将adc采样结果存储在环形数据缓冲区中
cycle_num + +;
if(cycle_num == cycle_num) // cycle_num = 5
{
DATA_FIFO [ptr_in] [0] = (uint8_t)(计数器/ 256);/ /高字节
DATA_FIFO [ptr_in] [1] = (uint8_t)(计数器% 256);/ /低字节
如果(counter = = 0 xffff)
{
counter = 0;
国旗= true;
}
计数器+ +;
If (flag) {counter = 0;国旗= false;}
cycle_num = 0;
ptr_in + +;
if(ptr_in = PACKET_NUMBER) ptr_in = 0; / / ptr_in = 0
adc_int_is_set = false;
返回KEEP_POWERED;//需要通知数据
}
adc_int_is_set = false;
}
返回GOTO_SLEEP;//不需要通知数据
}
3.
Static const struct arch_main_loop_callbacks user_app_main_loop_callbacks = {
.app_on_init = user_app_init,
.app_on_ble_powered = user_app_on_ble_powered,
.app_on_sytem_powered = user_app_on_sytem_powered,
.app_before_sleep =零,
.app_validate_sleep =零,
.app_going_to_sleep =零,
.app_resume_from_sleep =零,
};
4 .数据发送函数,先检查TX_IS_COMPLETED标志
uint8_t data_send_process(空白)
{
如果(! TX_IS_COMPLETED)返回0;//前一个通知已完成
data_to_notify (DATA_FIFO ptr_out, PACKET_SIZE);/ /数据传输
ptr_out + +;
if(ptr_out >= PACKET_NUMBER) ptr_out = 0;
TX_IS_COMPLETED = false;//清除TX_COMPLETE标志
返回0;
}
5. data_send_process()在bie的时候调用
静态内联void schedule_while_ble_on(void)
{
//开启BLE时钟
而(ble_is_powered ()) {
//设置BLE事件结束。有条件的射频校准可以运行。
uint8_t ble_end_set = ke_event_get(KE_EVENT_BLE_EVT_END);
//执行消息和事件
rwip_schedule ();
//
如果(ble_evt_end_set)
{
Uint32_t sleep_duration = 0;
rcx20_read_freq ();
//如果你有足够的时间,对收音机进行温度校准
如果(lld_sleep_check(&sleep_duration, 4)) //6个槽-> 3.750 ms . If (lld_sleep_check(&sleep_duration, 4)
//检查时间和温度以进行无线电校准。
conditionally_run_radio_cals ();
}
//将控制权授予应用程序,尝试进入睡眠
//如果应用程序返回GOTO_SLEEP
如果(! app_asynch_trm ())
打破;
/ / SDKIMPROVEMENTS需要测试! !我们可以添加以下条件,然后移动
//退出循环
//我们可以考虑把它放在app_asynch_trm之前
/ /如果(GetBits16 (CLK_CTRL_REG RUNNING_AT_XTAL16M))
//执行printf进程
arch_printf_process ();
data_send_process ();
}
}
6.TX_IS_COMPLETED置位,当上一包数据发送完毕的时候
Void user_catch_rest_hndl(ke_msg_id_t const msgid,
空白const *参数,
ke_task_id_t const dest_id,
ke_task_id_t const src_id)
{
开关(是否)
{
案例CUSTS1_VAL_NTF_CFM:
{
Struct custs1_val_ntf_cfm const *msg_param = (Struct custs1_val_ntf_cfm const *)(param);
开关(msg_param - >处理)
{
案例ECG_IDX_DATA_VAL:
TX_IS_COMPLETED = true;//设置前一个数据包是否完全传输
打破;
默认值:
打破;
}
}打破;
默认值:
打破;
}
}
环境:
SDK5.0.3
测试手机:iphone6及三星s6
BR,
年轻的
1 .你可以参考一下,SDK3.0.10里的吞吐量工程。
2.我的建议是在enum arch_main_loop_callback_ret user_app_on_sytem_powered (void)里面只在收到中断的时候,发送消息出去,别的不用做。
在消息处理函数里的面,拿ADC的值之前,调用一下arch_force_active_mode函数,然后存储数据到队列。收满5个,直接通知出去。
另外,你可以参考吞吐量工程里的streamdatad_send_data_packets_req_handler函数写法,直接去检查l2CAP的队列,这样会比你通过通知返回值再决定是否继续发要快。
嗨Gongyu_Dialog,
补充:在连接上之后我就调用了arch_disable_sleep()使系统进入闲置状态,因为如果不醒着的话,恐怕处理不过来这么大的数据量吧,另外你说的消息处理函数是指“data_send_process ()“还”是“arch_main_loop_callback_ret user_app_on_ble_powered(),这两个函数是BLE醒了之后才会去执行,但是我的数据每4就女士要存储一次,放在这里处理不妥吧,会严重地丢数据!
BR,
年轻的
1.adc_int_is_set是通过之后的中断函数设置的,还是GPIO的中断函数?
2.ads1115_get_adc_result这个函数会有多大的耗时?
3.“在连接上之后我就调用了arch_disable_sleep()使系统进入闲置状态”,/ /现在你设置的不进延长睡眠的?
4.你可以评估一下你平均发出去一组包的耗时,可以用rwble_get_clock函数,一头一尾来计算差值,得到耗时。单位625。
消息处理函数是另加的,做的事情和你的user_app_on_sytem_powered差不多。只不过再加判断,条件满足直接发通知。读取ADC值,放数,收满5个包直接出发通知去)。只要有任务消息没被处理,祝福芯片就不会睡。
嗨Gongyu_Dialog,
3.连接上之后设置为不进延长睡眠的模式;
1 .由于ADC采样是在连接上之后才执行的,所以其中断标志adc_int_is_set是由普通GPIO的中断产生而置位的;
其它的我需要做个测试才能得知,谢谢!
BR,
年轻的
简单说来,就是
.app_on_ble_powered = user_app_on_ble_powered / /收到异步中断后,直接发出消息
.app_on_sytem_powered = user_app_on_sytem_powered / /处理消息,写缓冲区,决定是否要发notificatiion消息
那真正的通知数据的函数要放在哪里,要在哪里发数据呢?
我有点混乱了,你较早前说过:
“enum arch_main_loop_callback_ret user_app_on_sytem_powered (void)里面只在收到中断的时候,发送消息出去,别的不用做”
现在又说:
”。app_on_sytem_powered = user_app_on_sytem_powered / /处理消息,写缓冲区,决定是否要发notificatiion消息”
究竟是要怎样,你再重新帮我捋顺下顺序,谢谢!
BR,
年轻的
之前写错了函数名~~~
app_on_ble_powered里检查中断标记,然后发消息通知采集数据
app_on_system_powered里处理消息,写缓冲区,在这里发通知
嗨Gongyu_Dialog,
按照你的方法试了下,结果还是一样的,连接间隔还是会变化。还有其它建议么?
BR,
年轻的
补充:
app_on_ble_powered跟app_on_system_powered两个返回要怎么处理,刚才的测试都是返回GOTO_SLEEP,望知悉,谢谢!