Stm32具有IIC接口,接口有以下主要特性
多主機(jī)功能:該模塊既可做主設(shè)備也可做從設(shè)備
主設(shè)備功能
C地址檢測(cè)
產(chǎn)生和檢測(cè)7位/10位地址和廣播呼叫
支持不同的通訊速度
狀態(tài)標(biāo)志:
發(fā)送器/接收器模式標(biāo)志
字節(jié)發(fā)送結(jié)束標(biāo)志
總線忙標(biāo)志
錯(cuò)誤標(biāo)志
2個(gè)中斷向量
可選的拉長(zhǎng)時(shí)鐘功能
具單字節(jié)緩沖器的DMA
雖然很多人說(shuō)STM的硬件IIC不好用,但是對(duì)于這么一個(gè)設(shè)備去探索一下還是很有必要的,指不定哪天就用上了呢,
IIC借口一共有九個(gè)寄存器,比較重要的幾個(gè)寄存器分別如下
1.CR1
由這幾個(gè)位我們可以正常產(chǎn)生標(biāo)準(zhǔn)IIC的START條件STOP條件,ACK與NOACK
CR2
控制IIC的通行頻率
這兩位檢測(cè)IIC總線是否收到數(shù)據(jù)
1.對(duì)于硬件IIC的初始化流程包括
1.配置IO口,配置為GPIO_Mode_AF_OD模式
2.選擇IIC模式
3.選擇是否使能自動(dòng)應(yīng)答以及設(shè)備地址長(zhǎng)度
4.設(shè)置IIC總線的傳輸速率
2.硬件IIC的讀寫(xiě)操作其實(shí)邏輯上和標(biāo)準(zhǔn)總線類(lèi)似,也是發(fā)送地址等待ack發(fā)送數(shù)據(jù)等待ACK,但是因?yàn)橛杏布淖詣?dòng)參與,所以我們不需要延時(shí)了
具體代碼如下
voidHmcIICInit(void)
{
/*GPIO初始化*/
GPIO_InitTypeDefGPIO_InitStructure;
/*配置硬件IIC需要的變量*/
I2C_InitTypeDefI2C_InitStructure;
/*使能與I2C1有關(guān)的時(shí)鐘*/
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外設(shè)初始化*/
/*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;//使能自動(dòng)應(yīng)答
I2C_InitStructure.I2C_AcknowledgedAddress=I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed=50000;//5K的速度?
/*I2C1初始化*/
I2C_Init(I2C1,&I2C_InitStructure);
/*使能I2C1*/
I2C_Cmd(I2C1,ENABLE);
/*允許應(yīng)答模式*/
I2C_AcknowledgeConfig(I2C1,ENABLE);
}
voidHmcByteWrite(u8addr,u8dataValue)
{
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);
}
u8HmcByteRead(u8addr)
{
u8dataValue;
while(I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY));
I2C_GenerateSTART(I2C1,ENABLE);//起始信號(hào)
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C1,HMC_ADDR,I2C_Direction_Transmitter);//發(fā)送設(shè)備地址+寫(xiě)信號(hào)
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));//
I2C_Cmd(I2C1,ENABLE);
I2C_SendData(I2C1,addr);//發(fā)送存儲(chǔ)單元地址,從0開(kāi)始
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_GenerateSTART(I2C1,ENABLE);//起始信號(hào)
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C1,HMC_ADDR,I2C_Direction_Receiver);//發(fā)送設(shè)備地址+讀信號(hào)
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);//讀出寄存器數(shù)據(jù)
returndataValue;
}