• I2C EEPROM24C02


    1.main.c

    #include <reg52.h>
    #include "..\lib\delay.h"
    #include "..\lib\display.h"
    #include "..\lib\i2c.h"

    #define AddWr 0xae //写数据地址,需要参考24c02芯片文档
    #define AddRd 0xaf //读数据地址

    sbit WP = P1^0;

    /*------------------------------------------------
    写入数据
    ------------------------------------------------
    */
    void WrToRom(unsigned char buffer[], unsigned char address, unsigned char length)
    {
    unsigned char i;
    unsigned char *pData;
    pData = buffer;
    for(i=0;i<length;i++)
    {
    Start_I2C(); //启动IIC总线
    SendByte(AddWr); //写入芯片地址
    Ack(); //应答
    SendByte(address + i); //写入存储地址
    Ack(); //应答
    SendByte(*(pData + i)); //写数据
    Ack();
    Stop_I2C(); //停止IIC总线
    delay_ms(20);
    }
    }
    /*------------------------------------------------
    读出数据
    ------------------------------------------------
    */
    void RdFromRom(unsigned char buffer[], unsigned char address, unsigned char length)
    {
    unsigned char i;
    unsigned char *pData;
    pData = buffer;
    for(i =0;i<length;i++)
    {
    Start_I2C(); //启动IIC总线
    SendByte(AddWr); //写入芯片地址
    Ack(); //应答
    SendByte(address + i); //写入存储地址
    Ack(); //应答

    Start_I2C();
    SendByte(AddRd); //读入地址
    Ack();
    *(pData + i) = RecvByte(); //读数据
    NoAck();
    Stop_I2C(); //停止IIC总线
    }
    }
    /*------------------------------------------------

    ------------------------------------------------
    */
    void main()
    {
    unsigned char i;
    unsigned char number[4] = {1,2,3,4};
    WP = 0; //写保护关掉
    P2 = 0x00;

    WrToRom(number, 4, 4);
    delay_ms(200);

    number[0] = 0;
    number[1] = 0;
    number[2] = 0;
    number[3] = 0;

    RdFromRom(number, 4, 4);

    while(1)
    {
    for(i=0;i<4;i++)
    {
    Display(0, number[i]);
    delay_ms(200);
    delay_ms(200);
    }
    }
    }
    /*------------------------------------------------
    ------------------------------------------------
    */

    2.delay

    #ifndef __DELAY_H__
    #define __DELAY_H__

    void delay_us(unsigned char t);
    void delay_ms(unsigned char t);

    #endif


    #include "delay.h"

    /******************************************************************/
    /* 延时函数 */
    /******************************************************************/
    void delay_us(unsigned char t)
    {
    while(--t);
    }
    /******************************************************************/
    /* 延时函数 */
    /******************************************************************/
    void delay_ms(unsigned char t)
    {
    while(t--)
    {
    //大致延时1ms
    delay_us(245);
    delay_us(245);
    }
    }

    3.display

    #ifndef __DISPLAY_H__
    #define __DISPLAY_H__

    #include <reg52.h>

    /******************************************************************/
    /* 定义端口 */
    /******************************************************************/
    sbit LATCH1 = P2^2; //定义锁存使能端口 段锁存
    sbit LATCH2 = P2^3; // 位锁存

    extern unsigned char TempData[8]; //存储显示值的全局变量
    /*
    *****************************************************************/
    /**/
    /******************************************************************/
    void Display(unsigned char fbit, unsigned char num);

    #endif

    #include "display.h"

    /******************************************************************/
    /* 定义端口 */
    /******************************************************************/
    #define DataPort P0
    #define SegPort P2

    unsigned char code dofly_DuanMa[] =
    {
    0x3f, 0x06, 0x5b, 0x4f,
    0x66, 0x6d, 0x7d, 0x07,
    0x7f, 0x6f, 0x77, 0x7c,
    0x39, 0x5e, 0x79, 0x71
    };
    //unsigned char code dofly_WeiMa[] = {0,1,2,3,4,5,6,7};
    /*
    *****************************************************************/
    /* 显示函数,用于动态扫描数码管 */
    /* bit 表示需要显示的第几位 */
    /* num 表示需要显示的位数,如需要显示99两位数值则该值输入2 */
    /******************************************************************/
    void Display(unsigned char fbit, unsigned char num)
    {
    //static unsigned char i = 0;
    DataPort = 0x00; //清空数据,防止有交替重影
    SegPort = fbit;
    DataPort = dofly_DuanMa[num];
    //if(++i == num)
    //i = 0;
    }

    4.I2C

    #ifndef __I2C_H__
    #define __I2C_H__

    #include <reg52.h>
    #include <intrins.h>

    extern bit _ack; //应答标志位

    void Start_I2C(void); //启动IIC总线
    void Stop_I2C(void); //结束IIC总线

    void SendByte(unsigned char c);
    unsigned char RecvByte(void);
    void Ack(void); //应答IIC总线
    void NoAck(void); //非应答IIC总线

    #endif


    /*-----------------------------------------------------------------
    名称:IIC协议
    内容:函数是采用软件延时的方法产生SCL脉冲,固对高晶振频率要作一定的修改
    (本例是1us机器周期,即晶振频率要小于12MHZ)
    ------------------------------------------------------------------
    */
    #include "i2c.h"

    /******************************************************************/
    /* 定义变量 */
    /******************************************************************/
    bit _ADFlag; //定义AD采样标志位
    bit _ack; //应答标志位
    /*
    *****************************************************************/
    /* 定义端口 */
    /******************************************************************/
    sbit SCL = P1^1;
    sbit SDA = P1^2;
    /******************************************************************/
    /* 启动IIC总线 */
    /******************************************************************/
    void Start_I2C(void)
    {
    SDA = 1; //发送起始条件的数据信号
    _nop_();_nop_();
    SCL = 1;
    _nop_();_nop_();_nop_();_nop_();_nop_(); //起始条件建立时间大于4.7us,延时
    SDA = 0; //发送起始信号
    _nop_();_nop_();_nop_();_nop_();_nop_(); //起始条件锁定时间大于4μ
    SCL = 0; //钳住I2C总线,准备发送或接收数据
    }
    /******************************************************************/
    /* 停止IIC总线 */
    /******************************************************************/
    void Stop_I2C(void)
    {
    SDA = 0; //发送结束条件的数据信号
    _nop_(); //发送结束条件的时钟信号
    SCL = 1;
    _nop_();_nop_();_nop_();_nop_();_nop_(); //结束条件建立时间大于4μ
    SDA = 1; //发送I2C总线结束信号
    _nop_();_nop_();_nop_();_nop_();_nop_();
    SCL = 0;
    }
    /******************************************************************/
    /* 应答IIC总线 */
    /******************************************************************/
    void Ack(void)
    {
    SDA = 0;
    _nop_();_nop_();_nop_();
    SCL = 1;
    _nop_();_nop_();_nop_();_nop_();_nop_();
    SCL = 0;
    _nop_();_nop_();
    }
    /******************************************************************/
    /* 非应答IIC总线 */
    /******************************************************************/
    void NoAck(void)
    {
    SDA = 1;
    _nop_();_nop_();_nop_();
    SCL = 1;
    _nop_();_nop_();_nop_();_nop_();_nop_(); //时钟低电平周期大于4μ
    SCL = 0;
    _nop_();_nop_();
    }
    /******************************************************************/
    /* 发送一个字节 */
    /******************************************************************/
    void SendByte(unsigned char b)
    {
    unsigned char count = 8;
    do
    {
    SCL = 0;
    _nop_();_nop_();_nop_();_nop_();_nop_();
    if((b & 0x80) == 0x80)
    SDA = 1;
    else
    SDA = 0;

    SCL = 1;
    b = b << 1;
    //_nop_();_nop_();_nop_();_nop_();_nop_();
    //SCL = 0;
    }
    while(--count);

    // _nop_();_nop_();
    // SDA = 1; //8位发送完后释放数据线,准备接收应答位
    // _nop_();_nop_();
    // SCL = 1;
    // _nop_();_nop_();_nop_();
    // if(SDA == 1)
    // _ack = 0;
    // else
    // _ack = 1;
    // SCL = 0;
    // _nop_();_nop_();
    SCL = 0;
    }
    /******************************************************************/
    /* 读入一个字节并返回 */
    /******************************************************************/
    unsigned char RecvByte(void)
    {
    unsigned char temp = 0;
    unsigned char count = 8;

    SDA = 1; //置数据线为输入方式
    do
    {
    SCL = 0; //置时钟线为低,准备接收数据位
    _nop_();_nop_();_nop_();_nop_();_nop_();
    SCL = 1; //置时钟线为高使数据线上数据有效
    _nop_();_nop_();_nop_();_nop_();_nop_();

    if(SDA)
    temp = temp | 0x01; //读数据位,接收的数据位放入temp中
    else
    temp = temp & 0xfe;

    if(count - 1)
    {
    temp = temp << 1;
    }
    }
    while(--count);
    SCL = 0;
    return temp;
    }
  • 相关阅读:
    9月9号作业
    9月9号笔记
    jupyter的补充
    jupyter的使用
    9月6号作业
    编程语言的分类
    计算机组成
    计算机组成的补充
    面向对象基础
    9月2号作业
  • 原文地址:https://www.cnblogs.com/LinFx/p/2330456.html
Copyright © 2020-2023  润新知