打印
[STM32F1]

【转】 STM32硬件IIC操作

[复制链接]
734|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
一灯大神|  楼主 | 2016-11-27 23:28 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

Stm32具有IIC接口,接口有以下主要特性

多主机功能:该模块既可做主设备也可做从设备

主设备功能

C地址检测

产生和检测7位/10位地址和广播呼叫

支持不同的通讯速度

状态标志:

发送器/接收器模式标志

字节发送结束标志

总线忙标志

错误标志

2个中断向量

可选的拉长时钟功能

具单字节缓冲器的DMA

虽然很多人说STM的硬件IIC不好用,但是对于这么一个设备去探索一下还是很有必要的,指不定哪天就用上了呢,

IIC借口一共有九个寄存器,比较重要的几个寄存器分别如下

1.       CR1


由这几个位我们可以正常产生标准IIC的START条件STOP条件,ACK与NOACK

CR2


控制IIC的通行频率

这两位检测IIC总线是否收到数据


1.       对于硬件IIC的初始化流程包括

1.       配置IO口,配置为GPIO_Mode_AF_OD模式

2.       选择IIC模式

3.       选择是否使能自动应答以及设备地址长度

4.       设置IIC总线的传输速率

2.       硬件IIC的读写操作其实逻辑上和标准总线类似,也是发送地址等待ack发送数据等待ACK,但是因为有硬件的自动参与,所以我们不需要延时了


沙发
一灯大神|  楼主 | 2016-11-27 23:29 | 只看该作者

具体代码如下

[cpp] view plain copy


  • void HmcIICInit(void)  
  • {  
  •     /*GPIO初始化*/  
  •     GPIO_InitTypeDef GPIO_InitStructure;  
  •     /* 配置硬件IIC需要的变量 */   
  •     I2C_InitTypeDef I2C_InitStructure;   
  •   
  •     /* 使能与 I2C1 有关的时钟 */  
  •     RCC_APB2PeriphClockCmd  (RCC_APB2Periph_GPIOB,ENABLE );   
  •     RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);   
  •   
  •     /* PB6-I2C1_SCL、PB7-I2C1_SDA*/  
  •     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;   
  •     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   
  •     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;   
  •     GPIO_Init(GPIOB, &GPIO_InitStructure);   
  •   
  •     /*IIC外设初始化*/  
  •   
  •     /* I2C 配置 */  
  •     I2C_InitStructure.I2C_Mode = I2C_Mode_I2C ;     //配置为普通IIC模式  
  •     //I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;   
  •     //I2C_InitStructure.I2C_OwnAddress1 = SlaveAddress;   
  •     I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;  //使能自动应答     
  •     I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;   
  •     I2C_InitStructure.I2C_ClockSpeed = 50000;   //5K的速度?  
  •   
  •   
  •     /* I2C1 初始化 */  
  •     I2C_Init(I2C1, &I2C_InitStructure);      
  •   
  •     /* 使能 I2C1 */  
  •     I2C_Cmd  (I2C1,ENABLE);   
  •     /*允许应答模式*/  
  •     I2C_AcknowledgeConfig(I2C1, ENABLE);     
  • }  
  •   
  • void HmcByteWrite(u8 addr,u8 dataValue)  
  • {  
  •     I2C_GenerateSTART(I2C1,ENABLE);  
  •   
  •     while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));  
  •   
  •     I2C_Send7bitAddress(I2C1,HMC_ADDR,I2C_Direction_Transmitter);  
  •   
  •     while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));  
  •   
  •     I2C_SendData(I2C1,addr);  
  •   
  •     while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED));  
  •   
  •     I2C_SendData(I2C1,dataValue);  
  •   
  •     while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED));  
  •   
  •     I2C_GenerateSTOP(I2C1,ENABLE);  
  •   
  • }  
  •   
  • u8 HmcByteRead(u8 addr)  
  • {  
  •     u8 dataValue;  
  •   
  •     while(I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY));  
  •   
  •     I2C_GenerateSTART(I2C1,ENABLE);//起始信号  
  •   
  •     while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));  
  •   
  •     I2C_Send7bitAddress(I2C1,HMC_ADDR,I2C_Direction_Transmitter);//发送设备地址+写信号  
  •   
  •     while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));//  
  •   
  •     I2C_Cmd(I2C1,ENABLE);  
  •   
  •     I2C_SendData(I2C1,addr);//发送存储单元地址,从0开始  
  •   
  •     while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED));  
  •   
  •     I2C_GenerateSTART(I2C1,ENABLE);//起始信号  
  •   
  •     while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));  
  •   
  •     I2C_Send7bitAddress(I2C1,HMC_ADDR,I2C_Direction_Receiver);//发送设备地址+读信号  
  •   
  •     while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));  
  •   
  •     I2C_AcknowledgeConfig(I2C1,DISABLE);  
  •   
  •     I2C_GenerateSTOP(I2C1,ENABLE);  
  •   
  •     while(!(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_RECEIVED)));  
  •   
  •     dataValue=I2C_ReceiveData(I2C1);//读出寄存器数据  
  •   
  •     return dataValue;  
  • }  
[url=][/url]



使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

65

主题

112

帖子

2

粉丝