历史上的今天
今天是:2025年08月16日(星期六)
2019年08月16日 | 14-HAL库之I2C通信
2019-08-16 来源:eefocus
1.I2C协议介绍
I2C是一个支持多设备的总线,可连接多个I2C通讯设备,每个总线包括一条双向串行数据线(SDA)和一条串行时钟线(SCL)。数据线用来表示数据,时钟线用来数据收发同步。通讯过程如下:

S:主机的I2C接口产生的传输开始信号,连接在I2C总线上的所有从机都会接收到。
SLAVE_ADDRESS:主机广播的从机地址信号,I2C总线上每个从机地址唯一。
R/W:读写方向,置1为读,置0为写。
A/A-:从机接收到匹配的地址后,主机或从机会返回一个应答信号或非应答信号,只有接收到应答信号主机才继续发送接收数据。写数据的时候,每次发送一个字节数据(DATA:8位)后,都要等待应答信号,重复这个过程可以发送N个数据。数据传输结束发送停止传输信号P。读数据时,主机向从机发应答信号,当主机希望停止接收数据时,发送非应答信号。

起始信号和停止信号见上图。

数据有效性见上图。
2.基于HAL库的I2C配置
步骤:时钟使能—GPIO管脚配置—I2C配置

初始化:
void MyI2C_Init(void){
__HAL_RCC_GPIOB_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Pin = GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_MODE_AF_OD;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF4_I2C1;
HAL_GPIO_Init(GPIOB,&GPIO_InitStruct);
//I2C_SCL config
GPIO_InitStruct.Pin = GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_MODE_AF_OD;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF4_I2C1;
HAL_GPIO_Init(GPIOB,&GPIO_InitStruct);
//I2C_SDA config
__HAL_RCC_I2C1_CLK_ENABLE();
I2C_HandleTypeDef MyI2C1;
MyI2C1.Instance=I2C1;
MyI2C1.Init.Timing=0x60201E2B;//100KHz
MyI2C1.Init.OwnAddress1=0;
MyI2C1.Init.AddressingMode=I2C_ADDRESSINGMODE_7BIT;
MyI2C1.Init.DualAddressMode=I2C_DUALADDRESS_DISABLE;
MyI2C1.Init.OwnAddress2=0;
MyI2C1.Init.OwnAddress2Masks=I2C_OA2_NOMASK;
MyI2C1.Init.GeneralCallMode=I2C_GENERALCALL_DISABLE;
MyI2C1.Init.NoStretchMode=I2C_NOSTRETCH_DISABLE;
MyI2C1.Mode=HAL_I2C_MODE_MASTER;
HAL_I2C_Init(&MyI2C1);
}
输入输出函数:
阻塞模式:
HAL_I2C_Master_Transmit(); HAL_I2C_Master_Receive(); HAL_I2C_Slave_Transmit(); HAL_I2C_Slave_Receive()
HAL_I2C_Mem_Write(); HAL_I2C_Mem_Read(); HAL_I2C_IsDeviceReady()
带中断非阻塞模式:
HAL_I2C_Master_Transmit_IT(); HAL_I2C_Master_Receive_IT(); HAL_I2C_Slave_Transmit_IT()
HAL_I2C_Slave_Receive_IT(); HAL_I2C_Mem_Write_IT(); HAL_I2C_Mem_Read_IT()
DMA传输非阻塞模式:
HAL_I2C_Master_Transmit_DMA(); HAL_I2C_Master_Receive_DMA(); HAL_I2C_Slave_Transmit_DMA(); HAL_I2C_Slave_Receive_DMA(); HAL_I2C_Mem_Write_DMA(); HAL_I2C_Mem_Read_DMA()
非阻塞模式下的回调函数:
HAL_I2C_MemTxCpltCallback(); HAL_I2C_MemRxCpltCallback(); HAL_I2C_MasterTxCpltCallback()
HAL_I2C_MasterRxCpltCallback(); HAL_I2C_SlaveTxCpltCallback(); HAL_I2C_SlaveRxCpltCallback(); HAL_I2C_ErrorCallback()
这部分可以参照USART中的函数进行理解。
上一篇:13-HAL库DMA系统总结
下一篇:15-HAL库之定时器学习
史海拾趣
|
近年来LED驱动由线性调整型(LDO)、电荷泵型向开关型转变,在效率、电流驱动能力方面有了长足进步,效率也大幅提高。随着半导体工艺的进步,特别是高压MOSFET和BCD技术的不断提高,一些外围功率开关管和二极管也被集成进了驱动芯片,使外围电路大大 ...… 查看全部问答> |
|
有没有从事EMS开发的TX 一直找不到比较专业的论坛,建立了一个GROUP,大家有兴趣就看看吧。希望能一起讨论EMS或者SNMP开发的话题。 您收到此信息是由于您订阅了 Google 论坛“EMS网管开发”论坛。 要在此论坛发帖,请发电子邮件到 ems-nms@go ...… 查看全部问答> |
|
Win9x_ME, Win2000_XP的驱动怎么在WinCE上面使用? 目前有个触摸显示器,我想用到我的板子上,s3c2440a+WinCE。但是此触摸显示器 的驱动支持WINNT,ME,9X,2000,Xp,就是不支持WINCE。 请问高手能否对现有的驱动进行改动后让它能够支持WINCE?如何改动? 还有我通过depends查看驱动内的dll文件, ...… 查看全部问答> |
|
各位高手: 不好意思,摄像头问题又有变化,小弟愚钝,只能求救于大家了! 我的摄像头打开时,LCD显示器在固定的几处出现较为明显的细条纹,或一条一处,或多条一处,颜色与周围的不连续,导致图像看 ...… 查看全部问答> |
|
请教大侠: 为了将nor flash从32M升级到64M,我修改了EBOOT中的flashWrite和flashErase 函数 并且修改了OEMaddressTable 其他都没修改 但是现在把boot烧写到FLASH中,不能从汇编进入到C文件中 以下是我以前的OEMAddressTable: OEMAddressTabl ...… 查看全部问答> |
|
尤其是1st of 10 req\'d task args to pass to func ,就是最后输入参数的10个有什么作用,刚看了英语解释,不是很懂,谢谢… 查看全部问答> |
|
单片机连接gprs模块(装有sim卡),想让手机给模块发短信,那么怎么样才能让单片机知道来了短信 单片机连接gprs模块(装有sim卡),想让手机给模块发短信,那么怎么样才能让单片机知道来了短信?并知道短信序号从而成功读取呢》? 我知道用at+cnmi可以设置短消息提示方式,但是如果是超级终端,短信来了,可以看见提示的是哪一条,从而可以立刻 ...… 查看全部问答> |
|
我用的是fedora10,配置samba是按着国嵌视频的方法配置的。我上网接的路由IP192.168.1.1,我的IP是192.168.1.100,我fedora设的是192.168.1.44。。虚拟机可以上网。win7上ping虚拟机linux可以通,但是linux ping win7可以ping的通,但进入死循环没 ...… 查看全部问答> |




