单片机/MCU论坛
直播中

辛书伟

12年用户 110经验值
擅长:嵌入式技术
私信 关注
[文章]

【RA4M2设计挑战赛】模拟IIC 及hs3003驱动

1.driver 中添加soft i2c

2. 指定I2C 管脚

由于RT env 还未添加 在头文件自己添加使能
pin定义对应pin number转换关系参考 drv_gpio的ra_pin_get,如'p408' 对应关系就是 4*16*16+0*10+8
这里定义了原理图中的两个IIC

hs3003 sensor 驱动编写

  1. #include
  2. #include

  3. #include "sensor_renesas_hs300x.h"
  4. #include
  5. #include
  6. #define DBG_TAG "sensor.renesas.hs300x"
  7. #define DBG_LVL DBG_INFO
  8. #include

  9. #define SENSOR_TEMP_RANGE_MAX (80)
  10. #define SENSOR_TEMP_RANGE_MIN (-10)
  11. #define SENSOR_HUMI_RANGE_MAX (100)
  12. #define SENSOR_HUMI_RANGE_MIN (0)

  13. /* Definitions of Mask Data for A/D data */
  14. #define RM_HS300X_MASK_HUMIDITY_UPPER_0X3F       (0x3F)
  15. #define RM_HS300X_MASK_TEMPERATURE_LOWER_0XFC    (0xFC)
  16. #define RM_HS300X_MASK_STATUS_0XC0               (0xC0)

  17. /* Definitions for Status Bits of A/D Data */
  18. #define RM_HS300X_DATA_STATUS_VALID              (0x00) // Status-bit: Valid data

  19. /* Definitions for Calculation */
  20. #define RM_HS300X_CALC_STATIC_VALUE              (16383.0F)
  21. #define RM_HS300X_CALC_HUMD_VALUE_100            (100.0F)
  22. #define RM_HS300X_CALC_TEMP_C_VALUE_165          (165.0F)
  23. #define RM_HS300X_CALC_TEMP_C_VALUE_40           (40.0F)
  24. #define RM_HS300X_CALC_DECIMAL_VALUE_100         (100.0F)

  25. struct hs300x_device
  26. {
  27.     struct rt_i2c_bus_device *i2c;

  28.     uint8_t addr;
  29. };
  30. static struct hs300x_device temp_humi_dev;

  31. static rt_err_t _hs300x_init(struct rt_sensor_intf *intf)
  32. {
  33.     temp_humi_dev.i2c = rt_i2c_bus_device_find(intf->dev_name);
  34.     //temp_humi_dev.addr = (uint8_t)intf->arg;
  35.                 temp_humi_dev.addr = HS300X_I2C_ADDR;

  36.     if (temp_humi_dev.i2c == RT_NULL)
  37.     {
  38.         return -RT_ERROR;
  39.     }

  40.     return RT_EOK;
  41. }

  42. int hs300x_read_data(struct hs300x_device* dev, float *humi_f, float *temp_f)
  43. {
  44.     uint8_t r_buf[4] = {0};
  45.     uint16_t humi, temp;
  46.     float    tmp_f   = 0.0;
  47.     struct rt_i2c_msg msgs;

  48.     msgs.addr = dev->addr;
  49.     msgs.flags = RT_I2C_WR;
  50.     msgs.buf = 0;
  51.     msgs.len = 0;
  52.     if (rt_i2c_transfer(dev->i2c, &msgs, 1) != 1)
  53.     {
  54.         LOG_E("mr error!
  55. ");
  56.         return -1;
  57.     }

  58.     msgs.addr = dev->addr;
  59.     msgs.flags = RT_I2C_RD;
  60.     msgs.buf = r_buf;
  61.     msgs.len = 4;

  62. __retry:
  63.     if (rt_i2c_transfer(dev->i2c, &msgs, 1) == 1)
  64.     {
  65.         LOG_D("%x,%x,%x,%x
  66. ", r_buf[0], r_buf[1], r_buf[2], r_buf[3]);
  67.         LOG_D("state:%x
  68. ", r_buf[0] & RM_HS300X_MASK_STATUS_0XC0);
  69.         if ((r_buf[0] & RM_HS300X_MASK_STATUS_0XC0) != RM_HS300X_DATA_STATUS_VALID)
  70.         {
  71.             rt_thread_mdelay(100);
  72.             goto __retry;
  73.         }

  74.         humi = (r_buf[0] & RM_HS300X_MASK_HUMIDITY_UPPER_0X3F) << 8 | r_buf[1];
  75.         temp = (r_buf[2] << 8 | (r_buf[3] & RM_HS300X_MASK_TEMPERATURE_LOWER_0XFC)) >> 2;

  76.         tmp_f = (float)humi;
  77.         tmp_f = (tmp_f * RM_HS300X_CALC_HUMD_VALUE_100) / RM_HS300X_CALC_STATIC_VALUE;
  78.         if (humi_f)
  79.         {
  80.             *humi_f = tmp_f;
  81.         }

  82.         tmp_f = (float)temp;
  83.         tmp_f = ((tmp_f * RM_HS300X_CALC_TEMP_C_VALUE_165) / RM_HS300X_CALC_STATIC_VALUE) - RM_HS300X_CALC_TEMP_C_VALUE_40;
  84.         if (temp_f)
  85.         {
  86.             *temp_f = tmp_f;
  87.         }
  88.         return 0;
  89.     }
  90.     else {
  91.         LOG_E("read error!
  92. ");
  93.         return -1;
  94.     }
  95. }

  96. float hs300x_read_temperature(struct hs300x_device* dev)
  97. {
  98.     float temp;
  99.     if (hs300x_read_data(dev, NULL, &temp) == 0)
  100.     {
  101.         return temp;
  102.     }
  103.     return 0;
  104. }

  105. float hs300x_read_humidity(struct hs300x_device* dev)
  106. {
  107.     float humi;
  108.     if (hs300x_read_data(dev, &humi, NULL) == 0)
  109.     {
  110.         return humi;
  111.     }
  112.     return 0;
  113. }

  114. static rt_size_t _hs300x_polling_get_data(rt_sensor_t sensor, struct rt_sensor_data *data)
  115. {
  116.     float temperature_x10, humidity_x10;

  117.     if (sensor->info.type == RT_SENSOR_TYPE_TEMP)
  118.     {
  119.         temperature_x10 = 10 * hs300x_read_temperature(&temp_humi_dev);
  120.         data->data.temp = (rt_int32_t)temperature_x10;
  121.         data->timestamp = rt_sensor_get_ts();
  122.     }
  123.     else if (sensor->info.type == RT_SENSOR_TYPE_HUMI)
  124.     {
  125.         humidity_x10    = 10 * hs300x_read_humidity(&temp_humi_dev);
  126.         data->data.humi = (rt_int32_t)humidity_x10;
  127.         data->timestamp = rt_sensor_get_ts();
  128.     }
  129.     return 1;
  130. }


  131. //rt_ssize_t (*fetch_data)(rt_sensor_t sensor, rt_sensor_data_t buf, rt_size_t len);

  132. static rt_ssize_t hs300x_fetch_data(struct rt_sensor_device *sensor, struct rt_sensor_data * buf, rt_size_t len)
  133. {
  134.     RT_ASSERT(buf);

  135.           if(sensor->config.irq_pin.mode==RT_SENSOR_MODE_FETCH_POLLING)
  136.     //if (sensor->config.mode == RT_SENSOR_MODE_FETCH_POLLING)
  137.     {
  138.         return _hs300x_polling_get_data(sensor, buf);
  139.     }
  140.     else
  141.         return 0;
  142. }

  143. static rt_err_t hs300x_control(struct rt_sensor_device *sensor, int cmd, void *args)
  144. {
  145.     rt_err_t result = RT_EOK;

  146.     return result;
  147. }

  148. static struct rt_sensor_ops sensor_ops =
  149. {
  150.     hs300x_fetch_data,
  151.     hs300x_control
  152. };

  153. int rt_hw_hs300x_init(const char *name, struct rt_sensor_config *cfg)
  154. {
  155.     rt_int8_t result;
  156.     rt_sensor_t sensor_temp = RT_NULL, sensor_humi = RT_NULL;

  157.      /* temperature sensor register */
  158.     sensor_temp = rt_calloc(1, sizeof(struct rt_sensor_device));
  159.     if (sensor_temp == RT_NULL)
  160.         return -1;

  161.     sensor_temp->info.type       = RT_SENSOR_TYPE_TEMP;
  162.     sensor_temp->info.vendor     = RT_SENSOR_VENDOR_UNKNOWN;
  163.     sensor_temp->info.name      = "hs300x";
  164.     sensor_temp->info.unit       = RT_SENSOR_UNIT_CELSIUS;
  165.     sensor_temp->info.intf_type  = RT_SENSOR_INTF_I2C;
  166.     sensor_temp->info.scale.range_max  = SENSOR_TEMP_RANGE_MAX;
  167.     sensor_temp->info.scale.range_min  = SENSOR_TEMP_RANGE_MIN;
  168.     sensor_temp->info.acquire_min = 5;

  169.     rt_memcpy(&sensor_temp->config, cfg, sizeof(struct rt_sensor_config));
  170.     sensor_temp->ops = &sensor_ops;

  171.     result = rt_hw_sensor_register(sensor_temp, name, RT_DEVICE_FLAG_RDONLY, RT_NULL);
  172.     if (result != RT_EOK)
  173.     {
  174.         LOG_E("device register err code: %d", result);
  175.         goto __exit;
  176.     }

  177.     /* humidity sensor register */
  178.     sensor_humi = rt_calloc(1, sizeof(struct rt_sensor_device));
  179.     if (sensor_humi == RT_NULL)
  180.         return -1;

  181.     sensor_humi->info.type       = RT_SENSOR_TYPE_HUMI;
  182.     sensor_humi->info.vendor     = RT_SENSOR_VENDOR_UNKNOWN;
  183.     sensor_humi->info.name      = "hs300x";
  184.     sensor_humi->info.unit       = RT_SENSOR_UNIT_PERMILLAGE;
  185.     sensor_humi->info.intf_type  = RT_SENSOR_INTF_I2C;
  186.     sensor_humi->info.scale.range_max  = SENSOR_HUMI_RANGE_MAX;
  187.     sensor_humi->info.scale.range_min  = SENSOR_HUMI_RANGE_MIN;
  188.     sensor_humi->info.acquire_min = 5;

  189.     rt_memcpy(&sensor_humi->config, cfg, sizeof(struct rt_sensor_config));
  190.     sensor_humi->ops = &sensor_ops;

  191.     result = rt_hw_sensor_register(sensor_humi, name, RT_DEVICE_FLAG_RDONLY, RT_NULL);
  192.     if (result != RT_EOK)
  193.     {
  194.         LOG_E("device register err code: %d", result);
  195.         goto __exit;
  196.     }

  197.     _hs300x_init(&cfg->intf);
  198.     return RT_EOK;

  199. __exit:
  200.     if (sensor_temp)
  201.         rt_free(sensor_temp);
  202.     if (sensor_humi)
  203.         rt_free(sensor_humi);

  204.     return -RT_ERROR;
  205. }

port端口注册
  1. static int rt_hw_hs300x_port(void)
  2. {
  3.         struct rt_sensor_config cfg;
  4.         cfg.intf.dev_name = "i2c1";
  5.         cfg.irq_pin.mode = RT_SENSOR_MODE_FETCH_POLLING;
  6.         rt_hw_hs300x_init("hs3003",&cfg);
  7.         return RT_EOK;
  8. }
  9. INIT_COMPONENT_EXPORT(rt_hw_hs300x_port);

可通过shell 或者编写线程读取数据,刚上电可看到sensor 注册成功






串口打印结果

更多回帖

发帖
×
20
完善资料,
赚取积分