历史上的今天

今天是:2024年08月26日(星期一)

正在发生

2021年08月26日 | STM32 I2C总线 自我总结学习

发布者:genius6 来源: eefocus关键字:STM32  I2C总线  AT24C02 手机看文章 扫描二维码
随时随地手机看文章

现在打算彻底搞清楚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;    

[1] [2] [3]
关键字:STM32  I2C总线  AT24C02 引用地址:STM32 I2C总线 自我总结学习

上一篇:STM32 ADC自我学习总结
下一篇:STM32 DS18B20 代码详解

推荐阅读

中国储能网讯:今年入夏以来,上海已经开展3次不同规模、不同类型需求响应试点,探索构建需求响应优先、有序用电保底的需求侧管理机制,实现了工业生产、自备电厂、冷热电三联供、冰蓄冷、储能设施、公共充电站、小区直供充电桩等全类型城市可控负荷资源的全面覆盖。通过多次需求响应试点开展,区域性商业办公楼宇“虚拟电厂”、各类新技术柔性负荷调控能...
STM32F10x 系列单片机中都包含了USART 模块,所谓USART,就是通用同步异步收发器。通用同步异步收发器(USART)提供了一种灵活的方法与使用工业标准NRZ异步串行数据格式的外部设备之间进行全双工数据交换。它支持同步单向通信和半双工单线通信,也支持LIN(局部互连网),智能卡协议和IrDA(红外数据组织)SIR ENDEC规范,以及调制解调器(CTS/RTS)操作。它还允许...
据新华视点微博账号消息,2020年8月26日8时38分,由中国航空工业集团有限公司自主研制的「领雁」AG50轻型运动飞机在湖北荆门首飞成功,经过12分钟平稳飞行后安全着陆。截图自新华视点微博
DS18B20是最常用来学习某一个新的开发工具的,程序都是大同小异,主要是要注意时序中的延时要准确,指令要正确,这里记录一下!------------------第一部分是--------ds18b20.h----------------------#ifndef __DS18B20_H#define __DS18B20_H#include "stm32f10x.h"#include "bsp_SysTick.h" //精确延时函数头文件----参考http://blog.csdn.net/xux...

史海拾趣

小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved