datasheet

IIC专题(二)——STM32驱动AT24C02

2019-01-09来源: eefocus 关键字:IIC  STM32  驱动AT24C02

1.概述

MiniSTM32 开发板板载的 EEPROM 芯片型号为 24C02。该芯片的总容量是 256个字节,该芯片通过 IIC 总线与外部连接。这里直接采用原子板上的 AT24C02 ,主要是软件编程方面的学习。


2.硬件连接


A2、A1、A0 三个引脚直接接地。供电: (VCC = 2.7V to 5.5V)


器件地址设置:



对于AT24C02:Addr—>0xA0(写)/ 0xA1(读)。


单字节写入:



按页写入:



从当前地址读出数据;



随机读取:



顺序读出:



3.例程分析

(一)IIC 部分实现代码

包括 IIC 的初始化(IO 口)、 IIC 开始、 IIC 结束、 ACK、 IIC 读写等功能,在其他函数里面,只需要调用相关的 IIC 函数就可以和外部 IIC 器件通信了,这里并不局限于 24C02,该段代码可以用在任何 IIC 设备上。


IIC_SCL 和 IIC_SDA 分别连在 STM32 的 PC12 和 PC11。


1.IIC 初始化

//IO操作函数     

#define IIC_SCL    PCout(12) //SCL

#define IIC_SDA    PCout(11) //SDA   

#define READ_SDA   PCin(11)  //输入SDA


//初始化 IIC

void IIC_Init(void)

{

    GPIO_InitTypeDef GPIO_InitStructure;


    RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC, ENABLE );

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12"GPIO_Pin_11;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; //推挽输出

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(GPIOC, &GPIO_InitStructure);


    IIC_SCL=1;

    IIC_SDA=1;

}


2.产生 IIC 开始信号

//产生 IIC 起始信号

void IIC_Start(void)

{

    SDA_OUT(); //sda 线输出


    IIC_SDA=1;

    IIC_SCL=1;


    delay_us(4);


    IIC_SDA=0;//START:when CLK is high,DATA change form high to low


    delay_us(4);


    IIC_SCL=0;//钳住 I2C 总线, 准备发送或接收数据

}


3.产生停止IIC信号

//产生 IIC 停止信号

void IIC_Stop(void)

{

    SDA_OUT();//sda 线输出


    IIC_SCL=0;

    IIC_SDA=0;//STOP:when CLK is high , DATA change form low to high

    delay_us(4);


    IIC_SCL=1;


    IIC_SDA=1;//发送 I2C 总线结束信号

    delay_us(4);

}


4.等待应答信号

//等待应答信号到来

//返回值: 1,接收应答失败

// 0,接收应答成功

u8 IIC_Wait_Ack(void)

{

    u8 ucErrTime=0;


    SDA_IN(); //SDA 设置为输入


    IIC_SDA=1;

    delay_us(1);

    IIC_SCL=1;

    delay_us(1);


    while(READ_SDA)

    {

    ucErrTime++;

    if(ucErrTime>250)

    {

    IIC_Stop();

    return 1;

    }

    }

    IIC_SCL=0;//时钟输出 0

    return 0;

}



5.应答信号

//产生 ACK 应答

void IIC_Ack(void)

{

    IIC_SCL=0;


    SDA_OUT();


    IIC_SDA=0;

    delay_us(2);


    IIC_SCL=1;


    delay_us(2);

    IIC_SCL=0;

}


6.不产生应答

//不产生 ACK 应答

void IIC_NAck(void)

{

    IIC_SCL=0;

    SDA_OUT();


    IIC_SDA=1;


    delay_us(2);

    IIC_SCL=1;

    delay_us(2);

    IIC_SCL=0;

}


7.IIC发送一个字节

//IIC 发送一个字节

//返回从机有无应答

//1,有应答

//0,无应答

void IIC_Send_Byte(u8 txd)

{

    u8 t;


    SDA_OUT();


    IIC_SCL=0;//拉低时钟开始数据传输


    for(t=0;t<8;t++)

    {

        IIC_SDA=(txd&0x80)>>7;//高位开始,一位一位的传数据

        txd<<=1;

        delay_us(2); //对 TEA5767 这三个延时都是必须的

        IIC_SCL=1;  //保持数据的稳定

        delay_us(2);

        IIC_SCL=0;   //下一位数据传输开始

        delay_us(2);

    }

}


8.IIC读一个字节

//读 1 个字节, ack=1 时,发送 ACK, ack=0,发送 nACK

u8 IIC_Read_Byte(unsigned char ack)

{

    unsigned char i,receive=0;


    SDA_IN();//SDA 设置为输入


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

    {

        IIC_SCL=0;

        delay_us(2);

        IIC_SCL=1;

        receive<<=1;

        if(READ_SDA)

            receive++;

        delay_us(1);

    }

    if (!ack)

    IIC_NAck();//发送 nACK

    else

    IIC_Ack(); //发送 ACK

    return receive;

}



(二)AT24C02 操作

直接通过寄存器操作设置 IO 口的模式为输入还是输出,代码如下:


#define SDA_IN() {GPIOC->CRH&=0XFFFF0FFF;GPIOC->CRH|=8<<12;}


