STM32 硬件I2C EEPROM命令解析

发布者:LogicLeaper最新更新时间:2016-04-08 来源: eefocus关键字:STM32  硬件I2C  EEPROM  命令解析 手机看文章 扫描二维码
随时随地手机看文章
void I2C_EE_BufferWrite(u8* pBuffer, u8 WriteAddr, u16 NumByteToWrite)
{
    u8 NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0;
    //写入地址是每页的第几位
    Addr = WriteAddr % I2C_PageSize;
    //在开始的一页要写入的个数
    count = I2C_PageSize - Addr;
    //要写入的页数
    NumOfPage = NumByteToWrite / I2C_PageSize;
    //不足一页的个数
    NumOfSingle = NumByteToWrite % I2C_PageSize;
    //EEPROM设为待命状态
    I2C_EE_WaitEepromStandbyState();
 
    //写入地址是页的开始
    if (Addr == 0)
    {
        //数据小于一页
        if (NumOfPage == 0)
        {
            //写少于一页的数据
            I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
            //EEPROM设为待命状态
            I2C_EE_WaitEepromStandbyState();
        }
        //数据大于等于一页
        else
        {
            while (NumOfPage--)//要写入的页数
            {
                //写一页的数据
                I2C_EE_PageWrite(pBuffer, WriteAddr, I2C_PageSize);
                //EEPROM设为待命状态
                I2C_EE_WaitEepromStandbyState();
                WriteAddr += I2C_PageSize;
                pBuffer += I2C_PageSize;
            }
            //剩余数据小于一页
            if (NumOfSingle!=0)
            {
                //写少于一页的数据
                I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
                //EEPROM设为待命状态
                I2C_EE_WaitEepromStandbyState();
            }
        }
    }
    //写入地址不是页的开始
    else
    {
        //数据小于一页
        if (NumOfPage== 0)
        {
            //写少于一页的数据
            I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
            //EEPROM设为待命状态
            I2C_EE_WaitEepromStandbyState();
        }
        //数据大于等于一页
        else
        {
            NumByteToWrite -= count;
            //重新计算要写入的页数
            NumOfPage = NumByteToWrite / I2C_PageSize;
            //重新计算不足一页的个数
            NumOfSingle = NumByteToWrite % I2C_PageSize;
 
            if (count != 0)
            {
                //将开始的空间写满一页
                I2C_EE_PageWrite(pBuffer, WriteAddr, count);
                //EEPROM设为待命状态
                I2C_EE_WaitEepromStandbyState();
                WriteAddr += count;
                pBuffer += count;
            }
            //要写入的页数
            while (NumOfPage--)
            {
                //写一页的数据
                I2C_EE_PageWrite(pBuffer, WriteAddr, I2C_PageSize);
                //EEPROM设为待命状态
                I2C_EE_WaitEepromStandbyState();
                WriteAddr += I2C_PageSize;
                pBuffer += I2C_PageSize;
            }
            //剩余数据小于一页
            if (NumOfSingle != 0)
            {
                //写少于一页的数据
                I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
                //EEPROM设为待命状态
                I2C_EE_WaitEepromStandbyState();
            }
        }
    }
}
 
 
void I2C_EE_ByteWrite(u8* pBuffer, u8 WriteAddr)
{
    //产生 I2C2传输 START条件
    I2C_GenerateSTART(I2C2, ENABLE);
    //通过START的产生,确定主机模式是否成功(检测EV5)
    while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT));
    //发送器件地址(写)
    I2C_Send7bitAddress(I2C2, EEPROM_ADDRESS, I2C_Direction_Transmitter);
    //检测主机传输模式是否成功(检测EV6)
    while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
 
    //通过外设 I2C2发送地址
    I2C_SendData(I2C2, WriteAddr);
    //检测主机发送的字节是否成功(检测EV8)
    while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
 
    //通过外设 I2C2发送数据
    I2C_SendData(I2C2, *pBuffer);
 
    //检测主机发送的字节是否成功(检测EV8)
    while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
 
    //产生 I2C2传输 STOP条件
    I2C_GenerateSTOP(I2C2, ENABLE);
}
 
void I2C_EE_PageWrite(u8* pBuffer, u8 WriteAddr, u8 NumByteToWrite)
{
    //产生 I2C2传输 START条件
    I2C_GenerateSTART(I2C2, ENABLE);
 
    //通过START的产生,确定主机模式是否成功(检测EV5)
    while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT));
    //发送器件地址(写)
    I2C_Send7bitAddress(I2C2, EEPROM_ADDRESS, I2C_Direction_Transmitter);
 
    //检测主机传输模式是否成功(检测EV6)
    while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
 
    //通过外设 I2C2发送地址
    I2C_SendData(I2C2, WriteAddr);
 
    //检测主机发送的字节是否成功(检测EV8)
    while (! I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
 
    //写数据
    while (NumByteToWrite--)
    {
        //通过外设 I2C2发送数据
        I2C_SendData(I2C2, *pBuffer);
 
        //指针++
        pBuffer++;
 
        //检测主机发送的字节是否成功(检测EV8)
        while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
    }
    //产生 I2C2 传输 STOP条件
    I2C_GenerateSTOP(I2C2, ENABLE);
}
 
