飞道的博客

HaaS EDU K1设备资源 之 IIC

294人阅读  评论(0)

1、概述

IIC(Inter-Integrated Circuit)总线是一种由PHILIPS公司开发的两线式串行总线,用于连接微控制器及其外围设备。它是由数据线SDA和时钟SCL构成的串行总线,可发送和接收数据。在CPU与被控IC之间、IC与IC之间进行双向传送,高速IIC总线一般可达400kbps以上。

 

I2C总线在传送数据过程中共有三种类型信号, 它们分别是:开始信号、结束信号和应答信号。

开始信号:SCL为高电平时,SDA由高电平向低电平跳变,开始传送数据。

结束信号:SCL为高电平时,SDA由低电平向高电平跳变,结束传送数据。

应答信号:接收数据的IC在接收到8bit数据后,向发送数据的IC发出特定的低电平脉冲,表示已收到数据。CPU向受控单元发出一个信号后,等待受控单元发出一个应答信号,CPU接收到应答信号后,根据实际情况作出是否继续传递信号的判断。若未收到应答信号,由判断为受控单元出现故障。IIC总线如图所示:

                                                                   IIC总线时序图

 

2、资源介绍

HaaS1000中自带了两路I2C,主模式最高1.4Mbps接口。两路I2C管脚也是复用的,都是通过IO的fuction选择出来的。当前的HaaS EDU K1的默认配置为:

引脚名

GPIO

说明

I2C_M0_SCL

GPIO_P2_0

i2C0的SCL

I2C_M0_SDA

GPIO_P2_1

i2C0的SDA

I2C_M1_SCL

GPIO_P0_2

I2C1的SCL

I2C_M1_SDA

GPIO_P0_3

I2C1的SDA

HaaS EDU K1中只用到的了I2C1, 即(GPIO_P0_2,GPIO_P0_3),HaaS EDU K1上所有的传感器都是接在I2C1,每个传感器的地址是不同的。

 

3、HAL接口介绍

AliOS Things对于不同底层驱动的i2c操作实现,统一封装成本文所述hal I2c接口。 hal相关头文件位于目录:include/aos/hal。hal相关实现位于具体的mcu目录下,如:platform/mcu/haas1000/hal/。

3.1、API列表

hal_i2c_init

初始化指定I2C端口

hal_i2c_master_send

master模式下从指定的I2C端口发送数据

hal_i2c_master_recv

master模式下从指定的I2C端口接收数据

hal_i2c_slave_send

slave模式下从指定的I2C端口发送数据

hal_i2c_slave_recv

slave模式下从指定的I2C端口接收数据

hal_i2c_mem_write

mem模式(读写I2C存储器)下从指定的I2C端口发送数据

hal_i2c_mem_read

mem模式(读写I2C存储器)下从指定的I2C端口接收数据

hal_i2c_finalize

关闭指定I2C端口

 

3.2、API详情

请参考include/aos/hal/i2c.h

 

3.2.1、相关宏定义


  
  1. #define I2C_MODE_MASTER 1 /* i2c communication is master mode */
  2. #define I2C_MODE_SLAVE  2 /* i2c communication is slave mode */
  3. #define I2C_MEM_ADDR_SIZE_8BIT  1 /* i2c memory address size 8bit */
  4. #define I2C_MEM_ADDR_SIZE_16BIT 2 /* i2c memory address size 16bit */
  5. /*
  6.  * Specifies one of the standard I2C bus bit rates for I2C communication
  7.  */
  8. #define I2C_BUS_BIT_RATES_100K  100000
  9. #define I2C_BUS_BIT_RATES_400K  400000
  10. #define I2C_BUS_BIT_RATES_3400K 3400000
  11. #define I2C_HAL_ADDRESS_WIDTH_7BIT  0
  12. #define I2C_HAL_ADDRESS_WIDTH_10BIT 1

 

3.2.2、相关结数据结构

i2c_dev_t


  
  1. typedef struct {
  2.     uint8_t      port;   /* i2c port */
  3.     i2c_config_t config; /* i2c config */
  4.     void        *priv;   /* priv data */
  5. } i2c_dev_t;

