当前位置:   article > 正文

hi3861使用iic驱动adxl346_hi_i2c_writeread

hi_i2c_writeread

开发平台

Ubuntu 18.04

DOPI  hi3861lv开发板、adxl346模组

Q群:735884031

一.配置3861iic

1.搭建demo工程,可参考我的上一篇博客

2.查看引脚复用,使用GPIO9、GPIO10作为iic0 IO

3.配置io复用,初始化iic控制器

  1. /Hi3861V100R001C00SPC025/app/adxl346$ tree
  2. .
  3. ├── app.json
  4. ├── iic
  5. │   ├── iic.c
  6. │   ├── iic.h
  7. │   └── SConscript
  8. ├── SConscript
  9. └── src
  10. ├── main.c
  11. └── SConscript

iic.c

  1. // 标准库
  2. #include <stdio.h>
  3. #include <unistd.h>
  4. // 第三方库
  5. #include <hi3861_platform.h>
  6. #include <hi_io.h>
  7. #include <hi_i2c.h>
  8. #include <hi_types_base.h>
  9. #include <hi_i2c.h>
  10. #include <hi_early_debug.h>
  11. #include <hi_stdlib.h>
  12. // 自定义头文件
  13. #include "i2c.h"
  14. hi_u32 iic0_write_reg(hi_u8 dev_addr, hi_u8 reg, hi_u8 val)
  15. {
  16. hi_u32 status;
  17. hi_u8 send_buff[2] = { 0 };
  18. hi_i2c_data send_data = { 0 };
  19. send_buff[0] = reg;
  20. send_buff[1] = val;
  21. send_data.send_buf = send_buff;
  22. send_data.send_len = 2;
  23. dev_addr <<= 1;
  24. status = hi_i2c_writeread(HI_I2C_IDX_0, dev_addr, &send_data);
  25. if (status != HI_ERR_SUCCESS)
  26. {
  27. return status;
  28. }
  29. return 0;
  30. }
  31. hi_u32 iic0_read_reg(hi_u8 dev_addr, hi_u8 reg)
  32. {
  33. hi_u32 status;
  34. hi_u8 send_buff[2] = { 0 };
  35. hi_u8 receive_buff[2] = { 0 };
  36. hi_i2c_data send_data = { 0 };
  37. send_buff[0] = reg;
  38. send_data.send_buf = send_buff;
  39. send_data.send_len = 1;
  40. send_data.receive_buf = receive_buff;
  41. send_data.receive_len = 1;
  42. dev_addr <<= 1;
  43. dev_addr |= 0x01;
  44. status = hi_i2c_writeread(HI_I2C_IDX_0, dev_addr, &send_data);
  45. if (status != HI_ERR_SUCCESS)
  46. {
  47. return status;
  48. }
  49. return receive_buff[0];
  50. }
  51. int iic0_init(void)
  52. {
  53. // 复用GPIO
  54. hi_io_set_func(HI_IO_NAME_GPIO_9, HI_IO_FUNC_GPIO_9_I2C0_SCL);
  55. hi_io_set_func(HI_IO_NAME_GPIO_10, HI_IO_FUNC_GPIO_10_I2C0_SDA);
  56. // 初始化iic0
  57. hi_i2c_init(HI_I2C_IDX_0, 100000);
  58. return 0;
  59. }

 main.c

  1. // 标准库
  2. #include <stdio.h>
  3. #include <unistd.h>
  4. // 第三方库
  5. #include <hi3861_platform.h>
  6. #include <hi_i2c.h>
  7. // 用户自定义
  8. #include "gpio.h"
  9. #include "adxl346.h"
  10. hi_void app_main(hi_void)
  11. {
  12. iic0_init();
  13. while(1)
  14. {
  15. sleep(1);
  16. }
  17. }

回到sdk根目录单独编译adxl346 demo

# ./build.sh adxl346

编译报错了,找不到iic初始化api,查看/build/build_tmp/下是否生成对应的中间文件,sdk编译的中间文件都在该目录下,包括编译log文件

打开内核iic编译选项 BSP Setting -> i2c driver support

./build.sh menuconfig

编译通过了

二.移植adxl346

adxl346在linux内核中自带驱动源码,有兴趣的小伙伴也可以去官网下载,附上官网链接

https://wiki.analog.com/resources/tools-software/linux-drivers/input-misc/adxl345

移植完成后

  1. int adxl346_init(void)
  2. {
  3. // 初始化adxl346
  4. iic0_write_reg(ADXL346_DEV_ADDR, POWER_CTL, 0x00);
  5. iic0_write_reg(ADXL346_DEV_ADDR, OFSX, 0x00);
  6. iic0_write_reg(ADXL346_DEV_ADDR, OFSY, 0x00);
  7. iic0_write_reg(ADXL346_DEV_ADDR, OFSZ, 0x00);
  8. iic0_write_reg(ADXL346_DEV_ADDR, THRESH_TAP, 0x31);
  9. iic0_write_reg(ADXL346_DEV_ADDR, DUR, 0x10);
  10. iic0_write_reg(ADXL346_DEV_ADDR, LATENT, 0x60);
  11. iic0_write_reg(ADXL346_DEV_ADDR, WINDOW, 0xF0);
  12. iic0_write_reg(ADXL346_DEV_ADDR, THRESH_ACT, 0x05);
  13. iic0_write_reg(ADXL346_DEV_ADDR, THRESH_INACT, 0x03);
  14. iic0_write_reg(ADXL346_DEV_ADDR, TIME_INACT, 0x04);
  15. iic0_write_reg(ADXL346_DEV_ADDR, THRESH_FF, 0x07);
  16. iic0_write_reg(ADXL346_DEV_ADDR, TIME_FF, 0x20);
  17. iic0_write_reg(ADXL346_DEV_ADDR, TAP_AXES, ADXL_TAP_X_EN | ADXL_TAP_Y_EN | ADXL_TAP_Z_EN);
  18. iic0_write_reg(ADXL346_DEV_ADDR, ACT_INACT_CTL, 0xFF);
  19. iic0_write_reg(ADXL346_DEV_ADDR, BW_RATE, 0x08);
  20. iic0_write_reg(ADXL346_DEV_ADDR, DATA_FORMAT, ADXL_FULL_RES);
  21. iic0_write_reg(ADXL346_DEV_ADDR, FIFO_CTL, DATA_READY/*ADXL_FIFO_STREAM*/);
  22. iic0_write_reg(ADXL346_DEV_ADDR, INT_MAP, 0);
  23. iic0_write_reg(ADXL346_DEV_ADDR, ORIENT_CONF, ORIENT_DEADZONE(ADXL_DEADZONE_ANGLE_10p8) | ORIENT_DIVISOR(ADXL_LP_FILTER_DIVISOR_16));
  24. iic0_write_reg(ADXL346_DEV_ADDR, POWER_CTL, PCTL_AUTO_SLEEP | PCTL_LINK | PCTL_MEASURE);
  25. return 0;
  26. }
  27. void adxl_read_data(void)
  28. {
  29. printf(" x = %d y = %d z = %d\n", iic0_read_reg(ADXL346_DEV_ADDR, DATAX0), iic0_read_reg(ADXL346_DEV_ADDR, DATAY0), iic0_read_reg(ADXL346_DEV_ADDR, DATAZ0));
  30. }

 调用初始化,轮询读取数据后,将模块沿旋转90°

  1. x = 3 y = 244 z = 217
  2. x = 4 y = 244 z = 216
  3. x = 3 y = 246 z = 218
  4. x = 6 y = 245 z = 218
  5. x = 5 y = 245 z = 217
  6. x = 1 y = 250 z = 220
  7. x = 3 y = 245 z = 216
  8. x = 19 y = 243 z = 217
  9. x = 65 y = 243 z = 215
  10. x = 110 y = 246 z = 197
  11. x = 152 y = 243 z = 174
  12. x = 190 y = 241 z = 145
  13. x = 219 y = 242 z = 107
  14. x = 243 y = 241 z = 69
  15. x = 255 y = 241 z = 27

三.配置GPIO中断使用中断方式读取

1.3861配置GPIO中断

  1. hi_void gpio_2_irq_callback(hi_void *arg)
  2. {
  3. printf("-----------------gpio_2_irq_callback\n");
  4. }
  5. int gpio_irq_init(void)
  6. {
  7. hi_gpio_init();
  8. hi_io_set_func (HI_IO_NAME_GPIO_2, HI_IO_FUNC_GPIO_2_GPIO);
  9. hi_gpio_set_dir (HI_IO_NAME_GPIO_2, HI_GPIO_DIR_IN);
  10. hi_gpio_register_isr_function(HI_IO_NAME_GPIO_2, HI_INT_TYPE_EDGE, HI_GPIO_EDGE_FALL_LEVEL_LOW, gpio_2_irq_callback, NULL);
  11. return 0;
  12. }

2.adxl346清楚中断状态,在初始化完成以及产生中断之后,都去读取一下中断状态寄存器清楚中断标志位,要不然不会产生新的中断

  1. iic0_read_reg(ADXL346_DEV_ADDR, ACT_TAP_STATUS);
  2. iic0_read_reg(ADXL346_DEV_ADDR, INT_SOURCE);
  3. iic0_read_reg(ADXL346_DEV_ADDR, ORIENT);

3.修改完成之后查看INT1引脚波形已经产生了中断信号

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/223422
推荐阅读
相关标签
  

闽ICP备14008679号