XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XX 作 者:ZHS(文化人)
XX 联系方式:文章末尾Chat快问
XX 版权声明:原创文章,欢迎评论和转载~转载时能告诉我一声就最好了
XX 要说的话:作者水平有限,难免有不足之处,恳请指正!
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
写在前面:因为楼主参与的项目中需要采集两路ADC,所以使用了ADC采集的多通道接口,ADC只针对nrf51,nrf52升级为SAADC。感慨一下:Nordic的资料真的太少了~
一、调试历程:
首先分享一下调试的历程,可谓是一路坎坷~
1、项目中需要采集两路ADC,就研究了ADC的接口;
2、使用多通道的接口,放在timer中调用结果导致复位,没找到原因只能放弃;(现在想想应该使用方法不对,还是对接口不熟)
3、接着改用单通道的接口,放在两个timer中调用,ADC是对了,但是发现整个程序的timer异常了,计时不对;
4、卡了很长时间,一直是觉得时钟设置或者晶振有问题,尝试各种方法解决timer异常问题,一直没解决;
5、最后为了解决别的问题,屏蔽了一组ADC,发现timer正常了,由此确定是两路ADC放在两个timer中调用冲突了,导致timer异常;
6、尝试把两路单通道ADC放在一个timer中,timer还是异常;(因为ADC初始化是阻塞模式)
7、没办法了,csdn里也没有搜索到有关多通道的使用,只能硬着头皮继续研究多通道的接口了;
8、最终还是搞明白了,在timer中调用多通道的接口,解决了问题;
二、使用方法:
1、single channel ADC:
nrf_drv_adc_sample_convert(channel,value);
2、more than one channel:
nrf_drv_adc_buffer_convert(buffer,size);
1)size 是buffer的长度;
2)如果size是2,使能了一个通道(input4),就是把该通道采集两次,每次都要调用nrf_drv_adc_sample();
3)如果size是2,使能了两个通道(input4和input5),则按照使能先后顺序,buffer[0]对应input4,buffer[1]对应input5;
4)阻塞模式下,buffer满了之后才会调用callback;
三、使用举例:
参考SDK中adc的例程和nrf_drv_adc.h中的介绍:
nrf_drv_adc_channel_t m_channel_config1 = NRF_DRV_ADC_DEFAULT_CHANNEL(NRF_ADC_CONFIG_INPUT_4);
nrf_drv_adc_channel_t m_channel_config2 = NRF_DRV_ADC_DEFAULT_CHANNEL(NRF_ADC_CONFIG_INPUT_5);
//初始化
adc_init()
{
ret_code_t ret_code;
nrf_drv_adc_config_t config = NRF_DRV_ADC_DEFAULT_CONFIG;
ret_code = nrf_drv_adc_init(&config, adc_event_handler);
m_channel_config1.config.config.input = NRF_ADC_CONFIG_SCALING_INPUT_ONE_THIRD;
m_channel_config2.config.config.input = NRF_ADC_CONFIG_SCALING_INPUT_ONE_THIRD;
nrf_drv_adc_channel_enable(&m_channel_config1);
nrf_drv_adc_channel_enable(&m_channel_config2);
}
//timer中调用
adc_timer_handler()
{
static uint8_t i;
i++;
if(1 == i)
nrf_drv_adc_buffer_convert(buffer, size);
if(2 == i)
i = 0;
nrf_drv_adc_sample();
}
如果需要频率是1hz,则timer设置为500ms采集一次,这样两次采集完才是1s,才会调用callback;
然后在callback~adc_event_handler中处理ADC数据就可以了。这里使用了一个简单的算法:加权平均值滤波算法。