1 设计方案
1)将psensor阈值写到寄存器中(0x90/0x91/0x92/0x93),这样,当得到的测量与之在设置阈值之外时就会产生中断
2)设置中断寄存器(0x8F),默认状态是不使能中断,在0x8F中需要使能中断并且设置中断是高电平还是低电平(默认低电平)
3)周期性轮询中断引脚,通过电平高低判断是否被遮挡,并在此基础上进行软件消抖处理
4)将遮挡状态设置为一个标志位,用于传给其他线程使用:比如屏可能需要根据psensor状态来控制屏幕的亮灭
2 相关寄存器介绍
1 )INTERRUPT Register(0x8F)
如果设置中断逻辑为低电平,则为:00000001 即0x01
若果设置中断逻辑为高电平,则为:00000101即0x05
2)PS_THRES Regiser (0x90/0x91/0x92/0x93)
比如设置的低阈值为0,高阈值为200,则:
0x90(UP_0) :200&0xFF 0X91(UP_1):200>>8
0x91(LOW_0) :0&0xFF 0X92(LOW_1):0>>8
3 代码实现
1) 寄存器配置
设置中断寄存器、设置测量阈值
#define LTR559_UPPER_THRESHOLD 512
#define LTR559_UPPER_LOWBYTE_DATA0 LTR559_UPPER_THRESHOLD&0xFF //upper threshold
#define LTR559_UPPER_HIGHBYTE_DATA1 LTR559_UPPER_THRESHOLD>>8
#define LTR559_LOWER_LOWBYTE_DATA0 0&0xFF //lower threshold
#define LTR559_LOWER_HIGHBYTE_DATA1 0>>8
#define LTR559_ENABLE_INTERRUPT 0x01 //interrupt register configure
具体怎样将这些值写到寄存器,代码略去
2)设置中断引脚为输入
gpio_in_cfg(GPIO_PIN_PSENSOR_IRQ , GPIO_IN_PULL_NOPULL);//configure psensor IRQ pin
其中:
#define GPIO_PIN_PSENSOR_IRQ NRF52_GPIO_PIN_1_13 //psensor IRQ pin
/**
* \brief GPIO input pull configurations.
*/
typedef enum {
GPIO_IN_PULL_NOPULL,
GPIO_IN_PULL_PULLDOWN,
GPIO_IN_PULL_PULLUP
} gpio_in_pull_t;
3)轮询中断脚及软件消抖
proximity_sensor.c
void psensor_eliminate_dithering(void)
{
static uint8_t read_pin_count_blocking = 0;
static uint8_t read_pin_count_unblocking = 0;
if(PROXIMITY_SENSOR_UNBLOCKING == g_psensor_status){
if(PSENSOR_IRQ_VOLTAGE_LOW == PSENSOR_IRQ_PIN_READ){
read_pin_count_blocking++;
if(read_pin_count_blocking > READ_PIN_COUNT_MAX){
g_wear_state = WEAR_ON_STATUS;
g_psensor_status = PROXIMITY_SENSOR_BLOCKING;
read_pin_count_blocking = 0;
}
} else {
read_pin_count_blocking=0;
}
} else {
if(PSENSOR_IRQ_VOLTAGE_HIGH == PSENSOR_IRQ_PIN_READ){
read_pin_count_unblocking++;
if(read_pin_count_unblocking > READ_PIN_COUNT_MAX){
g_wear_state = WEAR_OFF_STATUS;
g_psensor_status = PROXIMITY_SENSOR_UNBLOCKING;
read_pin_count_blocking = 0;
}
} else {
read_pin_count_unblocking=0;
}
}
}
其中:
proximity_sensor.h
extern uint8_t g_psensor_status;
extern uint8_t g_wear_state;
#define PROXIMITY_SENSOR_BLOCKING 1
#define PROXIMITY_SENSOR_UNBLOCKING 0
#define PSENSOR_IRQ_VOLTAGE_HIGH 1
#define PSENSOR_IRQ_VOLTAGE_LOW 0
#define WEAR_ON_STATUS 1
#define WEAR_OFF_STATUS 0
#define PSENSOR_IRQ_PIN_READ gpio_in_read(GPIO_PIN_PSENSOR_IRQ) //read pin voltage
#define READ_PIN_COUNT_MAX 20 //max read pin count
proximity_sensor.c
uint8_t g_psensor_status = PROXIMITY_SENSOR_UNBLOCKING;
uint8_t g_wear_state = WEAR_OFF_STATUS;
4) psensor线程周期性调用
。。。
。。。
。。。
psensor_eliminate_dithering();
if(WEAR_ON_STATUS == g_wear_state){LOG_INFO("P-sensor wear on\r\n");}