外围可编程示例

⚠️
大家好. .感谢来到论坛。令人兴奋的消息!我们现在正在转移到新的论坛平台的过程中,它将提供更好的功能,并包含在主对话网站。所有的帖子和账号已经迁移。我们现在只接受新论坛的流量-请发布任何新的帖子在//www.xmece.com/support.我们会在接下来的几天修复bug /优化搜索和标记。
11个员额/ 0个新员额
最后发表
迈克尔12344
离线
最后一次见到:2年3个月前
加入:2019-01-29 23:17
外围可编程示例

你好,

我目前正在使用BLE外设示例的一个修改版本来尝试用ADC采样信号。我基本上已经用从ADC而不是计数器读取值的代码替换了adc_adcval1_timer_cb_handler中的代码。我遇到的问题是调用adc处理器函数的时间。我需要采样我的信号在2000Hz或2000采样每秒。当我试图获得计时器在10毫秒或以下时,我得到断开连接和platform_reset_func函数在调用adc处理器几次后被调用。我已经尝试了应用程序简单定时器的例子已经使用,我也尝试了使用timer0回调方法。两者似乎都有同样的问题。我想知道是否有一些限制因素与代码或软件本身的时间,我没有意识到?还有什么类型的事情导致调用platform_reset func?

谢谢

关键词:
设备:
CYibin
离线
最后一次见到:10个月3周前
工作人员
加入:2017-12-14 02:48
嗨,迈克尔,

嗨,迈克尔,

你能给我看一下你的源代码吗?

目前我可以确认的是,app_easy_timer API的时间单位是10ms,这在2Khz采样时是不合适的。

CYibin

迈克尔12344
离线
最后一次见到:2年3个月前
加入:2019-01-29 23:17
我理解app_easy

我理解app_easy_timer不会让我到达2Khz采样。然而,即使当我使用app easy定时器的最低可能的时间单位10毫秒也不起作用。下面是使用app_easy_timer编辑的部分。当APP_PERIPHERAL_CTRL_TIMER_DELAY设置为2个时间单位时,它工作得很好,但在使用1后不久断开连接。

#define APP_PERIPHERAL_CTRL_TIMER_DELAY (1) void user_svc1_ctrl_wr_ind_handler(ke_msg_id_t const msgid, struct custs1_val_write_ind const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) {uint8_t val = 0;memcpy (val,参数[0]- >值,参数- >长度);if (val != CUSTS1_CP_ADC_VAL1_DISABLE) {adc_init(GP_ADC_SE, GP_ADC_SIGN, GP_ADC_ATTN3X);adc_usDelay (20);adc_enable_channel (ADC_CHANNEL_P00);timer_used = app_easy_timer (APP_PERIPHERAL_CTRL_TIMER_DELAY app_adcval1_timer_cb_handler);} else {adc_disable();if (timer_used != EASY_TIMER_INVALID_TIMER) {app_easy_timer_cancel(timer_used);timer_used = EASY_TIMER_INVALID_TIMER;}} void app_adcval1_timer_cb_handler() {struct custs1_val_ntf_ind_req *req = KE_MSG_ALLOC_DYN(CUSTS1_VAL_NTF_REQ, prf_get_task_from_id(TASK_ID_CUSTS1), TASK_APP, custs1_val_ntf_ind_req, DEF_SVC1_ADC_VAL_1_CHAR_LEN); // ADC value to be sampled static uint16_t sample __attribute__((section("retention_mem_area0"), zero_init)); sample = adc_get_sample(); //req->conhdl = app_env->conhdl; req->handle = SVC1_IDX_ADC_VAL_1_VAL; req->length = DEF_SVC1_ADC_VAL_1_CHAR_LEN; req->notification = true; memcpy(req->value, &sample, DEF_SVC1_ADC_VAL_1_CHAR_LEN); ke_msg_send(req); if (ke_state_get(TASK_APP) == APP_CONNECTED) { // Set it once again until Stop command is received in Control Characteristic timer_used = app_easy_timer(APP_PERIPHERAL_CTRL_TIMER_DELAY, app_adcval1_timer_cb_handler); } }