void I2C_EE_BufferRead(u8* pBuffer, u8 ReadAddr, u16 NumByteToRead)
{
    //EEPROM设为待命状态
    I2C_EE_WaitEepromStandbyState();
    //产生 I2C2传输 START条件
    I2C_GenerateSTART(I2C2, ENABLE);
    //通过START的产生,确定主机模式是否成功(检测EV5)
    while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT));
    //在一个单一的数据传输情况下读取数据之前禁用的ACK
    if (NumByteToRead==1)
    {
        I2C_AcknowledgeConfig(I2C2, DISABLE);//失能I2C2 的应答功能
    }
 
    //向指定的从 I2C设备传送地址字,选择发送方向
    I2C_Send7bitAddress(I2C2, EEPROM_ADDRESS, I2C_Direction_Transmitter);
 
    //检测主机传输模式是否成功(检测EV6)
    while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
 
    //使能I2C外设
    I2C_Cmd(I2C2, ENABLE);
 
    //通过外设 I2C2发送地址
    I2C_SendData(I2C2, ReadAddr);
 
    //检测主机发送的字节是否成功(检测EV8)
    while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
 
    //产生 I2C2 传输 START条件
    I2C_GenerateSTART(I2C2, ENABLE);
 
    //通过START的产生,确定主机模式是否成功(检测EV5)
    while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT));
 
    //向指定的从 I2C设备传送地址字,选择接收方向
    I2C_Send7bitAddress(I2C2, EEPROM_ADDRESS, I2C_Direction_Receiver);
 
    //检测主机接收模式是否成功(检测EV6)
    while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
 
    //读取数据
    while (NumByteToRead)
    {
        //检测主机接收的字节是否成功(检测EV8)
        if (I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_RECEIVED))
        {
            if (NumByteToRead == 2)
            {
                //使能或者失能指定 I2C的应答功能
                I2C_AcknowledgeConfig(I2C2, DISABLE);
            }
 
            if (NumByteToRead == 1)
            {
                //产生 I2C2 传输 STOP条件
                I2C_GenerateSTOP(I2C2, ENABLE);
            }
 
            //返回通过 I2C2最近接收的数据
            *pBuffer = I2C_ReceiveData(I2C2);
 
            //指向下个地址
            pBuffer++;
            NumByteToRead--;
        }
    }
 
    //使能I2C2 的应答功能
    I2C_AcknowledgeConfig(I2C2, ENABLE);
 
}
 
 
void I2C_EE_WaitEepromStandbyState(void)
{
    vu16 SR1_Tmp = 0;
 
    do
    {
        //产生 I2C2传输 START条件
        I2C_GenerateSTART(I2C2, ENABLE);
        //读取指定的 I2C寄存器 I2C_SR1 并返回其值
        SR1_Tmp = I2C_ReadRegister(I2C2, I2C_Register_SR1);
        //向指定的从 I2C设备传送地址字 ,选择发送方向
        I2C_Send7bitAddress(I2C2, EEPROM_ADDRESS, I2C_Direction_Transmitter);
    } while (!(I2C_ReadRegister(I2C2, I2C_Register_SR1) & 0x0002));//地址发送结束
 
    //清除 I2Cx的应答错误标志位
    I2C_ClearFlag(I2C2, I2C_FLAG_AF);
 
}

关键字:STM32  硬件I2C  EEPROM  命令解析 引用地址:STM32 硬件I2C EEPROM命令解析

上一篇:J-Flash ARM的配置
下一篇:stm32的定时器输入捕获与输出比较

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

基于STM32的嵌入式语音识别电路模块设计
 介绍了一种以ARM为核心的嵌入式语音识别模块的设计与实现。模块的核心处理单元选用ST公司的基于ARM Cortex-M3内核的32位处理器STM32F103C8T6。本模块以对话管理单元为中心,通过以LD3320芯片为核心的硬件单元实现语音识别功能,采用嵌入式操作系统μC/OS-II来实现统一的任务调度和外围设备管理。经过大量的实验数据验证,本文设计的语音识别模块具有高实时性、高识别率、高稳定性的优点。    主控制器电路   本文的主控制器选用的是ST公司的STM32F103C8T6芯片。该芯片基于ARM Cottex-M3 32位的RISC内核,工作频率最高可达72 MHz,内置高速存储器(64 KB的闪存和20 KB的S
[电源管理]
基于<font color='red'>STM32</font>的嵌入式语音识别电路模块设计
一文详解STM32输入捕获
输入捕获是处理器捕获外部输入信号的功能,基于定时器抓取输入信号指定触发方式之间的长度。具体有下面三种触发情况: 1、 上升沿触发 2、 下降沿触发 3、 上下都触发 当触发条件发生后,捕获比较寄存器锁定当前的计数值,如果开启了中断或者DMA,就可以通过中断或DMA及时获得数据进行处理。有时可能遇到上一次触发的标志还没清除,下次触发就发生了,此时会将over-capture标志置位,对于可能出现over-capture的情况,建议先读取数据再清除标志,避免在读取标志后及读取数据前这段时间错过over-capture。 配置输入捕获的步骤: 1. 打开定时器和对应输入引脚的时钟 2. 配置引脚为对应的复用功能 3. 配置基
[单片机]
一文详解<font color='red'>STM32</font>输入捕获
stm32之断言详细讲解
最近公司不忙,就想着充实下自己,偶然看到了“断言机制”,也认真试验了一番,便赶紧记录下来,也是为了温故而知新,再者与大家分享一下! 首先看一个应用:(网络不好,图片不好上传,原谅我偷懒) void TIM_DeInit(TIM_TypeDef* TIMx) { /* Check the parameters */ assert_param(IS_TIM_ALL_PERIPH(TIMx)); if (TIMx == TIM1) { RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM1, ENABLE); RCC_APB2PeriphResetCmd(RCC_AP
[单片机]
<font color='red'>stm32</font>之断言详细讲解
stm32使用中,printf函数不执行的问题
一、程序中已经添加了printf的库函数 #include“stdio.h” 二、stm32串口通讯测试没问题,此处可以通过调用 USART_SendData(USART1, 0xAA)函数来进行验证; 三、现象。printf函数无法工作 四、解决办法,使用自带的迷你库,就可以正常运行。
[单片机]
<font color='red'>stm32</font>使用中,printf函数不执行的问题
I2C—读写EEPROM 实验
EEPROM 是一种掉电后数据不丢失的存储器,常用来存储一些配置信息,以便系统重新上电的时候加载之。EEPOM 芯片最常用的通讯方式就是I2C 协议,本小节以EEPROM的读写实验为大家讲解STM32 的I2C 使用方法。实验中STM32 的I2C 外设采用主模式,分别用作主发送器和主接收器,通过查询事件的方式来确保正常通讯。 硬件设计 EEPROM 硬件连接图 本实验板中的EEPROM芯片(型号:AT24C02)的SCL 及SDA 引脚连接到了STM32 对应的I2C 引脚中,结合上拉电阻,构成了I2C 通讯总线,它们通过I2C 总线交互。EEPROM芯片的设备地址一共有7 位,其中高4 位固定为:1010 b,低3
[单片机]
<font color='red'>I2C</font>—读写<font color='red'>EEPROM</font> 实验
STM32 的 SWD调试模式
SWD:Serial Wire Debug 串行线调试 我们比较常用的是Jlink下载器 ,这种下载器有一个缺点就是使用的Jtag 20PIN接口,太多的PIN会导致一些小型的PCB板很拥挤,也会增加布线的难度。 而使用SWD接口下载调试,只需要要使用4个PIN: GND, RST, SWDIO, SWDCLK ,而且下载速度可以达到10M/s,优势显而易见。 以下转自: http://www.openedv.com/posts/list/187.htm 对于JTAG和SWD的使用区别,觉得下面这篇文章讲的比较清晰了,所以转帖到这里,希望对新手有所帮助。 SWD与JTAG区别及使用情况 上图
[单片机]
<font color='red'>STM32</font> 的 SWD调试模式
独立看门狗IWDG详细解析
独立看门狗IWDG详细解析 为什么要有看门狗? 看门狗的定时原理 寄存器功能简介 看门狗定时器计数原理 看门狗相关寄存器 KR寄存器 PR寄存器 RLR寄存器 SR寄存器 看门狗相关基础知识 什么是“溢出时间”? 溢出时间指的是“从重装载值递减至0的时间”,当距离上次使能键寄存器的时间超过溢出时间,那么看门狗会自动复位,重投开始执行程序。例如:当我们设定溢出时间为1s,但是我们操作键寄存器距离上次使能键寄存器的时间已经是1.2s了,这说明程序已经Reset复位,从头开始执行(从main函数的头部开始执行)。 预分频系数有什么用? “溢出时间”如何计算? 不同预分频系数
[单片机]
独立看门狗IWDG详细<font color='red'>解析</font>
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

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

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

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