您的位置 首页 电路

STM32F030中I2C 的装备和 AT24C16驱动

STM32F030中I2C 的配置和 AT24C16驱动-I2C_AutoEnd_Mode,顾名思义,操作length字节后自动添加STOP。 I2C_SoftEnd_Mode ,同样顾名思义,操作length字节后需要手动添加STOP。( I2C_GenerateSTOP() )

I2C 的装备

staTIc void IniTI2C()

{

I2C_InitTypeDef I2C_InitStructure;

GPIO_InitTypeDef GPIO_InitA;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);//使能I2C1,I2C2的时钟

RCC_I2CCLKConfig(RCC_I2C1CLK_SYSCLK);//时钟源设定

GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_1);  //装备PB8 成第二功用引脚 I2C1_SCL

GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_1);  //装备PB9 成第二功用引脚 I2C1_SDA

GPIO_InitA.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;

GPIO_InitA.GPIO_Mode = GPIO_Mode_AF;

GPIO_InitA.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitA.GPIO_OType = GPIO_OType_PP;

GPIO_InitA.GPIO_PuPd = GPIO_PuPd_UP;

GPIO_Init(GPIOB, &GPIO_InitA);

I2C_InitStructure.I2C_Mode = I2C_Mode_SMBusHost;

I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;

I2C_InitStructure.I2C_AnalogFilter = I2C_AnalogFilter_Enable;

I2C_InitStructure.I2C_DigitalFilter = 0x01;

I2C_InitStructure.I2C_OwnAddress1 = 0x00;

I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;

I2C_InitStructure.I2C_TIming = 0x0090174F;

I2C_Init(I2C1, &I2C_InitStructure);

I2C_Cmd(I2C1, ENABLE);

}

相同的装备计划,I2C_TIming的意思请移步本博客GY30那篇文章。 

I2C引脚为PB8 与PB9(运用的C8T6,f4p6可以用PA的)

#define AT24C16_Base_Address 0xA0

void AT24C16_WriteByte(uint8_t Page,uint8_t WordAddress,uint8_t Data);

uint8_t AT24C16_ReadByte(uint8_t Page,uint8_t WordAddress);

void AT24C16_PageWrite(uint8_t Page,uint8_t WordAddress,uint8_t Length,uint8_t* Data);

void AT24C16_SequentialRead(uint8_t Page,uint8_t WordAddress, uint8_t length , uint8_t* p);

下面是相关函数:

void AT24C16_WriteByte(uint8_t Page,uint8_t WordAddress,uint8_t Data)

{

if(WordAddress > 0x10)

{

return;

}

WordAddress |= ( Page & 0x0F ) << 4;

while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY) != RESET);//IF BUSY

I2C_TransferHandling(I2C1,AT24C16_Base_Address | ( ( Page & 0xF0 ) >> 3 ),2,I2C_AutoEnd_Mode,I2C_Generate_Start_Write);

while(I2C_GetFlagStatus(I2C1, I2C_FLAG_TXIS) == RESET);//If Write OK

I2C_SendData(I2C1,WordAddress);

while(I2C_GetFlagStatus(I2C1, I2C_FLAG_TXIS) == RESET);//If Write OK

I2C_SendData(I2C1,Data);

while(I2C_GetFlagStatus(I2C1, I2C_FLAG_STOPF) == RESET);

}

uint8_t AT24C16_ReadByte(uint8_t Page,uint8_t WordAddress)

{

uint8_t Recev = 0x00;

if(WordAddress > 0x10)

{

return 0;

}

WordAddress |= ( Page & 0x0F ) << 4;

while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY) != RESET);//IF BUSY

I2C_TransferHandling(I2C1,AT24C16_Base_Address | ( ( Page & 0xF0 ) >> 3 ),1,I2C_SoftEnd_Mode,I2C_Generate_Start_Write);

while(I2C_GetFlagStatus(I2C1, I2C_FLAG_TXIS) == RESET);//If Write OK

I2C_SendData(I2C1,WordAddress);

while(I2C_GetFlagStatus(I2C1, I2C_FLAG_TC) == RESET);

I2C_TransferHandling(I2C1,AT24C16_Base_Address | ( ( Page & 0xF0 ) >> 3 ),1,I2C_AutoEnd_Mode,I2C_Generate_Start_Read);