这里是使用timer0而不是app_easy_timer编辑的部分,它应该能够更快地采样2Khz。但是,当timer0设置为或低于10ms的间隔时,我得到的断开连接和调用platform_reset_func与使用app_easy_timer时相同。这里的间隔设置为20ms,工作正常。但是,如果要更改例如,重新加载到1000(5ms),它将断开连接并调用platform_reset_func。在这两个示例中,用户_cust1_impl.c的其余部分是相同的。

#define no_pwm 0x0 #define重新加载4000 void user_svc1_ctrl_wr_ind_handler(ke_msg_handler(ke_msg_hand_t const msgs,struct custs1_val_write_ind const * param,ke_task_id_t const dest_id,ke_task_id_t const src_id){uint8_t val = 0;memcpy (val,参数[0]- >值,参数- >长度);if (val != CUSTS1_CP_ADC_VAL1_DISABLE) {adc_init(GP_ADC_SE, GP_ADC_SIGN, GP_ADC_ATTN3X);adc_usDelay (20);adc_enable_channel (ADC_CHANNEL_P00);timer0_stop();timer0_register_callback(app_adcval1_timer_cb_handler);set_tmr_enable(clk_per_reg_tmr_enabled);set_tmr_div(clk_per_reg_tmr_div_8);timer0_set_pwm_high_counter(no_pwm); timer0_set_pwm_low_counter(NO_PWM); timer0_init(TIM0_CLK_FAST, PWM_MODE_ONE, TIM0_CLK_DIV_BY_10); timer0_set_pwm_on_counter(RELOAD); // Enable SWTIM_IRQn irq timer0_enable_irq(); // Start Timer0 timer0_start(); } else { set_tmr_enable(CLK_PER_REG_TMR_DISABLED); adc_disable(); } } void app_adcval1_timer_cb_handler() { struct custs1_val_ntf_ind_req *req = KE_MSG_ALLOC_DYN(CUSTS1_VAL_NTF_REQ, prf_get_task_from_id(TASK_ID_CUSTS1), TASK_APP, custs1_val_ntf_ind_req, DEF_SVC1_ADC_VAL_1_CHAR_LEN); // ADC value to be sampled static uint16_t sample __attribute__((section("retention_mem_area0"), zero_init)); sample = adc_get_sample(); //req->conhdl = app_env->conhdl; req->handle = SVC1_IDX_ADC_VAL_1_VAL; req->length = DEF_SVC1_ADC_VAL_1_CHAR_LEN; req->notification = true; memcpy(req->value, &sample, DEF_SVC1_ADC_VAL_1_CHAR_LEN); ke_msg_send(req); }

谢谢

迈克尔12344
离线
最后一次见到:2年3个月前
加入:2019-01-29 23:17
只是为了避免

为了避免误解,该项目的其他部分在user_custs_impl文件之外是SDK中的外围蓝牙低能耗示例。

CYibin
离线
最后一次见到:10个月3周前
工作人员
加入:2017-12-14 02:48
你好,michael12344,

你好,michael12344,

将断开连接的原因是发送给SDK配置文件的通知命令太过频繁。

您应该首先存储ADC采样产生的数据,然后以较低的频率发送它们。

CYibin

迈克尔12344
离线
最后一次见到:2年3个月前
加入:2019-01-29 23:17
你好,

你好,

有什么办法可以解决这个问题吗?如果数据可以连续流出,而不是收集所有样本然后发送数据,那就更理想了。有没有其他发送/接收数据的方法更好,或者可以像我希望的那样频繁或接近频繁地发送/接收数据?

谢谢

PM_对话框
离线
最后一次见到:4天21小时前
工作人员
加入:2018-02-08 11:03
你好,michael12344,

你好,michael12344,

t平台重置函数(),由平台重置函数()调用,是一个由ROM代码实现的函数。获得此断言的最可能原因是内存不足,因为您可能会尝试分配从不使用的消息。例如,如果您正在分配通知消息,并且连接间隔很小,则消息会堆积到连接结束之前nt到达,但连接间隔很长,在连接事件到达之前内存不足。您使用的连接间隔是什么?

