STM32开发板入门教程(六) - I2C--24Cxx

发布者:JoyfulExplorer最新更新时间:2016-06-30 来源: eefocus关键字:STM32  入门教程  I2C  24Cxx 手机看文章 扫描二维码
随时随地手机看文章
我们所用来示范的24Cxx系列是最常用的EEPROM芯片。

前面提到了一个地址码,
24Cxx的地址码是固定的,
8位如下:
1  0  1  0  A2 A1 A0  0
A2 A1 A0分别是它三个管脚的电平

24Cxx 理解起来有一个特别之处。
24Cxx 包括 01/02/04/08/16 四种,容量关系刚好和数字一样。1K 2K 4K 8K 16K
24C02 最为常见, 它的三个地址管脚A2 A1 A0都是可用的,
A2 A1 A0 有8中电平组合,也就是说,可以有8个 24C02 挂载同一个I2C总线上。
24C04呢, A0管脚就失效了,只有A2 和 A1 有用,四种组合,最多有4个24C04在总线上,
以此类推。24C16只能有一个在总线上。
这里就不好理解了,为什么要这样呢。
事实是一片 24C16 == 8片24C02 总线挂到一起。A2 A1 A0虽然起不到设置作用了,但你使用地址码还是会访问到特定的区域。
明白了吧。所以其实24C系列的代码是通用的。
地址码也是固定的。就是 0xA0 0xA2 0xA4 0xA6 0xA8 0xAA 0xAC 0xAE
好,我们以24C16为范例吧。

IO设置在I2C1上,无Remap,复用开漏输出。I2C 总线是挂4.7k电阻上拉到高电平的。
        //-----------------------I2C--------------------------------------------
            /* Configure I2C1 pins: SCL and SDA */
          GPIO_InitStruct.GPIO_Pin =  GPIO_Pin_6 | GPIO_Pin_7;
          GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
          GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_OD;   //复用开漏输出
          GPIO_Init(GPIOB, &GPIO_InitStruct);

I2C init函数:

void i2c_24c_init(I2C_TypeDef *I2Cx)
{
        I2C_InitTypeDef I2C_InitStruct;

        I2C_InitStruct.I2C_Mode = I2C_Mode_I2C;    // I2C模式
        I2C_InitStruct.I2C_Ack = I2C_Ack_Enable;    // ACK 在通讯中常见,握手包,即发送到了一个数据,接收方回一句,我收到鸟。
        I2C_InitStruct.I2C_ClockSpeed = I2C_Speed;  // I2C 速度设置,一般是40KHZ,400KHZ是极限,一般到不了那么高
        I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2;  //快速模式下的选项,这里先不讲,100KHZ以上才有用
        I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;  //应答地址码长度,7位或者10位,24C是7位
       
// EEprom Block Select;
        I2C_InitStruct.I2C_OwnAddress1 = I2C_Slave_Adress7;   //第一个设备自身地址

        I2C_Cmd(I2Cx,ENABLE);   //开启I2C

        I2C_Init(I2Cx,&I2C_InitStruct);  //将刚刚的设置送进去
}

注意:现在的片子一般都不止一个I2C。所以用了上述模式,请详细看注释。

写一个字节进EEPROM:
参数解释:Byte待写的字节,WriteAddr预计写入的地址,ByteToWrite写多少给字节,EE24cBlockSelect选择EEPROM相应的区域(I2C地址),*I2Cx,I2C设备指针
void i2c_24c_byte_write(unsigned char Byte, unsigned char WriteAddr, unsigned int ByteToWrite, unsigned char EE24cBlockSelect,I2C_TypeDef *I2Cx)
{
        // Start the I2C
        I2C_GenerateSTART(I2Cx,ENABLE); //打开I2C,开始发送过程

      //not recommanded, stupid way
        while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));  //设置主机模式

        I2C_Send7bitAddress(I2Cx,EE24cBlockSelect,I2C_Direction_Transmitter); //发送片选,选择哪一片区域写。i2C地址区分

        // when get ACK, means Set Success
        while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); //等待这次选择过程完成

        I2C_SendData(I2Cx, WriteAddr);  //发送要写入的地址码

        while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); //等待字节发送完成

        I2C_SendData(I2Cx, Byte); //发送要写的字节

        while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); //等待直到字节发送完成
        
        I2C_GenerateSTOP(I2Cx, ENABLE); //发送过程结束。
}

读EEPROM函数类似,却稍微复杂。
参数说明:pBuffer接收I2C数据的缓冲区,Addr读的地址,NumToRead读多少个字节,ee24cblockselect读哪个区域,I2Cx i2c设备指针
void i2c_24c_buffer_read(unsigned char *pBuffer, unsigned char Addr,unsigned char NumToRead,unsigned char EE24cBlockSelect, I2C_TypeDef *I2Cx)
{
        //open I2C
        I2C_GenerateSTART(I2Cx, ENABLE);  //开始发送

        while(!(I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT))); //设置自己为主机

        I2C_Send7bitAddress(I2Cx,EE24cBlockSelect,I2C_Direction_Transmitter);  //设置自己为发送

        while(!(I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))); //等待主机发送模式设置成功

        I2C_Cmd(I2Cx,ENABLE);  //使能I2C

        I2C_SendData(I2Cx, Addr); //发送地址码,即要读的地址

        while(!(I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED)));  //等待主机发送过程完成

        I2C_GenerateSTART(I2Cx, ENABLE); //I2C开始发送

        while(!(I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT)));  //设置主机模式

        I2C_Send7bitAddress(I2Cx,EE24cBlockSelect,I2C_Direction_Receiver);   //设置从机地址,并设置主机为接收模式

        while(!(I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))); //确认该过程完成

        while(NumToRead)
        {
                if(NumToRead==1)
                        {
                                I2C_AcknowledgeConfig(I2Cx, DISABLE);  //关闭I2C的应答功能

                                I2C_GenerateSTOP(I2Cx, ENABLE); //发送结束信息
                        }

                if((I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED)))  //如果接收到信息了
                        {
                                *pBuffer = I2C_ReceiveData(I2Cx);  //把接收到的数据 填进缓冲区当中

                                pBuffer++;

                                NumToRead--;
                        }
        }

        I2C_AcknowledgeConfig(I2Cx, ENABLE);  //开启主机I2C的应答功能
        
}

 

在写i2C和读i2C之间要插入下面函数等待,否则会有问题

I2C_EE_WaitEepromStandbyState();

关键字:STM32  入门教程  I2C  24Cxx 引用地址:STM32开发板入门教程(六) - I2C--24Cxx

上一篇:STM32f10x_type.h文件--变量类型
下一篇:STM32开发板入门教程 - 内部温度传感器

推荐阅读最新更新时间:2024-03-16 14:59