#define SDA_OUT() {GPIOC->CRH&=0XFFFF0FFF;GPIOC->CRH|=3<<12;}  


1.初始化 IIC 接口

//初始化 IIC 接口

void AT24CXX_Init(void)

{

    IIC_Init();

}


2.在 AT24CXX 指定地址读出一个数据

//在 AT24CXX 指定地址读出一个数据

//ReadAddr:开始读数的地址,24C02大小为2Kbit;ADDR:0x00---0x7FF

//返回值 :读到的数据


u8 AT24CXX_ReadOneByte(u16 ReadAddr)

{

    u8 temp=0;


    IIC_Start();

    if(EE_TYPE>AT24C16)

    /*宏定义有个选择芯片类型的,如果这个定义大于AT24C16的话就发送两个8bit地址,否则就发送一个8bit地址*/

    {

    IIC_Send_Byte(0XA0); //发送写命令,0XA0:器件的地址,7位地址+写(0)

    IIC_Wait_Ack();

    IIC_Send_Byte(ReadAddr>>8);//发送高地址

    }else IIC_Send_Byte(0XA0+((ReadAddr/256)<<1)); //发送器件地址 0XA0,写数据

    IIC_Wait_Ack();

    IIC_Send_Byte(ReadAddr%256); //发送低地址

    IIC_Wait_Ack();

    IIC_Start();

    IIC_Send_Byte(0XA1); //进入接收模式,7位地址+读(1)

    IIC_Wait_Ack();

    temp=IIC_Read_Byte(0);

    IIC_Stop();//产生一个停止条件

    return temp;

}


3.在 AT24CXX 指定地址写入一个数据

//在 AT24CXX 指定地址写入一个数据

//WriteAddr :写入数据的目的地址

//DataToWrite:要写入的数据


void AT24CXX_WriteOneByte(u16 WriteAddr,u8 DataToWrite)

{

    IIC_Start();

    if(EE_TYPE>AT24C16)

    {

    IIC_Send_Byte(0XA0); //发送写命令

    IIC_Wait_Ack();

    IIC_Send_Byte(WriteAddr>>8);//发送高地址

    }else IIC_Send_Byte(0XA0+((WriteAddr/256)<<1)); //发送器件地址 0XA0,写数据

    IIC_Wait_Ack();

    IIC_Send_Byte(WriteAddr%256); //发送低地址

    IIC_Wait_Ack();

    IIC_Send_Byte(DataToWrite); //发送字节

    IIC_Wait_Ack();

    IIC_Stop(); //产生一个停止条件

    delay_ms(10); //对于 EEPROM 器件,每写一次要等待一段时间,否则写失败!

}


4.AT24CXX 里面的指定地址开始写入长度为 Len 的数据

//在 AT24CXX 里面的指定地址开始写入长度为 Len 的数据

//该函数用于写入 16bit 或者 32bit 的数据.

//WriteAddr :开始写入的地址

//DataToWrite:数据数组首地址

//Len :要写入数据的长度 2,4


void AT24CXX_WriteLenByte(u16 WriteAddr,u32 DataToWrite,u8 Len)

