注册官网,青岛网站关键词优化公司,做网站设计公司价格,宁夏网站推广因为业务需要, 需要在52832上, 采集3个pin的电压. 52832的ADC, 分为什么single, 连续, 扫描模式 single就是只有一个通道并采集一次, 连续就是不停的扫描, 如果要捕捉声音之类, 就配合DMA, 连续不停的采集, 转换就行了. 扫描模式就是如果是多通道, 就一开始初始化多个通道, 存放…因为业务需要, 需要在52832上, 采集3个pin的电压. 52832的ADC, 分为什么single, 连续, 扫描模式 single就是只有一个通道并采集一次, 连续就是不停的扫描, 如果要捕捉声音之类, 就配合DMA, 连续不停的采集, 转换就行了. 扫描模式就是如果是多通道, 就一开始初始化多个通道, 存放数据的数组, 以及采样次数, 然后全扫, 扫完回调中去拿数据即可.
初始化:
// 初始化SAADC配置使用的SAADC通道的参数和缓存
void saadc_3c_init(void) {ret_code_t err_code;// 使用NRF_SAADC_INPUT_AIN7通道即P0.31引脚, 生成一个通道配置结构体nrf_saadc_channel_config_t channel_config NRFX_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN7);err_code nrf_drv_saadc_init(NULL, saadc_callback);APP_ERROR_CHECK(err_code);// 初始化ADC通道0err_code nrfx_saadc_channel_init(0, channel_config);APP_ERROR_CHECK(err_code);// 为NRF_SAADC_INPUT_AIN5, 初始化ADC 通道1channel_config.pin_p NRF_SAADC_INPUT_AIN5;err_code nrfx_saadc_channel_init(1, channel_config);// 为NRF_SAADC_INPUT_AIN6, 初始化ADC 通道2APP_ERROR_CHECK(err_code);channel_config.pin_p NRF_SAADC_INPUT_AIN6;err_code nrfx_saadc_channel_init(2, channel_config);APP_ERROR_CHECK(err_code);// 双缓存模式err_code nrfx_saadc_buffer_convert(m_buffer_pool[0], ADC_SAMPLES_BUFFER_LEN);APP_ERROR_CHECK(err_code);err_code nrfx_saadc_buffer_convert(m_buffer_pool[1], ADC_SAMPLES_BUFFER_LEN);APP_ERROR_CHECK(err_code);}
这里使用的是双缓存模式, 采样的数据量为ADC_SAMPLES_BUFFER_LEN, 因为是3个通道, 所以采样3次就行了, 或者你喜欢浪费时间, 采样3的倍数也可以,如果不是3的倍数, 就会出现数据错位.
注册的回调时saadc_callback 这里使用的是非阻塞模式, 因为毕竟有蓝牙, 你阻塞好像不是那么回事. // SAADC事件回调函数只有一个缓存填满后才会进入事件回调函数
static void saadc_callback(nrfx_saadc_evt_t const *p_event) {float val; // 保存SAADC采样数据计算的实际电压值if (p_event-type NRFX_SAADC_EVT_DONE) {ret_code_t err_code;// 设置好缓存为下一次采样准备err_code nrfx_saadc_buffer_convert(p_event-data.done.p_buffer, ADC_SAMPLES_BUFFER_LEN);APP_ERROR_CHECK(err_code);int i;// 串口输出ADC采样值。// NRF_LOG_INFO(ADC event number: %d \n, (int) m_adc_evt_counter);for (i 0; i ADC_SAMPLES_BUFFER_LEN; i) {// 如果直接输出采样结果使用这个代码int16_t adc_result p_event-data.done.p_buffer[i];// NRF_LOG_INFO(Sample value: %d \n, adc_result);// 电压值 采样值 * 3.6 /2^10// val p_event-data.done.p_buffer[i] * 3.6 / 1024;// NRF_LOG_INFO(Voltage %.3fV\n, val);}uint8_t batVolPercentage get_battery_percentage(p_event-data.done.p_buffer[0]);NRF_LOG_INFO(batVolPercentage:%d \n, batVolPercentage);dis_battery_level_update_handle(batVolPercentage);// 事件次数加1m_adc_evt_counter;}
}
回调中, 先转换, 然后就可以打印每个数据的内容, 查看adc的采样值. 并根据业务需要, 比如把adc值转成mv为单位的电压值, 然后做char值修改等等.
static uint8_t get_battery_percentage(nrf_saadc_value_t adc_result) {uint16_t batt_lvl_in_milli_volts;batt_lvl_in_milli_volts ADC_RESULT_IN_MILLI_VOLTS(adc_result) DIODE_FWD_VOLT_DROP_MILLIVOLTS;NRF_LOG_INFO(battery %d mv \n\r, batt_lvl_in_milli_volts);return bat_mini_volt_to_percentage(batt_lvl_in_milli_volts);
}
这里是adc转mv, 下面是我老板写的, mv转百分数.
// 针对4.2伏特锂电池的点亮百分比算法.
uint8_t bat_mini_volt_to_percentage(uint16_t mvolts) {uint8_t battery_level;if (mvolts 4200) {battery_level 100;} else if (mvolts 3720) {battery_level 100 - (4200 - mvolts) / 6;} else if (mvolts 3200) {battery_level 20 - (3720 - mvolts) / 26;} else {battery_level 0;}return battery_level;
}
原谅有这么多魔术数字, 你自己写的时候可不能这样哦…