中频解调电路中的I2C总线接口电路
I2C 总线 (inter integrated circuit bus)由飞利浦公司于20世纪80年代研究开发。I2C 总线 接口 电路 其简单性和有效性而被广泛用于连接微处理器及外围设备。在电视中频解调 电路 中,二线制的I2C总线 接口 电路使得主 控制 器只需要2个引脚便可实现对解调电路所有功能的 控制 ,且总线接口集成在器件中,各电路单元之间只需要最简单的连接,大大简化了电路板上的走线,减少了电路板面积,提高了其可靠性,降低了成本。 在该中频解调的接口电路中,基于I2C总线传输协议,通过对状态机与控制逻辑的优化设置,只需要1个3位的状态机便可实现电路的使能、启动、终止、应答、复位、选址等功能,电路得到了最优化,且通过地
[模拟电子]
STM32】外部中断概述、寄存器、库函数(EXTI一般步骤)
STM32F1xx官方资料: 《STM32中文参考手册V10》-第9章 中断和事件 外部中断概述 外部中断(EXTI),和在【STM32】NVIC中断优先级管理(中断向量表) 中讲述的CM3内核的外部中断不同。特指的是,在中断向量表中的EXTI的外部中断。STM32的每个IO都可以作为外部中断输入。 外部中断线 STM32的中断控制器支持19个外部中断、事件请求(也就是19条外部中断线): 线0~15:对应外部IO口的输入中断; 线16:连接到PVD输出; 线17:连接到RTC闹钟事件; 线18:连接到USB唤醒事件。 每条外部中断线可以独立的配置触发方式(上升沿、下降沿或者双边沿触发)、使能/失能
[单片机]
【<font color='red'>STM32</font>】外部中断概述、寄存器、库函数(EXTI一般步骤)
一文分享STM32的学习笔记
1、AHB系统总线分为APB1(36MHz)和APB2(72MHz),其中2 1,意思是APB2接高速设备 2、Stm32f10x.h相当于reg52.h(里面有基本的位操作定义),另一个为stm32f10x_conf.h专门控制外围器件的配置,也就是开关头文件的作用 3、HSE Osc(High Speed External Oscillator)高速外部晶振,一般为8MHz,HSI RC(High Speed InternalRC)高速内部RC,8MHz 4、LSE Osc(Low Speed External Oscillator)低速外部晶振,一般为32.768KHz,LSI RC(Low Speed InternalRC
[单片机]
一文分享<font color='red'>STM32</font>的学习笔记
STM32学习笔记(八)---通讯基本知识
通讯的基本知识 一、通讯的分类 按数据传送的方式分 a. 串行通讯:按数据位形式一位一位地传输数据 b. 并行通讯:使用8、16、32及64根或更多的数据线进行传输 按数据通讯的方向分 a. 全双工:同一时刻,两个设备之间可以同时收发数据 b. 半双工:同一时刻,两个设备之间不能同时收发数据 c. 单工:任何时刻,只能进行单一方向通讯 按数据同步的方式分 a. 同步通讯:收发双方会使用同一时钟信号线,在时钟信号的驱动下双方进行协调,同步数据 b. 异步通讯:不使用时钟信号同步。 二、通讯速率 通信速率:通常以比特率(bitrate)表示,即每秒钟传输的二进制位数,单位为比特每秒(bit/s)
[单片机]
keil写STM32程序出现literal treated as "long long"
在Keil MDKARM中 unsigned int value2=0x80000000; unsigned int value4=2147483648; value2编译时不产生警告,而value4就产生警告 main.c(17): warning: #1134-D: literal treated as long long 解决方法: 关键是2147483648是一个字面常量,类型是int型,而不是unsigned int. 上面这个语句,需要先将int类型,转换成unsigned int类型,再赋值给value4; 在转换过程中,因为这个数值超过32位int类型的表示范围,所以会出现你所见到的那个警告. unsign
[单片机]
STM32小知识】分频及重装载疑惑
RGB彩灯程序的阅读过程中,到了这两行代码,卡了半天不明所以。 回头重新审视第三章的内容,才发现忽略了某些东西! 说白了,所谓x分频就是,每经过x个CK_PS周期计数器寄存器加一次1! 那么对应到这个实例,也就不难理解了。定时周期10ms,分成256级(重载值255),那么每一级(每计一次数)需要,10ms/256 = 39us… 对应写程序,重载值255,关键是这个分频值。72*39-1…
[单片机]
【<font color='red'>STM32</font>小知识】分频及重装载疑惑
STM32基础入门(二)——STM32入坑指南
1. 开发板的选择 学习STM32,不能绕开的第一件事,那就是开发板。 开发板的意义: 开发板提供了动手的机会。学习网上课程后,自己动手编程,并下载到开发板中,观察是否与预期结果一致,如果不一致,可以调试寻找原因。试错的经历是学习过程中最宝贵的经历。 开发板提供了足够的资源,包含硬件资源和软件资源 。硬件资源,即开发板上自带的LED、蜂鸣器、显示屏、以及其他芯片,可以让我们学习某一部件的时候可以直接上手;软件资源,即开发板配套的课程、例程。这些都是厂家根据这款开发板的特性设计的,新手很适合这样一步一步学习。 开发板调试外设非常方便。在后续自己做项目的时候,自己需要用到的很多东西,可以借助开发板来测试。举个例子,如果
[单片机]
<font color='red'>STM32</font>基础入门(二)——<font color='red'>STM32</font>入坑指南
通过SerDes远端I2C接口访问16位I2C外设寄存器地址
摘要:本应用笔记介绍如何通过吉比特多媒体串行链路(GMSL) SerDes的远端I2C接口访问16位寄存器地址。 引言 Maxim吉比特多媒体串行链路(GMSL)串行器/解串器(SerDes)系列包括MAX9249、MAX9259、MAX9260、MAX9263和MAX9264,具有UART/I2C转换器,用于远端控制I2C接口外设。这些外设包括相机传感器、I/O端口扩展器、音频模/数转换器(ADC)和数/模转换器(DAC),以及LED照明。 在GMSL数据资料和相关技术文件中,通过UART端口直接连接至电子控制单元(ECU)的一端被称为“本地端”,另一端被称为“远端”。 I2C外设接口是控制通道基本模式中的默认设置。GM
[模拟电子]
通过SerDes远端<font color='red'>I2C</font>接口访问16位<font color='red'>I2C</font>外设寄存器地址
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

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

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

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved