hi3861使用iic驱动adxl346

Posted 耳 东

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hi3861使用iic驱动adxl346相关的知识,希望对你有一定的参考价值。

开发平台

Ubuntu 18.04

DOPI  hi3861lv开发板、adxl346模组

Q群:735884031

一.配置3861iic

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

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

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

/Hi3861V100R001C00SPC025/app/adxl346$ tree
.
├── app.json
├── iic
│   ├── iic.c
│   ├── iic.h
│   └── SConscript
├── SConscript
└── src
    ├── main.c
    └── SConscript

iic.c

// 标准库
#include <stdio.h>
#include <unistd.h>

// 第三方库
#include <hi3861_platform.h>
#include <hi_io.h>
#include <hi_i2c.h>
#include <hi_types_base.h>
#include <hi_i2c.h>
#include <hi_early_debug.h>
#include <hi_stdlib.h>

// 自定义头文件
#include "i2c.h"

hi_u32 iic0_write_reg(hi_u8 dev_addr, hi_u8 reg, hi_u8 val)
{
	hi_u32 status;
	hi_u8 send_buff[2] 	  = { 0 };
	hi_i2c_data send_data = { 0 };

	send_buff[0] = reg;
	send_buff[1] = val;

	send_data.send_buf = send_buff;
	send_data.send_len = 2;

	dev_addr <<= 1;
	status = hi_i2c_writeread(HI_I2C_IDX_0, dev_addr, &send_data);
	if (status != HI_ERR_SUCCESS)
	{
		return status;
	}
	return 0;
}

hi_u32 iic0_read_reg(hi_u8 dev_addr, hi_u8 reg)
{
	hi_u32 status;
	hi_u8 send_buff[2] 	  	= { 0 };
	hi_u8 receive_buff[2] 	= { 0 };
	hi_i2c_data send_data 	= { 0 };

	send_buff[0] = reg;
	send_data.send_buf = send_buff;
	send_data.send_len = 1;
	send_data.receive_buf = receive_buff;
	send_data.receive_len = 1;

	dev_addr <<= 1;
	dev_addr |= 0x01;
	status = hi_i2c_writeread(HI_I2C_IDX_0, dev_addr, &send_data);
	if (status != HI_ERR_SUCCESS)
	{
		return status;
	}
	return receive_buff[0];
}



int iic0_init(void)
{
	// 复用GPIO
    hi_io_set_func(HI_IO_NAME_GPIO_9, 	HI_IO_FUNC_GPIO_9_I2C0_SCL);
    hi_io_set_func(HI_IO_NAME_GPIO_10, 	HI_IO_FUNC_GPIO_10_I2C0_SDA);
	
	// 初始化iic0
	hi_i2c_init(HI_I2C_IDX_0, 100000);
	return 0;
}

 main.c


// 标准库
#include <stdio.h>
#include <unistd.h>

// 第三方库
#include <hi3861_platform.h>
#include <hi_i2c.h>


// 用户自定义
#include "gpio.h"
#include "adxl346.h"

hi_void app_main(hi_void)
{
	iic0_init();
 	while(1)
	{
		sleep(1);
	}
}

回到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

移植完成后

int adxl346_init(void)
{
	// 初始化adxl346
	iic0_write_reg(ADXL346_DEV_ADDR, POWER_CTL, 	0x00);
	iic0_write_reg(ADXL346_DEV_ADDR, OFSX, 			0x00);
	iic0_write_reg(ADXL346_DEV_ADDR, OFSY, 			0x00);
	iic0_write_reg(ADXL346_DEV_ADDR, OFSZ, 			0x00);
	iic0_write_reg(ADXL346_DEV_ADDR, THRESH_TAP, 	0x31);
	iic0_write_reg(ADXL346_DEV_ADDR, DUR, 			0x10);
	iic0_write_reg(ADXL346_DEV_ADDR, LATENT, 		0x60);
	iic0_write_reg(ADXL346_DEV_ADDR, WINDOW, 		0xF0);
	iic0_write_reg(ADXL346_DEV_ADDR, THRESH_ACT,	0x05);
	iic0_write_reg(ADXL346_DEV_ADDR, THRESH_INACT,	0x03);
	iic0_write_reg(ADXL346_DEV_ADDR, TIME_INACT,	0x04);
	iic0_write_reg(ADXL346_DEV_ADDR, THRESH_FF,		0x07);
	iic0_write_reg(ADXL346_DEV_ADDR, TIME_FF,		0x20);
	iic0_write_reg(ADXL346_DEV_ADDR, TAP_AXES,		ADXL_TAP_X_EN | ADXL_TAP_Y_EN | ADXL_TAP_Z_EN);
	iic0_write_reg(ADXL346_DEV_ADDR, ACT_INACT_CTL,	0xFF);
	iic0_write_reg(ADXL346_DEV_ADDR, BW_RATE,		0x08);
	iic0_write_reg(ADXL346_DEV_ADDR, DATA_FORMAT,	ADXL_FULL_RES);
	iic0_write_reg(ADXL346_DEV_ADDR, FIFO_CTL,		DATA_READY/*ADXL_FIFO_STREAM*/);
	iic0_write_reg(ADXL346_DEV_ADDR, INT_MAP,		0);
	iic0_write_reg(ADXL346_DEV_ADDR, ORIENT_CONF,	ORIENT_DEADZONE(ADXL_DEADZONE_ANGLE_10p8) | ORIENT_DIVISOR(ADXL_LP_FILTER_DIVISOR_16));
	iic0_write_reg(ADXL346_DEV_ADDR, POWER_CTL,		PCTL_AUTO_SLEEP | PCTL_LINK | PCTL_MEASURE);
	return 0;
}


void adxl_read_data(void)
{
	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));
}

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


 x = 3  y = 244  z = 217
 x = 4  y = 244  z = 216
 x = 3  y = 246  z = 218
 x = 6  y = 245  z = 218
 x = 5  y = 245  z = 217
 x = 1  y = 250  z = 220
 x = 3  y = 245  z = 216
 x = 19  y = 243  z = 217
 x = 65  y = 243  z = 215
 x = 110  y = 246  z = 197
 x = 152  y = 243  z = 174
 x = 190  y = 241  z = 145
 x = 219  y = 242  z = 107
 x = 243  y = 241  z = 69
 x = 255  y = 241  z = 27

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

1.3861配置GPIO中断

hi_void gpio_2_irq_callback(hi_void *arg)
{
	printf("-----------------gpio_2_irq_callback\\n");
}

int gpio_irq_init(void)
{
	hi_gpio_init();
    hi_io_set_func	(HI_IO_NAME_GPIO_2, HI_IO_FUNC_GPIO_2_GPIO);
	hi_gpio_set_dir	(HI_IO_NAME_GPIO_2, HI_GPIO_DIR_IN);
	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);
	return 0;
}

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

iic0_read_reg(ADXL346_DEV_ADDR, ACT_TAP_STATUS);
iic0_read_reg(ADXL346_DEV_ADDR, INT_SOURCE);
iic0_read_reg(ADXL346_DEV_ADDR, ORIENT);

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

 

以上是关于hi3861使用iic驱动adxl346的主要内容,如果未能解决你的问题,请参考以下文章

hi3861使用iic驱动adxl346

使用Hi3861驱动交流电机变频器方法简介

HI3861学习笔记(17)——NFC标签NT3H1201使用

用Hi3861-wifi联网下载播放wav音乐 - 基于Harmony2.0

HI3861学习笔记——编译构建和代码运行过程

Hi3861 业务代码编写框架