搭建开发环境
作为一个新人小白,项目临时需要用这款nRF51802开发一些功能,第一次接触那是一个脑袋两个大。在网上随便找的环境搭建(基于MDK5),过程基本上很顺利,我就不班门弄斧,直接给需要的指个路nRF51802开发环境搭建
开发参考资料
为了方便查找资料,我把开发过程中可能需要的资料贴在下面
芯片封装图
ADC通道和引脚对应图
ADC使用注意事项
从上面手册数据可以看出,nRF51802拥有8通道(AIN0~AIN7)最高可支持10bit(8/9/10)精度的ADC。
(由于这款芯片比较老,相对的开发资料已经不少,所以下面的ADC使用直接通过HAL操作,网上大多数帖子都是寄存器操作,也有一部分原因开发周期太紧,直接HAL操作简单快捷)
ADC的配置
在次需要说明一点,nRF51802的ADC只能进行单次转换,不能连续转换,如果需要连续转换,需要轮询或者定时器进行周期性操作。
配置数据先从官方的SDK中抽丝剥茧,逐个分析:
static nrf_drv_adc_channel_t m_channel_config = NRF_DRV_ADC_DEFAULT_CHANNEL(NRF_ADC_CONFIG_INPUT_2);
这是官方SDK中,头文件下面直接进行的通道配置
.直接跳转过去,可以查到是针对通道2进行了默认的初始化配置,那么,官方SDK中,默认的配置又是怎么配置的?需要跳转NRF_DRV_ADC_DEFAULT_CHANNEL();
/**@brief Macro for initializing the ADC channel with the default configuration. */
#define NRF_DRV_ADC_DEFAULT_CHANNEL(analog_input) \
{{{ \
.resolution = NRF_ADC_CONFIG_RES_10BIT, \
.input = NRF_ADC_CONFIG_SCALING_INPUT_FULL_SCALE, \
.reference = NRF_ADC_CONFIG_REF_VBG, \
.ain = (analog_input) \
}}, NULL}
跳转之后,官方的默认配置就很明确了,从上到下依次是:
1. 当前通道ADC的精度:10bit;
2. 模数转换比例(也就是输入输出缩放比例):
NRF_ADC_CONFIG_SCALING_INPUT_FULL_SCALE // 官方给的注释是不缩放,也就是比例为1
3. 参考电压:(官方默认内部1.2为参考电压)
NRF_ADC_CONFIG_REF_VBG = ADC_CONFIG_REFSEL_VBG, /**< 1.2 V reference. */
4. 最下面的ain:就是我们传入的通道,SDK示例为第二通道,也就是AIN2。
上面就是官方默认的ADC通道配置,在使用ADC的过程中,上面的配置数值是可以根据自己的项目需求进行修改。
ADC的计算
已经知道了ADC的配置数据,想要求出当前通道读取的电压需要怎么操作?
ADC计算公式:
V:实测电压
adc:ADC通道读出的数值
reference:参考电压(SDK默认1.2V)
1024:2^10(ADC通道的精度)
input:模数转换比例
比如,当前ADC读出数值235,按照官方默认的配置,当前ADC实测电压是多少?
(235 *1.2)/(1024 * 1) ≈ 0.275V
nRF51802ADC开发(HAL)
ADC配置使用demo演示
user_adc.c
static nrf_drv_adc_channel_t test_channel_config = NRF_DRV_ADC_TEST_CHANNEL(NRF_ADC_CONFIG_INPUT_2);
static void adc_event_handler(nrf_drv_adc_evt_t const * p_event);
/**
@brief ADC驱动初始化
@param 无
@return 无
*/
void adc_init(void)
{
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);
APP_ERROR_CHECK(ret_code);
nrf_drv_adc_channel_enable(&test_channel_config);
}
/**
@brief ADC中断处理回调函数
@param pEvent -[in] ADC事件
@return 无
*/
static void adc_event_handler(nrf_drv_adc_evt_t const * p_event)
{
if (p_event->type == NRF_DRV_ADC_EVT_DONE) {
NRF_LOG_INFO("test_adc\n");
}
}
user_adc.h
/**@brief Macro for initializing the ADC channel with the test configuration. */
#define NRF_DRV_ADC_TEST_CHANNEL(analog_input) \
{{{ \
.resolution = NRF_ADC_CONFIG_RES_10BIT, \
.input = NRF_ADC_CONFIG_SCALING_INPUT_ONE_THIRD, \
.reference = NRF_ADC_CONFIG_REF_SUPPLY_ONE_HALF, \
.ain = (analog_input) \
}}, NULL}
在配置中,没有使用官方默认的SDK配置,而是自己修改的配置,对比上面的配置,解释一下:
精度:10bit
模数转换比例:1/3
参考电压:芯片供电电压的1/2
通道:AIN2
对比上面的计算公式,如果此时adc读取的值为453,芯片供电3.3V,求出对应通道的电压:
(453 * 3.3 * 1/2)/(1024 * 1/3)≈ 2.2V;
ADC配置参数的意义
nRF51802的ADC精度最大10bit,也就是2^10 = 1024;
也就是说1023是ADC能读取的最大数值(简单理解0~1023就是1024个数),那么对比SDK的demo,当读取为1023的时候,就是最大值,那么官方SDK所能算出的最大电压:
(1023 * 1.2)/ (1024 * 1) = 1.2V;
也就是说,官方给的最大测量是1.2V,很明显不符合一些开发需求,那么如果用自己配置的,如果ADC通道读取1023,最大的数是:
(1023 *3.3 *1/2)/(1024 *1/3) ≈ 4.8V;
也就是说自己配置的量程为0~4.8V,这就可以满足大多数情况下的电压读取。
从上面对比可以看出,ADC的参数配置的意义,就是在使用过程中根据自己不同的需求,可以配置出适合自己当前项目的范围