Dai_Weis的笔记 https://bbs.21ic.com/?429416 [收藏] [复制] [RSS] 我的Blog偶尔写了自己的和别人的心得,交流交流,欢迎访问 内容来自网上和自己的心得,欢迎转载。 如果有内容侵犯了您的权益请来信告知 本网站引用的第三方的文章均由原著作者所有,如果所标示的作者非原始著作者,则本网站不承担查证责任。 cfso_v@sina.com

日志

模拟 IIC 的小程序

已有 1035 次阅读2007-12-15 20:34 |个人分类:班门弄斧|系统分类:单片机| 24C02访问的程序

本程序是我在网上收集的,我已经找不到原始作者了,我尽量保留了原来的风格,请原著作者与我联系,填写版权信息

 

//版权信息:暂空

/*the header files name is AT24C01.h
 *the header files program's function is link exterior extend E2PROM
 *the link chip's name is AT24C01A
 *the program's synopsis as follows
 * Author by:weiyi
 * Establish on Date:31-10-2002
 * Modified on Date:31-10-2002
 * Edition NO.:V1.0*/
 
 /*简介:
 A.本AT24C01A接口驱动程序的使用非常简单。在你的源程序包含此头文件后你所要做的
是:
     1。定义与你单片机所连接的相应口线号(bSda & bScl);
     2。设置你的芯片所连接的地址(A2-A0);你可以对你的芯片编号,比如Chip_1
对应
        一个地址、Chip_2对应另一个地址(AT24家族中最多可以定义8个),访问芯
片时你
        只需带入芯片号,程序便能连接你想要访问的芯片,同时进行读写操作。
 B.此驱动程序与你有关的主要内容为:
     1.2个涵数<ReadMem(l,x,y);>、<WriteMem(l,x,y)>;
     2.1个宏定义<#define Chip_x(器件号) y(具体器件A2-A0地址号)>;
     3.2个口线定义<sbit bScl =Px^x;、sbit bSda =Px^x;>;
     4.一个缓冲数组<cShareBuf[10]>,所有读写数据都会经此数组中转。
 C.你在源程序中调用这里面的涵数相当方便,请看试例;
 D.本程序的测试频率为:12.000MHz
 注意:1.如果在包含此头文件前有其他程序(包括其他程序、头文件里程序)使用了此头文
件内的某
      一涵数、宏等,请将包含此头文件的关键词放置在它前面,或将本头文件内
相应申明(或定义)
       放置于他的前面的任何一个地方甚至于他内部(也可以申明一个专门用于放
置一些涵数的申明、宏定义、
       口线定义的头文件,然后将一些涵数的申明放在内部以实现共用不冲突)
    2.读写的数据都是通过变量数组交换的,所以写之前必须将数据有规律的放置
在cShareBuf之中;执行
      完读功能后在cShareBuf之中取出数据*/
/*Sample:

/*main(){    ...
/*    ReadMem(l,x,y);    /*读。l为本次访问的器件号,在宏定义时分配不同芯
片的不同器件号,
            x为本次欲读出的字节数;y为本次读数的起始地址*/
/*    ...
/*    WriteMem(l,x,y);    /*写。l为本次访问的器件号,在宏定义时分配不同芯
片不同的器件号,
            x为本次欲写入的字节数;y为本次写数的起始地址,
            注:当心页写入的地址规律,即页地址在同一页内滚
动;否则会出现页溢出*/
/*}*/


#define    Wait1us        _nop_();
#define    Wait2us        {_nop_();_nop_();}
#define    Wait4us        {Wait2us;Wait2us;}
#define    Wait8us        {Wait4us;Wait4us;}
#define    Wait10us    {Wait8us;Wait2us;}
#define StartIic  {bSda=bScl=1;Wait8us;bSda=0;Wait8us;bScl=0;}
#define EndIic {bSda=0;bScl=1;Wait8us;bSda=1;}
#define    SlaWr        0xA0    /*0000 0 0 0 0*/
#define    SlaRd        0xA1    /*0000 0 0 0 1*/
#define    Chip_ADD        0x0    /*本器件的器件地址,可以第一8个不同地
址的芯片使之能用同一段程序进行读写*/
#include "INTRINS.H"
sbit    bScl = P2 ^ 6; //此处为总线的时钟
sbit    bSda = P2 ^ 5; //此处为总线的数据
sbit bWC = P2 ^ 7; //此处为写保护

