锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

JHM3000体温传感器驱动

时间:2023-12-06 01:07:01 传感器1130

由于2020年疫情的影响,一堆制造商突然出现在中国。

硬件平台:nRF52832 JHM3000

JHM3000是单线通信体温传感器芯片,线性好,校准后精度可达0.1度。

主要问题是通信是单一的IO输出,芯片上电后,IO脉冲信号将不断输出,需要MCU计算脉宽来解码数据。

每个采样周期为:2.8ms间隔 6ms数据传输

相邻两个高脉宽之比决定数据类型,START=3:3,BIT0=5:1,BIT1=1:5
数据样本:91、3、3、1、6、1、5、1、5、1、5、1、5、1、5、6、1、1、5、5、2、1、5、5、1、5、1、5、1、5、1、5、1、5、1、5、1、5、1、5、5、1、5、5、1、5、5、1、5、5、1、5、5、1、5、5、5、1、5、5、1、5、5、1、5、5、1、5、5、5、5、1、5、5、5、1、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、1、5、1、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、...
每次采样一次START 14个BIT数据:S BBBBBBBBBBBBB

解码数据时,需要先找到START然后开始分析采样数据。

以下是主源代码:

/* * JHM3000 体温传感器驱动程序 * 每次采样2.8ms   数据传输6ms * 单线IO输出,相邻两个高脉宽比决定数据,START=3:3, BIT0=5:1, BIT1=1:5 * 数据样本:61、4、3、1、5、1、6、1、6、1、5、1、5、1、5、1、5、6、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、5、1、5、1、5、1、5、1、5、1、5、1、1、1、1、1、1、1、1、1、1、1、1、1、1、5、1、5、1、5、1、5、1、5、1、5、1、5、1、5、1、5、1、5、1、5、1、5、1、5、1、5、1、5、1、5、1、5、1、5、1、5、1、5、1、5、1、5、1、1、5、1、5、1、5、1、5、1、5、1、5、1、5、1、5、1、5、1、5、1、5、5、1、5、5、1、5、5、1、5、1、5、5、1、5、5、5、5、1、1、5、5、5、5、1、1、1、5、1、5、5、1、5、5、5、5、1、1、1、5、1、5、5、1、5、5、5、5、1、5、5、5、5、1、1、5、1、1、1、1、1、1、5、1、1、1、1、1、1、1、1、5、5、5、1、1、1、1、1、1、1、1、1、1、5、1、1、1、1、1、1、1、5、5、5、5、5、1、1、1、1、1、1、1、5、5、5、5、1、1、1、1、1、1、1、1、1、1、5、1、1、1、1、5、5、5、5、5、5、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、5、5、5、1、1、1、1、1、1、1、1、5、5、5、6、1、5、1、6、1、1、1、5、1、1、1、5、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、5、5、5、5、5、5、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、5、1、1、5、5、5、5、5、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、5、5、5、1、1、1、1、5、5、1、5、5、5、5、5、5、1、5、5、5、1、5、1、5、5、5、5、5、5、1、1、1、1、1、1、1、1、1、1、1、1、1、1、5、1、5、1、5、5、5、5、5、5、5、5、5、5、1、1、1、1、5、5、5、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、1、5、5、5、5、5、5、5、1、1、5、5、1、1、1、1、1、1、1、5、 *           91、3、1、6、1、5、1、5、1、5、1、5、1、5、1、6、1、5、1、5、5、5、1、5、5、5、1、5、5、1、5、5、1、5、5、1、5、1、5、1、5、1、5、1、5、1、5、5、5、1、5、5、5、5、5、1、5、5、5、1、5、5、1、5、5、1、5、5、1、5、5、1、5、1、5、1、5、1、5、1、5、5、1、5、5、1、5、1、5、1、5、1、5、5、1、5、5、1、5、1、5、1、5、5、5、5、5、5、5、5、5、1、5、5、1、5、5、1、5、5、1、5、5、1、5、5、1、5、5、1、5、1、5、1、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5 *           91,3,4,... * 每次采样一次START 14个BIT数据:S BBBBBBBBBBBBB * 蒋晓岗 * 2020.03.06 */ #include  #include  #include "log.h" #include "bsp.h" #include "sdk.h"  ///判断数据类型,错误返回0, 成功返回1,S位bit=-1,BIT10,BIT1返回1 static int decode_one_bit(uint32_t t1, uint32_t t2, int *bit) {  uint32_t diff;  if((t1   t2) > 10)  {   LOG("t1=%d, t2=%d\r\n", t1, t2);   return 0;  }  if(t1 > t2)  {   diff = t1 - t2;   if(diff > t2)   {    *bit = 0;    return 1;   }  }  if(t2 > t1)  {   diff = t2 - t1;   if(diff > t1)   {    *bit = 1;    return 1;   }  }  *bit = -1;  return 1; }  //等待管脚电平跳变 static int wait_pin_state(int state, uint32_t timeout) {  uint32_t diff;  uint32_t tick;  diff = 0;  tick = app_timer_cnt_get();  timeout = timeout << 5; /1毫秒等于32小时  while(diff < timeout)  {   if(nrf_gpio_pin_read(HM3000_PIN_DATA) == state)   {    return 1;   }   else   {    app_timer_cnt_diff_compute(app_timer_cnt_get(), tick, &diff);   }  }  return 0; }  //计算高电平时长 static int calc_pulse_width(uint32_t *pw) {  int ret;  uint32_t diff;  uint32_t tick;  ret = wait_pin_state(1, 5);  if(!ret)  {   return 0;  }  tick = app_timer_cnt_get();  ret = wait_pin_state(0, 5);  if(!ret)  {   return 0;  }  app_timer_cnt_diff_compute(app_timer_cnt_get(), tick, &diff);  *pw = diff;  return 1; }  //等待高电平结束 static int wait_for_idle(void) {  return wait_pin_state(0, 5); }  //等待ADC采样开始 //ADC采样有2.5ms高电平 static int wait_for_adc(void) {  int i;  int ret;  uint32_t pw;  for(i=0; i<32; i  )  {   ret = calc_pulse_width(&pw);   if(!ret)   {    return 0;   }   if(pw > 30)   {    return 1;   }  }  return 0; }  //接收一个数据 static int recv_one_bit(int *bit) {  int ret;  uint32_t t1;  uint32_t t2;  ret = calc_pulse_width(&t1);  if(!ret)  {   return 0;  }  ret = calc_pulse_width(&t2);  if(!ret)  {   return 0;  }  return decode_one_bit(t1, t2, bit); }  /// static int recv_start_bit(void) {  int ret;  int bit;  ret = recv_one_bit(&bit);  if(!ret)  {   return 0;  }  return bit == -1; }  //接收采样数据 //数据=1位符号 13位数据 static int recv_adc_data(int *data) {  int i;  int bit;  int ret;  int16_t tmp;  tmp = 0;  for(i=0; i<14; i  )  {   ret = recv_one_bit(&bit);   if(!ret)   {    LOG("drv_hm3000: recv bit%d failed!ret)   {    LOG("drv_hm3000: recv bit%d failed!\r\n", i);    return 0;   }   if(bit < 0)   {    LOG("drv_hm3000: recv bit%d invalid!\r\n", i);    return 0;   }   if(bit)   {    tmp |= 1 << (15 - i);   }  }  //LOG("drv_hm3000: raw=%d\r\n", tmp);  *data = tmp >> 2;  return 1; }  //采样数据 static int sample_data(int *data) {  int ret;  ret = wait_for_idle();  if(!ret)  {   LOG("drv_hm3000: wait idle timeout!ret)  {   LOG("drv_hm3000: wait idle timeout!\r\n");   return 0;  }  ret = wait_for_adc();  if(!ret)  {   LOG("drv_hm3000: wait adc timeout!\r\n");   return 0;  }  ret = recv_start_bit();  if(!ret)  {   LOG("drv_hm3000: recv start failed!\r\n");   return 0;  }  ret = recv_adc_data(data);  if(!ret)  {   LOG("drv_hm3000: recv data failed!\r\n");   return 0;  }  return ret; }  #if 0 //调试数据 static void dump_data(void) {  int i;  static uint32_t time[100];  for(i=0; i<64; i  )  {   calc_pulse_width(&time[i]);  }  for(i=0; i<64; i  )  {   LOG("%d,", time[i]);  }  LOG("\r\n"); } #endif  //读取采样数据 int drv_hm3000_read(int *data) {  //dump_data();  //return 0;    int ret;  //uint8_t sr;  //sd_nvic_critical_region_enter(&sr);  ret = sample_data(data);  //sd_nvic_critical_region_exit(sr);  return ret; }  ///打开芯片电源 void drv_hm3000_enable(void) {  nrf_gpio_pin_write(HM3000_PIN_PWR, 1); }  //关闭芯片电源 void drv_hm3000_disable(void) {  nrf_gpio_pin_write(HM3000_PIN_PWR, 0); }  ///初始化驱动 void drv_hm3000_init(void) {  nrf_gpio_cfg_output(HM3000_PIN_PWR);     nrf_gpio_cfg_input(HM3000_PIN_DATA, NRF_GPIO_PIN_NOPULL);  nrf_gpio_pin_write(HM3000_PIN_PWR, 0); } 

锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章