历史上的今天
今天是:2024年08月26日(星期一)
2021年08月26日 | STM32 I2C总线 自我总结学习
2021-08-26 来源:eefocus
现在打算彻底搞清楚STM32的I2C总线通信----首先是对AT24C02的读写----手上有PCF8574的IO扩展芯片,也是I2C协议的,希望实现多个控制!
STM32的I2C有自带的硬件驱动,也可以使用GPIO模拟-----先总结一下硬件驱动下的问题。
----------------------------------硬件下-----以AT24C02与PCF8574为例---------------
------第一部分是简单宏定义-------
#define I2C_Speed 300000 //传输速率--挂载原件多时要求降低速率,自己在调试过程中出现过这样问题
#define I2C1_OWN_ADDRESS7 0x0A //主机自定义地址--总线上每个设备都需要地址---包括主机STM32
#define I2C_PageSize 8 // AT24C02每页有8个字节
#define EEP_Firstpage 0x00 //写起始地址
#define EEPROM_ADDRESS 0xA0 //AT24C02从机地址--后面赋值
#define PCF8574_ADDRESS 0x70 //PCF8574从机地址--后面赋值
uint8_t I2c_Buf_Write[256]; //写缓存
uint8_t I2c_Buf_Read[256]; //读缓存
------第二部分是IO---时钟---I2C硬件配置-------
static void I2C_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
I2C_InitTypeDef I2C_InitStructure;
//----时钟-----
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);
// -----GPIO设置-----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);
//-- I2C 配置 --------------------------
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;//选择I2C模式
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;//高低电平占空比为2:1
I2C_InitStructure.I2C_OwnAddress1 =I2C1_OWN_ADDRESS7;//本机地址
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable ; //应答允许
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;//寻址模式为7位---(还有10位的选择)
I2C_InitStructure.I2C_ClockSpeed = I2C_Speed;//传输速率30000--挂载原件多时要求降低速率,自己在调试过程中出现过这样问题
I2C_Cmd(I2C1, ENABLE); // 使能 I2C1
I2C_Init(I2C1, &I2C_InitStructure); //I2C1 初始化
}
------第三部分是----I2C写AT24C02一个字节----关于while循环不去具体研究,主要是判断各步骤是否完成
void I2C_EE_ByteWrite(u8* pBuffer, u8 WriteAddr)
{
u8 i=0;
I2C_GenerateSTART(I2C1, ENABLE); //----(1.)----产生通信起始信号
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))
{
i++;
if(i>100)//防止器件损坏引起死循环
break;
}
I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS,I2C_Direction_Transmitter);//---(2.)---发送地址寻找匹配-- I2C_Direction_Transmitter--表示数据传输方向为STM32发送-- I2C_Direction_Receiver--表示数据传输方向为STM32接收
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
{
i++;
if(i>100)//防止器件损坏引起死循环
break;
}
I2C_SendData(I2C1, WriteAddr); //---(3.)---写起始地址
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
{
i++;
if(i>100)//防止器件损坏引起死循环
break;
}
I2C_SendData(I2C1, *pBuffer); //---(4.)---写数据
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
{
i++;
if(i>100)//防止器件损坏引起死循环
break;
}
I2C_GenerateSTOP(I2C1, ENABLE); //---(5.)---产生结束信号
}
-----第四部分---I2C写AT24C02多个字节,但是不超过AT24C02的一页字节数---8个----关于while循环不去具体研究,主要是判断各步骤是否完成
void I2C_EE_PageWrite(u8* pBuffer, u8 WriteAddr, u8 NumByteToWrite)
{
u8 i=0;
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY))//---(1.)---检测总线状态
{
i++;
if(i>100)
break;
}
I2C_GenerateSTART(I2C1, ENABLE);//---(2.)---起始信号
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))
{
i++;
if(i>100)
break;
}
I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS, I2C_Direction_Transmitter); //---(3.)---发送地址寻址匹配
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
{
i++;
if(i>100)
break;
}
I2C_SendData(I2C1, WriteAddr); //---(4.)---写起始地址
while(! I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
{
i++;
if(i>100)
break;
}
while(NumByteToWrite--) //按照写入个数依次写入
{
I2C_SendData(I2C1, *pBuffer); //---(5.)---写数据
pBuffer++;
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
{
i++;
if(i>100)
break;
}
}
I2C_GenerateSTOP(I2C1, ENABLE);//---(6.)---产生结束信号
}
-----第五部分---I2C读AT24C02多个字节----关于while循环不去具体研究,主要是判断各步骤是否完成
void I2C_EE_BufferRead(u8* pBuffer, u8 ReadAddr, u16 NumByteToRead)
{
u8 i=0;
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY))//---(1.)---忙信号
{
i++;
if(i>100)
break;
}
I2C_GenerateSTART(I2C1, ENABLE);//---(2.)---起始信号
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))
{
i++;
if(i>100)
break;
}
I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS, I2C_Direction_Transmitter);//---(3.)---地址寻址匹配
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
{
i++;
if(i>100)
break;
}
I2C_Cmd(I2C1, ENABLE);
I2C_SendData(I2C1, ReadAddr); //---(4.)---读取数据的起始地址
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
{
i++;
if(i>100)
break;
}
I2C_GenerateSTART(I2C1, ENABLE);//---(5.)---读数据特别之处---重新发送起始信号
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))
{
i++;
if(i>100)
break;
上一篇:STM32 ADC自我学习总结
史海拾趣
|
开发平台是vs2005下vc++下的智能设备开发 三星s2440下的wince平台 屏幕显示分辨率为800*600 在中文版本下应用程序可以全屏显示,但是到了英文平台,只能显示出程序的一部分内容,感觉像是应用程序的分辨率变小了 如果换成vs2005下C#下的智能设备 ...… 查看全部问答> |
|
我的多国语言用ini文件的方式来实现,在记事本中写好了多国语言后,保存为unicode编码。 在读取这个ini文件时查看内存中读出的S为 53 00 00 00,而在程序中自己定义的宽字节S在内存中则为53 00。 看起来读的unicode的ini文件中的字符好像多了2个 ...… 查看全部问答> |
|
平台:自己定制的wince5.0平台,非mobile 问题:CeCreateDatabaseWithProps和CeCreateSession函数未定义;本机上没有wincebase_edb.h和coredll.dll; coredll.lib和winbase.h中没有这些函数的定义。 是我定制的平台有问题,还是winc ...… 查看全部问答> |
|
现在正在做一个板子,需要做HSMC接口。可是网上找不到资料,ALTERA公司网站也没有。看到你们这边做示波器2.0中用到了这个接口,想跟你们求助一下,看看有没有封装等资料能共享一下,谢谢了……… 查看全部问答> |