unsigned char bdata cFlag;    /**/
    sbit    bRight = cFlag ^ 0;
    sbit    bErr = cFlag ^ 1;
    sbit    bReadOk = cFlag ^ 2;
    sbit    bBeepEn = cFlag ^ 3;
    sbit    bCtrl = cFlag ^ 4;
    sbit    bScanErr = cFlag ^ 5;
    sbit    bAll = cFlag ^ 6;
    sbit    bSame = cFlag ^ 7;
unsigned char data cShareBuf[9];    /*I2c read and write buffer*/

unsigned char ScanIic();
void SendIic(unsigned char cData);
void SendAck(void);
void SendNotAck(void);
void WriteMem(unsigned char cChipsAdd,cSize,cAddress);
void ReadMem(unsigned char cChipsAdd,cSize,cAddress);
/************Name:ScanIic***********
Function:Read 1byte data from 24C01
NO.:1
Run time:145us    1=10us    0=10us    f=50kbps
**********Function Start************/
unsigned char ScanIic()
{
    unsigned char data i,j;/*IIC data*/
    //StopDog;    /*喂狗*/
    bSda = 1;
    j = 0;
    for(i = 0; i < 8; i ++)
 {
        bScl = 1;
        Wait2us;
        j <<= 1;/*这个指令已经有15个周期,所以无须再延时*/
        j |= bSda;/*Scan 0*/    /*Scan 1*/
        bScl = 0;
        Wait1us;
    }
    return (j);
}
/**********Function End*************/

/************Name:SendIic***********
Function:Send 1byte to 24C01
NO.:2
Run time:150us    1=10us    0=13us    f=43.5kbps
**********Function Start************/
void SendIic(unsigned char cData)
{
    unsigned char data i;
    //StopDog;    /*喂狗*/
    for(i = 0; i < 8; i ++)
 {
        bSda = (bit)(cData&0x80);
        bScl = 1;
        cData <<= 1;
        Wait4us;
        Wait2us;
        bScl = 0;
    }
    bSda = bScl = 1;    /*检测ACK*/
    for(i = 0; (bSda == 1) && (bScanErr == 0); i ++)
 {
        //StopDog;    /*喂狗*/
        if(i == 17)
        {
            bScanErr = 1;/*如果101us没有响应就错误*/
  }
    }
    bScl = 0;
}
/**********Function End*************/

/************Name:SendAck***********
Function:Send ack
NO.:3
Run time:12us
**********Function Start************/
void SendAck(void)
{
    bSda = 0;
    bScl = 1;
    Wait10us;
    bScl = 0;
    bSda = 1;
}
/**********Function End*************/

/************Name:SendNotAck***********
Function:send not ack
NO.:4
Run time:11us
**********Function Start************/
void SendNotAck(void)
{
    bScl = bSda = 1;
    Wait10us;
    bScl = 0;
}   
/**********Function End*************/
/************Name:WriteMem***********
Function:write data to 24C01
NO.:5
Run time:xx
**********Function Start************/
void WriteMem(unsigned char cChipsAdd, cSize, cAddress)
{
    unsigned char data i;
    //StopDog;    /*喂狗*/
 Wait10us;
    bScanErr = 0;
    i = SlaWr;
    i |= cChipsAdd;
    StartIic;
    SendIic(i);/*SLA*/
    SendIic(cAddress);/*address*/
    for(i = 0;(bScanErr == 0) && (i != cSize); i ++)
 {
        SendIic(cShareBuf);    /*写一个字节数据*/
 }
    EndIic;
 Wait10us;
}
/**********Function End*************/

/************Name:ReadMem***********
Function:Read data from 24C01
NO.:6
Run time:xx
**********Function Start************/
void ReadMem(unsigned char cChipsAdd, cSize, cAddress)
{
    unsigned char data i;
    //StopDog;    /*喂狗*/
    bScanErr = 0;
    i = SlaWr;
    i |= cChipsAdd;
    StartIic;
    SendIic(i);/*address and  read*/
    SendIic(cAddress);/*address and write*/
    i |= 0x1;    /*Read*/
    StartIic;
    SendIic(i);/*address and  read*/
    for(i = 0; (bScanErr == 0) && (i != cSize); i ++)
 {
        cShareBuf = ScanIic();/*读入第一个字节*/
        if(i == (cSize - 1))
  {
            SendNotAck();           
  }
        else
      {
            SendAck();
  }
    }
    EndIic;
}
/**********Function End*************/

路过

鸡蛋

鲜花

握手

雷人

评论 (0 个评论)