i2c_config_t


  
  1. typedef struct {
  2.     uint32_t address_width;
  3.     uint32_t freq;
  4.     uint8_t  mode;
  5.     uint16_t dev_addr;
  6. } i2c_config_t;

 

3.2.3、hal_i2c_init

初始化指定I2C端口

函数原型

int32_t hal_i2c_init(i2c_dev_t *i2c)

参数

i2c_dev_t *i2c

入参

I2C设备描述,定义需要初始化的I2C参数

用户自定义一个i2c_dev_t结构体

返回值

返回成功或失败, 返回0表示I2C初始化成功,非0表示失败

调用示例


  
  1. #define I2C1_PORT_NUM  1
  2. #define I2C2_PORT_NUM  2
  3. #define I2C2_SLAVE_ADDR  0x50
  4. /* define dev master */
  5. i2c_dev_t i2c_dev_master;
  6. i2c_dev_t i2c_dev_slave;
  7. /* i2c port set */
  8. i2c_dev_master.port = I2C1_PORT_NUM;
  9. /* i2c attr config */
  10. i2c_dev_master.config.mode          = I2C_MODE_MASTER;
  11. i2c_dev_master.config.freq          = I2C_BUS_BIT_RATES_3400K;
  12. i2c_dev_master.config.address_width = I2C_HAL_ADDRESS_WIDTH_7BIT;
  13. i2c_dev_slave.port = I2C2_PORT_NUM;
  14. /* i2c attr config */
  15. i2c_dev_slave.config.mode          = I2C_MODE_SLAVE;
  16. i2c_dev_slave.config.freq          = I2C_BUS_BIT_RATES_3400K;
  17. i2c_dev_slave.config.address_width = I2C_HAL_ADDRESS_WIDTH_7BIT;
  18. i2c_dev_slave.config.dev_addr     = I2C2_SLAVE_ADDR;
  19. /* init master i2c with the given settings */
  20. ret = hal_i2c_init(&i2c_dev_master);
  21. /* init slave i2c with the given settings */
  22. ret = hal_i2c_init(&i2c_dev_slave);

 

3.2.4、hal_i2c_master_send

master模式下从指定的I2C端口发送数据

函数原型

int32_t hal_i2c_master_send(i2c_dev_t *i2c, uint16_t dev_addr, const uint8_t *data, uint16_t size, uint32_t timeout)

参数

i2c_dev_t *i2c

入参

I2C设备描述

使用hal_i2c_init传入参数

uint16_t dev_addr

入参

目标设备地址

0x50

const uint8_t *data

入参

指向发送缓冲区的数据指针

char pdata_send[10]

uint16_t size

入参

要发送的数据字节数

10

uint32_t timeout

入参

超时时间(单位ms),如果希望一直等待设置为HAL_WAIT_FOREVER

50

返回值

返回成功或失败, 返回0表示I2C数据发送成功,非0表示失败

调用示例


  
  1. char pdata_send[ 10] = { 0};
  2. #define I2C2_SLAVE_ADDR  0x50
  3. ret = hal_i 2c_master_send(&i 2c_dev_master,I 2C 2_SLAVE_ADDR,pdata_send, 10, 50);


3.2.5、hal_i2c_master_recv

master模式下从指定的I2C端口接收数据

函数原型

int32_t hal_i2c_master_recv(i2c_dev_t *i2c, uint16_t dev_addr, uint8_t *data,uint16_t size, uint32_t timeout)

参数

i2c_dev_t *i2c

入参

I2C设备描述

使用hal_i2c_init传入参数

uint16_t dev_addr

入参

目标设备地址

0x50

uint8_t *data

入参

指向接收缓冲区的数据指针

char pdata_recv[10]

uint16_t size

入参

期望接收的数据字节数

10

uint32_t timeout

入参

超时时间(单位ms),如果希望一直等待设置为HAL_WAIT_FOREVER

50

返回值