谢谢,下午好

迈克尔12344
离线
最后一次见到:2年3个月前
加入:2019-01-29 23:17
你好,

你好,

连接间隔是在外围设备还是在中央设备上设置的?我在user_peripal.c和user_config.c中发现,似乎将最小和最大连接间隔设置为10ms到20ms。

无效用户应用程序连接(uint8\u t connection\u idx,struct gapc\u connection\u req\u ind const*param){if(应用程序环境[connection\u idx].conidx!=GAP\u INVALID\u conidx){app\u connection\u idx=connection\u idx;//停止广告数据更新定时器应用程序\u轻松定时器\u取消(使用了应用程序数据更新定时器);//检查已建立连接的参数是否为首选参数//如果不是,则计划一个连接参数更新请求。如果((参数->控制间隔<用户连接参数配置Intvmin);(参数->控制间隔>用户连接参数配置Intvmax);(参数->控制延迟!=用户连接参数配置延迟)(param->sup_to!=user_connection_param_conf.time_out)){//连接参数不是我们期望的app_param_update_request_timer_used=app_easy_timer(app_param_update_request_request_timer_to,param_update_timer_cb)}否则{//没有建立连接,重新启动广告用户app_adv_start()}默认的app_on_连接(连接_idx,param);}
static const struct connection_param_configuration user_connection_param_conf={///在ble双插槽中测量的最小连接间隔(1.25ms)///使用宏MS_TO_DOUBLESLOTS将毫秒(MS)转换为双插槽。intv_min=MS_TO_DOUBLESLOTS(10),///在ble双插槽中测量的最大连接间隔(1.25ms)///使用宏MS_TO_DOUBLESLOTS将毫秒(MS)转换为双插槽。intv_max=MS_TO_DOUBLESLOTS(20),///在连接事件中测量的延迟。延迟=0,///以计时器单位(10毫秒)测量的监控超时///使用宏MS_TO_TIMERUNITS将毫秒(MS)转换为计时器单位。time_out=MS_转换为计时器单位(1250),///在ble双插槽中测量的最小连接事件持续时间(1.25ms)///使用宏MS_TO_DOUBLESLOTS将毫秒(MS)转换为双插槽。ce_len_min=MS_TO_DOUBLESLOTS(0),///在ble双插槽中测量的最大连接事件持续时间(1.25ms)///使用宏MS_TO_DOUBLESLOTS将毫秒转换为毫秒(ms)到双插槽。ce_len_max=ms_到_双插槽(0),};

PM_对话框
离线
最后一次见到:4天21小时前
工作人员
加入:2018-02-08 11:03
你好,michael12344,

你好,michael12344,

请将连接间隔(.intv_min和.intv_max)改大一点好吗?

谢谢,下午好

迈克尔12344
离线
最后一次见到:2年3个月前
加入:2019-01-29 23:17
你好,

你好,

我尝试将intv_min和intv_max改为更大的值30-45ms和100-160ms。然而,由于仍然调用platform_reset_func(),这个问题似乎仍然存在。还有什么方法可以提高数据吞吐量吗?

PM_对话框
离线
最后一次见到:4天21小时前
工作人员
加入:2018-02-08 11:03
你好,michael12344,

你好,michael12344,

在您的应用程序中,可能会在每次连接后出现某种内存泄漏堆积。当wrap_platform_reset()发生时,请确保错误代码是RESET_MEM_ALLOC_FAIL,为了找到它,您必须调试它。此外,检查在ADC读取期间是否发送了任何挂起的消息,并确保正在使用在处理消息时获得的消息,或者正在分配应该释放它们的数据。例如,如果你取样ADC,你分配消息,以便在有一个连接时通过通知发送数据,设备最终将耗尽内存,如果设备耗尽内存,这将导致设备重置。尝试从da1458x_config_advanced定义并增加DB_HEAP_SZ,例如,您可以将值设置为2048。

谢谢,下午好