while(I2C_GetFlagStatus(I2C1, I2C_FLAG_RXNE) == RESET);

Recev = I2C_ReceiveData(I2C1);

while(I2C_GetFlagStatus(I2C1, I2C_FLAG_STOPF) == RESET);

return Recev;

}

下面是页读取,页写入:

void AT24C16_PageWrite(uint8_t Page,uint8_t WordAddress,uint8_t Length,uint8_t* Data)

{

uint8_t i = 0;

if(WordAddress > 0x10)

{

return;

}

WordAddress |= ( Page & 0x0F ) << 4;

while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY) != RESET);//IF BUSY

I2C_TransferHandling(I2C1,AT24C16_Base_Address | ( ( Page & 0xF0 ) >> 3 ),Length + 1,I2C_AutoEnd_Mode,I2C_Generate_Start_Write);

while(I2C_GetFlagStatus(I2C1, I2C_FLAG_TXIS) == RESET);//If Write OK

I2C_SendData(I2C1,WordAddress);

for(i = 0;i < Length; i++)

{

while(I2C_GetFlagStatus(I2C1, I2C_FLAG_TXIS) == RESET);//If Write OK

I2C_SendData(I2C1,Data[i]);

}

while(I2C_GetFlagStatus(I2C1, I2C_FLAG_STOPF) == RESET);

}

void AT24C16_SequentialRead(uint8_t Page,uint8_t WordAddress, uint8_t length , uint8_t* p)

{

uint8_t i;

if(WordAddress > 0x10)

{

return;

}

WordAddress |= ( Page & 0x0F ) << 4;

while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY) != RESET);//IF BUSY

I2C_TransferHandling(I2C1,AT24C16_Base_Address | ( ( Page & 0xF0 ) >> 3 ),1,I2C_SoftEnd_Mode,I2C_Generate_Start_Write);

while(I2C_GetFlagStatus(I2C1, I2C_FLAG_TXIS) == RESET);//If Write OK

I2C_SendData(I2C1,WordAddress);

while(I2C_GetFlagStatus(I2C1, I2C_FLAG_TC) == RESET);

I2C_TransferHandling(I2C1,AT24C16_Base_Address | ( ( Page & 0xF0 ) >> 3 ),length,I2C_AutoEnd_Mode,I2C_Generate_Start_Read);

for(i = 0;i < length;i++)

{

while(I2C_GetFlagStatus(I2C1, I2C_FLAG_RXNE) == RESET);

p[i] = I2C_ReceiveData(I2C1);

}

while(I2C_GetFlagStatus(I2C1, I2C_FLAG_STOPF) == RESET);

}

感觉没什么说的,GY30那篇文章根本都说完了,添点小知识点吧。

I2C_AutoEnd_Mode,望文生义,操作length字节后主动增加STOP。 

I2C_SoftEnd_Mode ,相同望文生义,操作length字节后需求手动增加STOP。( I2C_GenerateSTOP() ) 

这个形式比主动多了一步,需求 I2C_GetFlagStatus(I2C1, I2C_FLAG_TC) ,Translate Completed,是否传输完结,主动形式下拜访这个会得到Reset值,但是手动形式下需求拜访他,然后生成Stop。

然后……差不多了吧?举个 上面网址的比如吧,我觉得很多人不会看……

所以在编写程序对AT24C16第100页的第3个字节进行写数据的时分,过程如下: 

1)发送起始信号; 

2)发送器材地址0XA6(1010 0110,1010是固定地址,011是页地址的高三位,0表明写操作); 

3)发送操作地址0X43(0100 0011,0100是页地址的低四位,0011是页地址偏移量,即第100页内的第三个字节, 

4)发送要写的数据, 

5)发送停止信号。

我信任各位最起码都看了AT24C16的地址了,0xA0。(再次引证畅学电子网的图片) 

STM32F030中I2C 的装备和 AT24C16驱动

P0P1P2为页地址高三位,发送的字地址(WordAddress)高四位为页地址的第四位,低四位为字地址。 

AT24C16有128页,每页16bytes。所以正好匹配上。 

写的距离至少为5ms,否则用循环等候的话I2C会卡死。

以上。 

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/fangan/dianlu/347595.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部