返回成功或失败, 返回0表示成功接收size个数据,非0表示失败

调用示例


  
  1. char pdata_recv[ 10] = { 0};
  2. #define I2C2_SLAVE_ADDR  0x50
  3. ret = hal_i 2c_master_recv(&i 2c_dev_master,I 2C 2_SLAVE_ADDR,pdata_recv, 10, 50);

 

3.2.6、hal_i2c_slave_send

slave模式下从指定的I2C端口发送数据

函数原型

int32_t hal_i2c_slave_send(i2c_dev_t *i2c, const uint8_t *data, uint16_t size, uint32_t timeout)

参数

i2c_dev_t *i2c

入参

I2C设备描述

使用hal_i2c_init传入参数

const uint8_t *data

入参

指向发送缓冲区的数据指针

char pdata_send[10]

uint16_t size

入参

要发送的数据字节数

10

uint32_t timeout

入参

超时时间(单位ms),如果希望一直等待设置为HAL_WAIT_FOREVER

50

返回值

返回成功或失败, 返回0表示成功发送size个数据,非0表示失败

调用示例


  
  1. char pdata_send[ 10] = { 0};
  2. ret = hal_i 2c_slave_send(&i 2c_dev_slave,pdata_send, 10, 50);

 

3.2.7、hal_i2c_slave_recv

slave模式下从指定的I2C端口接收数据

函数原型

int32_t hal_i2c_slave_recv(i2c_dev_t *i2c, uint8_t *data, uint16_t size, uint32_t timeout)

参数

i2c_dev_t *i2c

入参

I2C设备描述

使用hal_i2c_init传入参数

uint8_t *data

入参

指向要接收数据的数据指针

char pdata_recv[10]

uint16_t size

入参

要接收的数据字节数

10

uint32_t timeout

入参

超时时间(单位ms),如果希望一直等待设置为HAL_WAIT_FOREVER

50

返回值

返回成功或失败, 返回0表示成功接收size个数据,非0表示失败

调用示例


  
  1. char pdata_recv[ 10] = { 0};
  2. ret = hal_i 2c_slave_recv(&i 2c_dev_slave,pdata_recv, 10, 50);

 

3.2.8、hal_i2c_mem_write

向指定的设备内存写数据

函数原型

int32_t hal_i2c_mem_write(i2c_dev_t *i2c, uint16_t dev_addr, uint16_t mem_addr, uint16_t mem_addr_size, const uint8_t *data, uint16_t size, uint32_t timeout)

参数

i2c_dev_t *i2c

入参

I2C设备描述

使用hal_i2c_init传入参数

uint16_t dev_addr

入参

目标设备地址

0x50

uint16_t mem_addr

入参

内部内存地址

0x20

uint16_t mem_addr_size

入参

内部内存地址大小

1

const uint8_t *data

入参

指向要发送数据的数据指针

char pdata[10]

uint16_t size

入参

要发送的数据字节数

1

uint32_t timeout

入参

超时时间(单位ms),如果希望一直等待设置为HAL_WAIT_FOREVER

50

返回值

返回成功或失败, 返回0表示成功发送size个数据,非0表示失败

调用示例


  
  1. char pdata[ 10] = { 0};
  2. ret = hal_i 2c_mem_write(&i 2c_dev_master, 0x 50, 0x 20, 1,pdata, 1, 50);

 

3.2.9、hal_i2c_mem_read

从指定的设备内存读数据

函数原型

int32_t hal_i2c_mem_read(i2c_dev_t *i2c, uint16_t dev_addr, uint16_t mem_addr, uint16_t mem_addr_size, uint8_t  *data, uint16_t size, uint32_t timeout)

参数

i2c_dev_t *i2c

入参

I2C设备描述

使用hal_i2c_init传入参数

uint16_t dev_addr

入参

目标设备地址

0x50

uint16_t mem_addr

入参

内部内存地址

0x20

uint16_t mem_addr_size

入参

内部内存地址大小

1

uint8_t *data

入参

指向接收缓冲区的数据指针

char pdata[10]

