完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
MM32L0系列包含一个硬件I2C接口,支持主从模式,能控制所有符合I2C总线协议的设备。I2C可以工作在标准模式(数据传输速率为0∼100 Kbps),快速模式(数据传输速率最大为400 Kbps)。 欲了解更多详细参数包括其他功能,欢迎大家登录灵动微电子官网(www.mm23mcu.com)下载、获取相关型号的技术手册,在这里我们不做过多的描述。 I2C 总线在传送数据过程中共有三种类型信号,它们分别是:开始信号、结束信号和应答信号。 当总线处于空闲状态时,SCL和SDA同时被外部上拉电阻拉为高电平。当主机启动数据传输时,必须先产生一个起始条件。在SCL线是高电平时,SDA线从高电平向低电平切换表示起始条件。当主机结束传输时要发送停止条件。在SCL线是高电平时,SDA线由低电平向高电平切换表示停止条件。下图显示了起始和停止条件的时序图。数据传输过程中,当SCL为1时,SDA必须保持稳定。 图1 起始和停止条件 eMiniBoard板载一颗24C02,我们接下来一起进入I2C实战操作过程,通过MM32 MCU的硬件I2C接口来与24C02进行双向通信。 板级24C02的SCL和SDA分别连在MM32的PB6和PB7上,如下图所示: 图2 MM32与24C02连接图 I2C主机初始化 AMetal 平台提供了MCU的I2C初始化函数,可以直接调用初始化函数。在AMetal 中,由于用户无需关心读/写方向位的控制,因此其地址使用7-bit地址表示。 函数原型为: am_i2c_handle_t am_mm32l073_i2c1_inst_init (void) 该函数在user_config目录下的am_hwconf_mm32l073_i2c.c文件中定义,在am_mm32l073_inst_init.h中声明。因此使用I2C初始化函数时,需要包含头文件 am_mm32l073_inst_init.h。 初始化I2C,调用该函数时需要定义一个am_i2c_handle_t 类型的变量,用于保存获取的I2C 服务句柄,初始化程序为: am_i2c_handle_t i2c_handle i2c_handle = am_mm32l073_i2c1_inst_init() 获取了I2C服务句柄后,还应该有一个描述I2C从设备的结构体,构造I2C设备函数的原型为:void am_i2c_mkdev ( am_i2c_device_t *p_dev, am_i2c_handle_t handle, uint16_t dev_addr, uint16_t dev_flags)
I2C从机初始化 和MM32 MCU作为主机一样,AMetal平台也提供了作为I2C从机初始化函数, 可以直接调用初始化函数。函数原型为: am_i2c_slv_handle_t am_mm32l073_i2c1_slv_inst_init (void) 该函数在user_config目录下的am_hwconf_mm32l073_i2c_slv.c文件中定义,在 am_mm32l073_inst_init.h中声明。因此使用定时器初始化函数时,需要包含头文件 am_mm32l073_inst_init.h。 初始化I2C,调用该函数时需要定义一个am_i2c_slv_device_t 类型的变量, 用于保存获取的I2C从机服务句柄,初始化程序为: am_i2c_slv_handle_t slv_handle = am_mm32l073_i2c1_slv_inst_init () 获取了I2C服务句柄后,还应该有一个描述I2C从设备的结构体,构造I2C设备函数的原型为: void am_i2c_slv_mkdev (am_i2c_slv_device_t *p_dev, am_i2c_slv_handle_t handle, am_i2c_slv_cb_funcs_t *p_cb_funs, uint16_t dev_addr, uint16_t dev_flags, void *p_arg)
其中 p_cb_funs 指向的回调函数结构体包括:
回调函数得用户定义,如果不需要某个回调函数,可以不定义并将其函数指针指向NULL。 在AMetal中提供了实例初始化、读操作和写操作等函数接口,用户不用操作底层,直接按照规范调用相关函数即可,下面我们将结合EEPROM操作来熟悉IIC的函数接口调用。 EEPROM操 AMetal 提供I2C接口EEPROM的驱动函数,可以适配不同型号不同容量的产品,下面将以FM24C02为例予以说明,其函数原型(am_ep24cxx.h)为: am_ep24cxx_handle_t am_ep24cxx_init (am_ep24cxx_dev_t *p_dev, const am_ep24cxx_devinfo_t *p_devinfo, am_i2c_handle_t i2c_handle); 该函数意在获取器件实例句柄 24c02_handle,其中p_dev为指向 am_ep24cxx_dev_t类型实例的指针,p_devinfo为指向 am_ep24cxx_devinfo_t 类型实例信息的指针。 01 实例 单个FM24C02可以看作EP24Cxx的一个实例,EP24Cxx只是抽象了代表一个系列或同种类型的E²PROM芯片,显然多个24C02是EP24Cxx的多个实例。如果I2C总线上只外接一个FM24C02,定义 am_ep24cxx_dev_t 类型(am_ep24cxx.h)实例如下: am_ep24cxx_handle_t am_ep24cxx_init (am_ep24cxx_dev_t *p_dev, const am_ep24cxx_devinfo_t *p_devinfo, am_i2c_handle_t i2c_handle) 其中,g_at24c02_dev为用户自定义的实例,其地址作为p_dev的实参传递。如果同一个 I2C 总线上外接了2个FM24C02,需要定义 2 个实例。即:am_ep24cxx_dev_t g_24c02_dev0 am_ep24cxx_dev_t g_24c02_dev1 每个实例都要初始化,其每个实例的初始化均会返回一个该实例的handle,便于使用其它接口函数时,传递不同的handle操作不同的实例。 01实例信息 实例信息主要描述了具体器件固有的信息,即 I2C 器件的从机地址和具体型号,其类型am_ep24cxx_devinfo_t 的定义(am_ep24cxx.h)如下: typedef struct am_ep24cxx_devinfo { uint8_t slv_addr; uint32_t type; } am_ep24cxx_devinfo_t; 当前已经支持的器件型号均在 am_ep24cxx.h 中定义了对应的宏, 比如, FM24C02 对应的宏为 AM_EP24CXX_FM24C2,实例信息定义如下: const am_ep24cxx_devinfo_t _g_24c02_devinfo = { 0x50; AM_EP24CXX_FM24C02 } 其中,g_24c02_devinfo为用户自定义的实例信息,其地址作为p_devinfo的实参传递。 02 I2C 句柄 I2C_handle 以I2C1为例, 其实例初始化函数 am_mm32l073_i2c1_inst_init()的返回值将作为实参传递给i2c_handle。即: i2c_handle = am_mm32l073_i2c1_inst_init() 03 实例句柄 fm24c02_handle FM24C02初始化函数 am_ep24cxx_init()的返回值 fm24c02_handle,作为实参传递给读ARM 嵌入式软件工程方法和实践: 写数据函数,其类型 am_ep24cxx_handle_t(am_ep24cxx.h)定义如下: typedef struct am_ep24cxx_dev *am_ep24cxx_handle_t 若返回值为NULL,说明初始化失败;若返回值不为NULL,说明返回一个有效的 handle。 基于模块化编程思想,将初始化相关的实例信息等的定义存放到对应的配置文件中,通过头文件引出实例初始化函数接口。 实例初始化函数范例程序: #include "ametal.h" #include "am_ep24cxx.h" #include "am_mm32l073_inst_init.h" static const am__ep24cxx_devinfo_t __g_24c02_devinfo = { } static am_ep24cxx_dev_t __g_24c02_dev; //定义 FM24C02 器件实例 am_ep24cxx_handle_t am_fm24c02_inst_init(void) { am_i2c_handle_t i2c_handle =am_mm32l073_i2c1_inst_init(); return am_ep24cxx_init(&__g_24c02_dev, &__g_24c02_devinfo, i2c_handle); } 实例初始化函数接口: #pragma once #include "ametal.h" #include "am_ep24cxx.h" am_ep24cxx_handle_t am_fm24c02_inst_init(void); 后续只需要使用无参数的实例初始化函数,即可获取到 FM24C02 的实例句柄。即: am_ep24cxx_handle_t fm24c02_handle =am_fm24c02_inst_init(); 注意, i2c_handle 用于区分 I2C0、 I2C1、 I2C2、 I2C3,初始化函数返回值实例句柄用于区分同一系统中连接多个器件。
各 API 的返回值含义都是相同的:AM_OK 表示成功,负值表示失败,失败原因可根据具体的值查看 am_errno.h 文件中相对应的宏定义。正值的含义由各 API 自行定义,无特殊说明时,表明不会返回正值。 02 数据读写 01 写入数据 从指定的地址开始写入一段数据的函数原型为: int am_ep24cxx_write (am_ep24cxx_handle_t handle, int start_addr, uint8_t *p_buf, int len); 如果返回值为AM_OK,则说明写入成功,反之失败。假定从0x20地址开始,连续写入16字节。 写入数据范例程序:uint8_t data[16] = {0,1,2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15}; am_ep24cxx_write(fm24c02_handle, 0x20, &data[0],16); 02 读取数据 从指定的起始地址开始读取一段数据的函数原型为: int am_ep24cxx_read (am_ep24cxx_handle_t handle, int start_addr, uint8_t *p_buf, int len); 如果返回值为 AM_OK,则说明读取成功,反之失败。假定从 0x20 地址开始,连续读取数据范例程序为: uint8_t data[16]; am_ep24cxx_read(fm24c02_handle, 0x20, &data[0],16); 03 应用实例 E2PROM 读写测试, 向存储器写入20个字节数据再读出来,然后校验是否读写正常的范例。 #include "ametal.h" #include "am_led.h" #include "am_delay.h" #include "am_mm32l073_inst_init.h" #include "am_ep24cxx.h" #include "am_hwconf_ep24cxx.h" int app_test_ep24cxx(am_ep24cxx_handle_t handle) { int i; uint8_t data[20]; for(i=0;i<20;i++) //填充数据 data=i; am_ep24cxx_write(handle,0,&data[0],20); //从 0 地址开始,连续写入 20 字节数据16 for(i=0;i<20;i++) //清零数据 data=0; am_ep24cxx_read(handle,0,&data[0],20); //从 0 地址开始,连续读出 20 字节数据19 for(i=0;i<20;i++) { //比较数据 if(data!=i) return AM_ERROR; } return AM_OK; } int am_main(void) { am_ep24cxx_handle_t fm24c02_handle =am_fm24c02_inst_init();//获取24C02初始化实例句柄 if(app_test_ep24cxx(fm24c02_handle)!=AM_OK) { am_led_on(0); } while(1) { am_led_toggle(0);//翻转 LED am_mdelay(100); } } app_test_ep24cxx()的参数为实例 handle,与EP24Cxx器件具有依赖关系,因为没办法实现全兼容调用,用户可根据EEPROM信息设置对应的参数。 上述是基于MM32L073的硬件IIC操作EEPROM实例,在《AMetal从入门到实践》一书中有详细描述IIC接口的主、从机配置方式及操作流程,用户可以下载相关资料熟悉。下一章节我们将进入到基于AMetal平台SPI控制,欢迎大家支持阅览,谢谢! |
|
相关推荐
|
|
只有小组成员才能发言,加入小组>>
2252个成员聚集在这个小组
加入小组灵动微电子MM32全系列MCU产品应用手册,库函数和例程和选型表
11816 浏览 3 评论
【MM32 eMiniBoard试用连载】+基于OLED12864的GUI---U8G2
5972 浏览 1 评论
【MM32 eMiniBoard试用连载】移植RT-Thread至MM32L373PS
11114 浏览 0 评论
【MM32 eMiniBoard测评报告】+ 开箱 + 初探
4593 浏览 1 评论
灵动微课堂(第106讲) | MM32 USB功能学习笔记 —— WinUSB设备
4325 浏览 1 评论
[MM32软件] MM32F002使用内部flash存储数据怎么操作?
1269浏览 1评论
845浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-23 00:25 , Processed in 0.417065 second(s), Total 40, Slave 32 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号