• 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;
    }
  • 相关阅读:
    饿了么P7级前端工程师进入大厂的面试经验
    前端程序员面试的坑,简历写上这一条信息会被虐死!
    这次来分享前端的九条bug吧
    移动端开发必会出现的问题和解决方案
    创建一个dynamics 365 CRM online plugin (八)
    创建一个dynamics 365 CRM online plugin (七)
    创建一个dynamics 365 CRM online plugin (六)
    创建一个dynamics 365 CRM online plugin (五)
    使用User Primary Email作为GUID的问题
    怎样Debug Dynamics 365 CRM Plugin
  • 原文地址:https://www.cnblogs.com/LinFx/p/2330456.html
Copyright © 2020-2023  润新知