uint16_t size

入参

要接收的数据字节数

1

uint32_t timeout

入参

超时时间(单位ms),如果希望一直等待设置为HAL_WAIT_FOREVER

50

返回值

返回成功或失败, 返回0表示成功接收size个数据,非0表示失败

调用示例


  
  1. char pdata[ 10] = { 0};
  2. ret = hal_i 2c_mem_read(&i 2c_dev_master, 0x 50, 0x 20, 1,pdata, 1, 50);

 

3.2.10、hal_i2c_finalize

关闭指定I2C端口

函数原型

int32_t hal_i2c_finalize(i2c_dev_t *i2c)

参数

i2c_dev_t *i2c

入参

I2C设备描述

使用hal_i2c_init传入参数

返回值

类型:int 返回成功或失败, 返回0表示I2C关闭成功,非0表示失败。

调用示例

ret = hal_i2c_finalize(&i2c_dev_master);

 

4、案例介绍

HaaS EDU K1上自带了多个传感器,均为I2C方式访问,这里我们选取温湿度SI7006的测试代码用来介绍I2C是如何运作的。

 

4.1、硬件实现

硬件电路在开发板上默认是已经连接好了的,默认的I2C地址为0x40。。原理图如下:

                     EDU SI7006部分原理图

 

4.2、软件设计

驱动代码位于platform/board/haaseduk1/drivers/i2c.c

I2C部分测试代码位于 application/example/edu_demo/mfg_test/sensors_test.c

获取ID


  
  1. si7006_getID(id_buf);
  2. if (id_buf[ 4] == Si7006_TAG){
  3.     LOGI( "si7006_test", "READ Si7006 Chip OK");
  4. }

IIC驱动代码


  
  1. void si7006_init(void)
  2. {
  3. i2c_dev.port = 1;
  4. i2c_dev.config.address_width = I2C_HAL_ADDRESS_WIDTH_7BIT;
  5. i2c_dev.config.freq = I2C_BUS_BIT_RATES_400K;
  6. i2c_dev.config.mode = I2C_MODE_MASTER;
  7. i2c_dev.config.dev_addr = Si7006_ADDRESS;
  8. hal_i2c_init(&i2c_dev);
  9. }
  10. uint8_t si7006_getVer(void)
  11. {
  12. uint8_t reg[ 2] = {Si7006_READ_Firmware_Revision_0,Si7006_READ_Firmware_Revision_1};
  13. uint8_t version = 0;
  14. hal_i2c_master_send(&i2c_dev, i2c_dev.config.dev_addr, reg, 2, 1000);
  15. aos_msleep( 30);
  16. hal_i2c_master_recv(&i2c_dev, i2c_dev.config.dev_addr, &version, 1, 1000);
  17. //LOGI("APP", "ver:0x%2x \n",version);
  18. return version;
  19. }

 

4.3、编译与下载

4.3.1、代码准备

打开edu_demo的产测开关

application/example/edu_demo/Config.in

在该文件中修改编译选项,打开EDK_DEMO_FACTORY_TEST_ENABLIE开关。


  
  1. config EDK_DEMO_FACTORY_TEST_ENABLIE
  2.     bool "enable factory test function"
  3.     default y

 

加入Demo到启动代码

application/example/edu_demo/app_entry.c

函数application_start中注释掉menu_init();,添加sensors_test(); 


  
  1.        //menu_init();
  2. sensors_test();

 

4.3.2、编译

如下使用命令行方式


  
  1. aos make distclean
  2. aos make edu_demo@haaseduk1 -c config
  3. aos make

4.3.3、烧录

  • 命令行方式
aos upload
  • 图形界面方式

详见haaS EDU k1 快速开始 第4.3.3章节-使用GUI工具烧录部分。

 

开发者技术支持

如需更多技术支持,可加入钉钉开发者群,或者关注微信公众号

更多技术与解决方案介绍,请访问阿里云AIoT首页https://iot.aliyun.com/


转载:https://blog.csdn.net/HaaSTech/article/details/114677894
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场