1.目的
学习nrf51822模拟比较器
2.分析
模拟比较器,用于比较2个模拟信号的大小,
3.平台:
协议栈版本:SDK10.0.0
编译软件:keil 5.14
硬件平台:nrf51822最小系统
例子:SDK 10.0.0\examples\ble_peripheral\ble_app_uart\pca10028\s110\arm4
4.步骤
1.把SDK10.0\components\drivers_nrf\lpcomp 文件中的.c文件添加到目录如下,并添加对应的路径。
2.添加如下代码。
static void lpcomp_event_handler(nrf_lpcomp_event_t event):设置回调函数
void lpcomp_init(void)初始化比较器。比较器底层配置使用的使系统默认的。
if (p_config == NULL)
{
p_config = &m_default_config;
}
底层硬件配置:nrf_lpcomp_configure(&(p_config->hal) );
/** LPCOMP driver default configuration, including the LPCOMP HAL configuration. */ #define NRF_DRV_LPCONF_DEFAULT_CONFIG \ { \ .hal = {LPCOMP_CONFIG_REFERENCE , LPCOMP_CONFIG_DETECTION}, \ .input = LPCOMP_CONFIG_INPUT, \ .interrupt_priority = LPCOMP_CONFIG_IRQ_PRIORITY \ }这里设置设置参数有: ={ 参考电压 ,检测方式}
中断优先级
/* LPCOMP */ #define LPCOMP_ENABLED 1 #if (LPCOMP_ENABLED == 1) #define LPCOMP_CONFIG_REFERENCE NRF_LPCOMP_REF_SUPPLY_4_8 #define LPCOMP_CONFIG_DETECTION NRF_LPCOMP_DETECT_DOWN #define LPCOMP_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW #define LPCOMP_CONFIG_INPUT NRF_LPCOMP_INPUT_2 #endif
/** * @enum nrf_lpcomp_ref_t * @brief LPCOMP reference selection. */ typedef enum { #ifdef NRF51 NRF_LPCOMP_REF_SUPPLY_1_8 = LPCOMP_REFSEL_REFSEL_SupplyOneEighthPrescaling, /**< Use supply with a 1/8 prescaler as reference. */ NRF_LPCOMP_REF_SUPPLY_2_8 = LPCOMP_REFSEL_REFSEL_SupplyTwoEighthsPrescaling, /**< Use supply with a 2/8 prescaler as reference. */ NRF_LPCOMP_REF_SUPPLY_3_8 = LPCOMP_REFSEL_REFSEL_SupplyThreeEighthsPrescaling, /**< Use supply with a 3/8 prescaler as reference. */ NRF_LPCOMP_REF_SUPPLY_4_8 = LPCOMP_REFSEL_REFSEL_SupplyFourEighthsPrescaling, /**< Use supply with a 4/8 prescaler as reference. */ NRF_LPCOMP_REF_SUPPLY_5_8 = LPCOMP_REFSEL_REFSEL_SupplyFiveEighthsPrescaling, /**< Use supply with a 5/8 prescaler as reference. */ NRF_LPCOMP_REF_SUPPLY_6_8 = LPCOMP_REFSEL_REFSEL_SupplySixEighthsPrescaling, /**< Use supply with a 6/8 prescaler as reference. */ NRF_LPCOMP_REF_SUPPLY_7_8 = LPCOMP_REFSEL_REFSEL_SupplySevenEighthsPrescaling, /**< Use supply with a 7/8 prescaler as reference. */ #elif defined NRF52 NRF_LPCOMP_REF_SUPPLY_1_8 = LPCOMP_REFSEL_REFSEL_Ref1_8Vdd, /**< Use supply with a 1/8 prescaler as reference. */ NRF_LPCOMP_REF_SUPPLY_2_8 = LPCOMP_REFSEL_REFSEL_Ref2_8Vdd, /**< Use supply with a 2/8 prescaler as reference. */ NRF_LPCOMP_REF_SUPPLY_3_8 = LPCOMP_REFSEL_REFSEL_Ref3_8Vdd, /**< Use supply with a 3/8 prescaler as reference. */ NRF_LPCOMP_REF_SUPPLY_4_8 = LPCOMP_REFSEL_REFSEL_Ref4_8Vdd, /**< Use supply with a 4/8 prescaler as reference. */ NRF_LPCOMP_REF_SUPPLY_5_8 = LPCOMP_REFSEL_REFSEL_Ref5_8Vdd, /**< Use supply with a 5/8 prescaler as reference. */ NRF_LPCOMP_REF_SUPPLY_6_8 = LPCOMP_REFSEL_REFSEL_Ref6_8Vdd, /**< Use supply with a 6/8 prescaler as reference. */ NRF_LPCOMP_REF_SUPPLY_7_8 = LPCOMP_REFSEL_REFSEL_Ref7_8Vdd, /**< Use supply with a 7/8 prescaler as reference. */ NRF_LPCOMP_REF_SUPPLY_1_16 = LPCOMP_REFSEL_REFSEL_Ref1_16Vdd, /**< Use supply with a 1/16 prescaler as reference. */ NRF_LPCOMP_REF_SUPPLY_3_16 = LPCOMP_REFSEL_REFSEL_Ref1_16Vdd, /**< Use supply with a 3/16 prescaler as reference. */ NRF_LPCOMP_REF_SUPPLY_5_16 = LPCOMP_REFSEL_REFSEL_Ref1_16Vdd, /**< Use supply with a 5/16 prescaler as reference. */ NRF_LPCOMP_REF_SUPPLY_7_16 = LPCOMP_REFSEL_REFSEL_Ref1_16Vdd, /**< Use supply with a 7/16 prescaler as reference. */ NRF_LPCOMP_REF_SUPPLY_9_16 = LPCOMP_REFSEL_REFSEL_Ref1_16Vdd, /**< Use supply with a 9/16 prescaler as reference. */ NRF_LPCOMP_REF_SUPPLY_11_16 = LPCOMP_REFSEL_REFSEL_Ref1_16Vdd, /**< Use supply with a 11/16 prescaler as reference. */ NRF_LPCOMP_REF_SUPPLY_13_16 = LPCOMP_REFSEL_REFSEL_Ref1_16Vdd, /**< Use supply with a 13/16 prescaler as reference. */ NRF_LPCOMP_REF_SUPPLY_15_16 = LPCOMP_REFSEL_REFSEL_Ref1_16Vdd, /**< Use supply with a 15/16 prescaler as reference. */ #endif NRF_LPCOMP_REF_EXT_REF0 = LPCOMP_REFSEL_REFSEL_ARef | (LPCOMP_EXTREFSEL_EXTREFSEL_AnalogReference0 << 16), /**< External reference 0. */ NRF_LPCOMP_CONFIG_REF_EXT_REF1 = LPCOMP_REFSEL_REFSEL_ARef | (LPCOMP_EXTREFSEL_EXTREFSEL_AnalogReference1 << 16), /**< External reference 1. */ } nrf_lpcomp_ref_t;
/** * @enum nrf_lpcomp_input_t * @brief LPCOMP input selection. */ typedef enum { NRF_LPCOMP_INPUT_0 = LPCOMP_PSEL_PSEL_AnalogInput0, /**< Input 0. */ NRF_LPCOMP_INPUT_1 = LPCOMP_PSEL_PSEL_AnalogInput1, /**< Input 1. */ NRF_LPCOMP_INPUT_2 = LPCOMP_PSEL_PSEL_AnalogInput2, /**< Input 2. */ NRF_LPCOMP_INPUT_3 = LPCOMP_PSEL_PSEL_AnalogInput3, /**< Input 3. */ NRF_LPCOMP_INPUT_4 = LPCOMP_PSEL_PSEL_AnalogInput4, /**< Input 4. */ NRF_LPCOMP_INPUT_5 = LPCOMP_PSEL_PSEL_AnalogInput5, /**< Input 5. */ NRF_LPCOMP_INPUT_6 = LPCOMP_PSEL_PSEL_AnalogInput6, /**< Input 6. */ NRF_LPCOMP_INPUT_7 = LPCOMP_PSEL_PSEL_AnalogInput7 /**< Input 7. */ } nrf_lpcomp_input_t;
/** * @enum nrf_lpcomp_detect_t * @brief LPCOMP detection type selection. */ typedef enum { NRF_LPCOMP_DETECT_CROSS = LPCOMP_ANADETECT_ANADETECT_Cross, /**< Generate ANADETEC on crossing, both upwards and downwards crossing. */ NRF_LPCOMP_DETECT_UP = LPCOMP_ANADETECT_ANADETECT_Up, /**< Generate ANADETEC on upwards crossing only. */ NRF_LPCOMP_DETECT_DOWN = LPCOMP_ANADETECT_ANADETECT_Down /**< Generate ANADETEC on downwards crossing only. */ } nrf_lpcomp_detect_t;
模拟输入通道2作为模拟比较电压。
具体参考手册:nRF51_Series_Reference_manual v3.0 和 nRF51822_PS v3.1
下载地址:http://www.nordicsemi.com/eng/Products/Bluetooth-Smart-Bluetooth-low-energy/nRF51822
/**@brief Function for placing the application in low power state while waiting for events. */ void lpcomp_event_handler(nrf_lpcomp_event_t event) { if (event == NRF_LPCOMP_EVENT_READY) { SEGGER_RTT_printf(0,"\r\nNRF_LPCOMP_EVENT_READY\r\n"); } if (event == NRF_LPCOMP_EVENT_DOWN) { SEGGER_RTT_printf(0,"\r\nNRF_LPCOMP_EVENT_DOWN\r\n"); } if (event == NRF_LPCOMP_EVENT_UP) { SEGGER_RTT_printf(0,"\r\nNRF_LPCOMP_EVENT_UP\r\n"); } }
/** * @brief Initialize LPCOMP driver. */ void lpcomp_init(void) { uint32_t err_code; // initialize LPCOMP driver, from this point LPCOMP will be active and provided // event handler will be executed when defined action is detected err_code = nrf_drv_lpcomp_init(NULL, lpcomp_event_handler); APP_ERROR_CHECK(err_code); nrf_drv_lpcomp_enable(); }
ret_code_t nrf_drv_lpcomp_init(const nrf_drv_lpcomp_config_t * p_config, lpcomp_events_handler_t events_handler) { if (m_state != NRF_DRV_STATE_UNINITIALIZED) { // LPCOMP driver is already initialized return NRF_ERROR_INVALID_STATE; } if (p_config == NULL) { p_config = &m_default_config; } nrf_lpcomp_configure(&(p_config->hal) ); if (events_handler) { m_lpcomp_events_handler = events_handler; } else { return NRF_ERROR_INVALID_PARAM; } nrf_lpcomp_input_select(p_config->input); switch (p_config->hal.detection) { case NRF_LPCOMP_DETECT_UP: nrf_lpcomp_int_enable(LPCOMP_INTENSET_UP_Msk); break; case NRF_LPCOMP_DETECT_DOWN: nrf_lpcomp_int_enable(LPCOMP_INTENSET_DOWN_Msk); break; case NRF_LPCOMP_DETECT_CROSS: nrf_lpcomp_int_enable(LPCOMP_INTENSET_CROSS_Msk); break; default: break; } nrf_lpcomp_shorts_enable(NRF_LPCOMP_SHORT_READY_SAMPLE_MASK); nrf_drv_common_irq_enable(LPCOMP_IRQn, p_config->interrupt_priority); m_state = NRF_DRV_STATE_INITIALIZED; return NRF_SUCCESS; }
这个是,中断函数,会查找对应的标志位,并产生对应的回调。。
void LPCOMP_IRQHandler(void) { lpcomp_execute_handler(NRF_LPCOMP_EVENT_READY, LPCOMP_INTENSET_READY_Msk); lpcomp_execute_handler(NRF_LPCOMP_EVENT_DOWN, LPCOMP_INTENSET_DOWN_Msk); lpcomp_execute_handler(NRF_LPCOMP_EVENT_UP, LPCOMP_INTENSET_UP_Msk); lpcomp_execute_handler(NRF_LPCOMP_EVENT_CROSS, LPCOMP_INTENSET_CROSS_Msk); }