{

    u8 t;

    for(t=0;t

        AT24CXX_WriteOneByte(WriteAddr+t,(DataToWrite>>(8*t))&0xff);

}


5.AT24CXX 里面的指定地址开始读出长度为 Len 的数据

//在 AT24CXX 里面的指定地址开始读出长度为 Len 的数据

//该函数用于读出 16bit 或者 32bit 的数据.

//ReadAddr :开始读出的地址

//返回值 :数据

//Len :要读出数据的长度 2,4


u32 AT24CXX_ReadLenByte(u16 ReadAddr,u8 Len)

{

    u8 t; u32 temp=0;

    for(t=0;t

    {

        temp<<=8;

        temp+=AT24CXX_ReadOneByte(ReadAddr+Len-t-1);

    }

    return temp;

}


6.检查 AT24CXX 是否正常

//检查 AT24CXX 是否正常

//这里用了 24XX 的最后一个地址(255)来存储标志字.

//如果用其他 24C 系列,这个地址要修改

//返回 1:检测失败

//返回 0:检测成功

u8 AT24CXX_Check(void)

{

    u8 temp;

    temp=AT24CXX_ReadOneByte(255);//避免每次开机都写 AT24CXX

    if(temp==0X55)

        return 0;

    else//排除第一次初始化的情况

    {

        AT24CXX_WriteOneByte(255,0X55);

        temp=AT24CXX_ReadOneByte(255);

        if(temp==0X55)

            return 0;

    }

    return 1;

}


7.AT24CXX 里面的指定地址开始读出指定个数的数据

/在 AT24CXX 里面的指定地址开始读出指定个数的数据

//ReadAddr :开始读出的地址 对 24c02 为 0~255

//pBuffer :数据数组首地址

//NumToRead:要读出数据的个数


void AT24CXX_Read(u16 ReadAddr,u8 *pBuffer,u16 NumToRead)

{

    while(NumToRead)

    {

        *pBuffer++=AT24CXX_ReadOneByte(ReadAddr++);

        NumToRead--;

    }

}


8.AT24CXX 里面的指定地址开始写入指定个数的数据

//在 AT24CXX 里面的指定地址开始写入指定个数的数据

//WriteAddr :开始写入的地址 对 24c02 为 0~255

//pBuffer :数据数组首地址

//NumToWrite:要写入数据的个数


void AT24CXX_Write(u16 WriteAddr,u8 *pBuffer,u16 NumToWrite)

{

    while(NumToWrite--)

    {

        AT24CXX_WriteOneByte(WriteAddr,*pBuffer);

        WriteAddr++;

        pBuffer++;

    }

}


参考:

1.原子 STM32 开发库函数版本


关键字:IIC  STM32  驱动AT24C02

编辑:什么鱼 引用地址:http://www.eeworld.com.cn/mcu/2019/ic-news010942856.html
本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:SPI专题(二)——STM32驱动FLASH(W25Q64)
下一篇:最后一页

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

STM32硬件IIC驱动设计

前言stm32的硬件IIC一直是令人诟病的地方,以至于很多情况下我们不得不选择使用模拟IIC的方式来在stm32上进行iic通讯。我在stm32 iic通讯上也浪费了几多青春。。。经过不断地探索最终还是成功了(可喜可贺啊),现在把我的探索成功的经验分享出来,如果能减少读者在硬件iic上面浪费的时间,那真是太棒了! 关于IIC通讯众所周知IIC是一种通讯方式。。。所以有必要先介绍一下IIC通信,省的下面不知道不知道我在写什么。当然这些都是基础,你可以选择跳过,直接看第三部分STM32的IICIIC是什么说实话这个问题有点难,我就百度了一下,描述如下IIC 即Inter-Integrated Circuit(集成电路总线
发表于 2018-12-29
STM32硬件IIC驱动设计

STM32 模拟IIC主设备 非IIC静默模式

//为啥用软件模拟IIC而不用硬件IIC? 除了ST的IIC模块本身问题,还因为硬件IIC移植不方便,在不同的MCU中无法通用。/****************************Copyright(c)*********************************************                                    **--------------文件信息
发表于 2018-12-29

C51 GPIO口模拟IIC读写24CXX

#include <reg52.h>#define delayNOP() {_nop_(); _nop_(); _nop_(); _nop_();}//IIC 开始信号void iic_start(void){    SDA = 1;    SCL = 1;    delayNOP();    SDA = 0;    delayNOP();    SCL = 0;}//IIC 停止信号void iic_stop(void){    SDA = 0;   
发表于 2018-12-19

STM32Cube MX 下IIC的配置与使用

本文介绍了在STM32下的IIC的基本使用方法,通过对板载具备IIC接口EEPROM的读写,完成对IIC驱动程序的测试。硬件平台:STM32F107VCT6开发板软件平台:STM32Cube MX + MDK5.221. 进行STM32Cube MX的配置配置PB6和PB7为输出模式,同时配置了USART1进行串口调试使用。然后生成工程。2. 打开工程,可以看到GPIO的初始化状态3. 模拟IIC驱动程序源文件代码/**  * @file  iic_dup.c  * @brief IIC上层程序  * @par   date     
发表于 2018-11-26
STM32Cube MX 下IIC的配置与使用

STM32硬件IIC与51模拟IIC通信

IIC介绍  IIC协议规定:SDA上传输的数据必须在SCL为高电平期间保持稳定,SDA上的数据只能在SCL为低电平期间变化。IIC期间在脉冲上升沿把数据放到SDA上,在脉冲下降沿从SAD上读取数据。这样的话,在SCL高电平期间,SDA上的数据是稳定的。在脉冲下降沿之后的保持时间以后,SDA上的数据可以变化,直到脉冲上升沿之前。STM32与51 IIC通信实验  下面是在使用51模拟IIC作为主机、STM32硬件IIC作为从机时发生的一些问题:STM32地址不匹配:   1、STM32工作为从机接收器模式下时,STM32设置IIC地址为0x0A但是I2C_OAR1寄存器中的地址为0x05,所以51发送地址时,应该发送
发表于 2018-11-26

【STM32 IIC详解】stm32 IIC从机模式(中断方式收发数据)

1、IIC简介 第二节代码会用到该部分内容,对于IIC来说,从机是不能主动发送数据的,开始条件都是由主机生成。     1.1、主机发送数据流程   1) 主机在检测到总线为“空闲状态”(即 SDA、SCL 线均为高电平)时,发送一个启动信号“S”,开始一次通信的开始  2) 主机接着发送一个命令字节。该字节由 7 位的外围器件地址和 1 位读写控制位 R/W组成(此时 R/W=0)  3) 相对应的从机收到命令字节后向主机回馈应答信号 ACK(ACK=0)  4) 主机收到从机的应答信号后开始发送第一个字节的数据
发表于 2018-11-26

小广播

何立民专栏

单片机及嵌入式宝典

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

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2018 EEWORLD.com.cn, Inc. All rights reserved
pt type="text/javascript" src="//v3.jiathis.com/code/jia.js?uid=2113614" charset="utf-8">