24C02测试程序
24C02读写程序

HT49 MCU系列单片机读写HT24系列的EEPROM应用范例HT49 MCU系列单片机读写HT24系列的EEPROM应用范例文件编码:HA0017s简介:HT24系列的EEPROM是通过I2C协议控制其读写的。
HT49系列单片机的接口部分是简单I/O 口,可以用来很方便地采用I2C协议控制周边器件。
HT24系列的EEPROM总共8个管脚,三个为芯片地址脚A0、A1、A2,在单片机对它进行操作时,从SDA输入A0、A1、A2数据和芯片外部A0、A1、A2所接地址需一一对应。
一个为芯片写保护脚WP,WP脚接低电平时,芯片可进行读写操作;WP脚接高时,芯片只可进行读,不可进行写。
另外两个管脚为电源脚VCC,VSS。
用单片机对HT24系列的EEPROM进行控制时,HT24系列的EEPROM的外部管脚VCC、VSS、WP、A0、A1、A2根据需要,对应接上,SDA、SCL接到单片机控制脚上。
引脚名称I/O 功能描述A0~A2 I地址输入VSS I电源负极输入SDA I/O串行数据输入/输出SCL I串行数据传送时钟信号输入WP I写保护VCC I电源正极输入HT24系列的EEPROM根据型号不同,EEPROM的容量大小不同,当EEPROM的空间大于1页(256bytes)时,即大于2048bits,则HT49 MCU需要控制A0、A1、A2来确定写HT24系列的EEPROM的第几页,HT24系列的EEPROM空间大小如下表所示:型号引脚A0、A1及A2使用方法容量大小HT24LC02 A0、A1、A2引脚作为器件地址输入,从SDA输入A0、A1、A2数据和芯片引脚A0、A1、A2所接状态需一一对应2K(256×8)HT24LC04 A1、A2引脚作为器件地址输入,从SDA输入A1、A2数据和芯片引脚A1、A2所接状态需一一对应,A0引脚浮空4K(512×8,2pages)HT24LC08 A2引脚器件地址输入,从SDA输入A2数据和芯片引脚A2所接状态需一一对应,其余引脚浮空8K(1024×8,4pages)HT24LC16 A0、A1、A2全部浮空,不必接16K(2048×8,8pages)HT49 MCU系列单片机读写HT24系列的EEPROM应用范例程式说明:本文是以HT49R30A-1控制HT24LC04为例的。
AT24C02操作方法及程序(含时序图)

总线工作原理
I2C 总线进行数据传送时,时钟信号为高电平期间,数据线上的数据必须保持稳定,只有在时钟线上的信号为低电平期间,数据线上的高电平或低电平状态才允许变化。
起始和终止信号 :SCL 线为高电平期间,SDA 线由高电平向低电平的变化表示起始信号;SCL 线为高电平期间,SDA 线由低电平向高电平的变化表示终止信号。
数据传送格式(1)字节传送与应答
每一个字节必须保证是8位长度。
数据传送时,先传送最高位(MSB ),每一个被传送的字节后面都必须跟随一位应答位(即一帧共有9位)。
如果一段时间内没有收到从机的应答信号,则自动认为从机已正确接收到数据。
AT24C02的芯片地址如下图,1010为固定,A0,A1,A2正好与芯片的1,2,3引角对应,为当前电路中的地址选择线,三根线可选择8个芯片同时连接在电路中,当要与哪个芯片通信时传送相应的地址即可与该芯片建立连接,TX-1B 实验板上三根地址线都为0。
最后一位R/W 为告诉从机下一字节数据是要读还是写,0为写入,1为读出。
AT24C02的芯片地址(0xa0为写,0xa1为读)
任一地址写入数据格式
任一地址读取数据格式。
24C02与按键结合程序

//广西柳州市一职校电气自动化专业部//By: China o soft#include <r eg52.h>//使用8052内核单片机#include <stdlib.h>//使用rand随机数函数sbit SCL=P1^0;//IIC时钟线(SCL)定义sbit SDA=P1^1;//IIC数据线(SDA)定义sbit K EY1=P2^0;//按钮1,用于将地址+1sbit K EY2=P2^1;//按钮2,用于将地址-1sbit K EY3=P2^2;//按钮3,用于将数据+1sbit BEEP=P2^3;//蜂鸣器,当读写测试失败时报警sbit K EY5=P1^2;//按钮5,用于读取当前地址数据sbit K EY6=P1^3;//按钮6,用于在现地址写入当前数据sbit K EY7=P1^4;//按钮7,用于进行256字节的读写测试sbit K EY4=P1^5;//按钮4,用于将数据-1unsigned char code L ED_SEG[16]={0x88,0xBE,0xC4,0x94,0xB2,0x91,0x81,0xBC,0x80,0x90,0xA0,0x83,0xC9,0x86,0xC1,0xE1};//数码管段码表0-f;a:D1,b:D0,c:D6,d:D5,e:D4,f:D2,g:D3,dp:D 7unsigned char D1,D2,D3,D4;//显示在数码管上的值unsigned char ADDR,INDEX;//当前地址,当前数据变量void e eprom_write_byte(unsigned char addr,dat)//eeprom写字节,传递参数1:要写的地址,参数2:要写的数据{//写字节程序开始unsigned char t emp1,t emp2;//写入延时使用的临时变量SCL=1;//时钟线(SCL)拉高SDA=1;//数据线(SDA)拉高SDA=0;//在时钟线(SCL)为高电平时,数据线(SDA)发生下跳变,总线启动 SCL=0;//只有时钟线(SCL)为低电平时才可以改变数据线(SDA)的状态SDA=1;//AT24C02eeprom的器件地址(A0-A2接地),1010000x.SCL=1;//读入一位数据(1)SCL=0;//只有时钟线(SCL)为低电平时才可以改变数据线(SDA)的状态SDA=0;//将数据0放到总线上SCL=1;//读入一位数据(0)SCL=0;//只有时钟线(SCL)为低电平时才可以改变数据线(SDA)的状态SDA=1;//将数据1放到总线上SCL=1;//读入一位数据(1)SCL=0;//只有时钟线(SCL)为低电平时才可以改变数据线(SDA)的状态SDA=0;//将数据0放到总线上SCL=1;//读入一位数据(0)SCL=0;//只有时钟线(SCL)为低电平时才可以改变数据线(SDA)的状态SDA=0;//将数据0放到总线上SCL=1;//读入一位数据(0)SCL=0;//只有时钟线(SCL)为低电平时才可以改变数据线(SDA)的状态SDA=0;//将数据0放到总线上SCL=1;//读入一位数据(0)SCL=0;//只有时钟线(SCL)为低电平时才可以改变数据线(SDA)的状态SDA=0;//将数据0放到总线上SCL=1;//读入一位数据(0)SCL=0;//只有时钟线(SCL)为低电平时才可以改变数据线(SDA)的状态SDA=0;//将数据0放到总线上,此位特殊,为0代表写,为1代表读SCL=1;//读入一位数据(0,写数据)SCL=0;//只有时钟线(SCL)为低电平时才可以改变数据线(SDA)的状态SDA=1;//放开数据线(SDA),以使得eeprom能够应答SCL=1;//发送第九个脉冲,让eeprom应答,应答信号从数据线(SDA)输出SCL=0;//应答结束,如果需要判断是否应答,应检查数据线(SDA)电平,本程序不检查SDA=addr&0X80;//将地址的最高位(MSB)放到总线上SCL=1;//写入最高位(MSB D7)SCL=0;//只有时钟线(SCL)为低电平时才可以改变数据线(SDA)的状态SDA=addr&0X40;//将地址的D6位放到总线上SCL=1;//写入数据位(D6)SCL=0;//只有时钟线(SCL)为低电平时才可以改变数据线(SDA)的状态SDA=addr&0X20;//将地址的D5位放到总线上SCL=1;//写入数据位(D5)SCL=0;//只有时钟线(SCL)为低电平时才可以改变数据线(SDA)的状态SDA=addr&0X10;//将地址的D4位放到总线上SCL=1;//写入数据位(D4)SCL=0;//只有时钟线(SCL)为低电平时才可以改变数据线(SDA)的状态SDA=addr&0X08;//将地址的D3位放到总线上SCL=1;//写入数据位(D3)SCL=0;//只有时钟线(SCL)为低电平时才可以改变数据线(SDA)的状态SDA=addr&0X04;//将地址的D2位放到总线上SCL=1;//写入数据位(D2)SCL=0;//只有时钟线(SCL)为低电平时才可以改变数据线(SDA)的状态SDA=addr&0X02;//将地址的D1位放到总线上SCL=1;//写入数据位(D1)SCL=0;//只有时钟线(SCL)为低电平时才可以改变数据线(SDA)的状态SDA=addr&0X01;//将地址的(LSB D0)位放到总线上SCL=1;//写入数据位(D0)SCL=0;//只有时钟线(SCL)为低电平时才可以改变数据线(SDA)的状态SDA=1;//放开数据线(SDA),以使得eeprom能够应答SCL=1;//发送第九个脉冲,让eeprom应答,应答信号从数据线(SDA)输出SCL=0;//应答结束,如果需要判断是否应答,应检查数据线(SDA)电平,本程序不检查SDA=dat&0X80;//将数据的最高位(MSB)放到总线上SCL=1;//写入数据位(MSB D7)SCL=0;//只有时钟线(SCL)为低电平时才可以改变数据线(SDA)的状态SDA=dat&0X40;//将数据的D6位放到总线上SCL=1;//写入数据位(D6)SCL=0;//只有时钟线(SCL)为低电平时才可以改变数据线(SDA)的状态SDA=dat&0X20;//将数据的D5位放到总线上SCL=1;//写入数据位(D5)SCL=0;//只有时钟线(SCL)为低电平时才可以改变数据线(SDA)的状态SDA=dat&0X10;//将数据的D4位放到总线上SCL=1;//写入数据位(D4)SCL=0;//只有时钟线(SCL)为低电平时才可以改变数据线(SDA)的状态SDA=dat&0X08;//将数据的D3位放到总线上SCL=1;//写入数据位(D3)SCL=0;//只有时钟线(SCL)为低电平时才可以改变数据线(SDA)的状态SDA=dat&0X04;//将数据的D2位放到总线上SCL=1;//写入数据位(D2)SDA=dat&0X02;//将数据的D1位放到总线上SCL=1;//写入数据位(D1)SCL=0;//只有时钟线(SCL)为低电平时才可以改变数据线(SDA)的状态SDA=dat&0X01;//将数据的D0位(LSB)放到总线上SCL=1;//写入数据位(D0)SCL=0;//只有时钟线(SCL)为低电平时才可以改变数据线(SDA)的状态SDA=1;//放开数据线(SDA),以使得eeprom能够应答SCL=1;//发送第九个脉冲,让eeprom应答,应答信号从数据线(SDA)输出SCL=0;//应答结束,如果需要判断是否应答,应检查数据线(SDA)电平,本程序不检查SDA=0;//拉低数据线(SDA)SCL=1;//拉高时钟线(SCL)SDA=1;//在时钟线(SCL)为高电平时,数据线(SDA)发生上跳变,停止总线//按ATMEL的手册,每次写完,都应该延时5ms以上temp1=t emp2=20;//准备延时do//外层do-while循环{//外层循环开始do//内层do-while循环{//内层循环开始;//空操作,延时}while(--t emp2);//do-while结构}while(--t emp1);//do-while结构}//写字节程序结束unsigned char e eprom_read_byte(unsigned char addr)//eeprom读字节,传递参数为要读的地址,返回读到的数据{//读字节程序开始unsigned char temp;//接收数据用的临时变量SCL=1;//时钟线(SCL)拉高SDA=1;//数据线(SDA)拉高SDA=0;//在时钟线(SCL)为高电平时,数据线(SDA)发生下跳变,总线启动SCL=0;//只有时钟线(SCL)为低电平时才可以改变数据线(SDA)的状态SDA=1;//AT24C02eeprom的器件地址(A0-A2接地),1010000x.SCL=1;//读入一位数据(1)SCL=0;//只有时钟线(SCL)为低电平时才可以改变数据线(SDA)的状态SDA=0;//将数据0放到总线上SCL=1;//读入一位数据(0)SCL=0;//只有时钟线(SCL)为低电平时才可以改变数据线(SDA)的状态SDA=1;//将数据1放到总线上SCL=1;//读入一位数据(1)SCL=0;//只有时钟线(SCL)为低电平时才可以改变数据线(SDA)的状态SDA=0;//将数据0放到总线上SCL=1;//读入一位数据(0)SCL=0;//只有时钟线(SCL)为低电平时才可以改变数据线(SDA)的状态SDA=0;//将数据0放到总线上SCL=1;//读入一位数据(0)SCL=0;//只有时钟线(SCL)为低电平时才可以改变数据线(SDA)的状态SDA=0;//将数据0放到总线上SCL=1;//读入一位数据(0)SDA=0;//将数据0放到总线上SCL=1;//读入一位数据(0)SCL=0;//只有时钟线(SCL)为低电平时才可以改变数据线(SDA)的状态SDA=0;//将数据0放到总线上,此位特殊,为0代表写,为1代表读SCL=1;//读入一位数据(0,写数据)SCL=0;//只有时钟线(SCL)为低电平时才可以改变数据线(SDA)的状态SDA=1;//放开数据线(SDA),以使得eeprom能够应答SCL=1;//发送第九个脉冲,让eeprom应答,应答信号从数据线(SDA)输出SCL=0;//应答结束,如果需要判断是否应答,应检查数据线(SDA)电平,本程序不检查SDA=addr&0X80;//将地址的最高位(MSB)放到总线上SCL=1;//写入最高位(MSB D7)SCL=0;//只有时钟线(SCL)为低电平时才可以改变数据线(SDA)的状态SDA=addr&0X40;//将地址的D6位放到总线上SCL=1;//写入数据位(D6)SCL=0;//只有时钟线(SCL)为低电平时才可以改变数据线(SDA)的状态SDA=addr&0X20;//将地址的D5位放到总线上SCL=1;//写入数据位(D5)SCL=0;//只有时钟线(SCL)为低电平时才可以改变数据线(SDA)的状态SDA=addr&0X10;//将地址的D4位放到总线上SCL=1;//写入数据位(D4)SCL=0;//只有时钟线(SCL)为低电平时才可以改变数据线(SDA)的状态SDA=addr&0X08;//将地址的D3位放到总线上SCL=1;//写入数据位(D3)SCL=0;//只有时钟线(SCL)为低电平时才可以改变数据线(SDA)的状态SDA=addr&0X04;//将地址的D2位放到总线上SCL=1;//写入数据位(D2)SCL=0;//只有时钟线(SCL)为低电平时才可以改变数据线(SDA)的状态SDA=addr&0X02;//将地址的D1位放到总线上SCL=1;//写入数据位(D1)SCL=0;//只有时钟线(SCL)为低电平时才可以改变数据线(SDA)的状态SDA=addr&0X01;//将地址的(LSB D0)位放到总线上SCL=1;//写入数据位(D0)SCL=0;//只有时钟线(SCL)为低电平时才可以改变数据线(SDA)的状态SDA=1;//放开数据线(SDA),以使得eeprom能够应答SCL=1;//发送第九个脉冲,让eeprom应答,应答信号从数据线(SDA)输出SCL=0;//应答结束,如果需要判断是否应答,应检查数据线(SDA)电平,本程序不检查SCL=1;//时钟线(SCL)拉高SDA=1;//数据线(SDA)拉高SDA=0;//在时钟线(SCL)为高电平时,数据线(SDA)发生下跳变,总线启动SCL=0;//只有时钟线(SCL)为低电平时才可以改变数据线(SDA)的状态SDA=1;//AT24C02eeprom的器件地址(A0-A2接地),1010000x.SCL=1;//读入一位数据(1)SCL=0;//只有时钟线(SCL)为低电平时才可以改变数据线(SDA)的状态SDA=0;//将数据0放到总线上SCL=1;//读入一位数据(0)SCL=0;//只有时钟线(SCL)为低电平时才可以改变数据线(SDA)的状态SDA=1;//将数据1放到总线上SCL=1;//读入一位数据(1)SCL=0;//只有时钟线(SCL)为低电平时才可以改变数据线(SDA)的状态SDA=0;//将数据0放到总线上SCL=1;//读入一位数据(0)SCL=0;//只有时钟线(SCL)为低电平时才可以改变数据线(SDA)的状态SDA=0;//将数据0放到总线上SCL=1;//读入一位数据(0)SCL=0;//只有时钟线(SCL)为低电平时才可以改变数据线(SDA)的状态SDA=0;//将数据0放到总线上SCL=1;//读入一位数据(0)SCL=0;//只有时钟线(SCL)为低电平时才可以改变数据线(SDA)的状态SDA=0;//将数据0放到总线上SCL=1;//读入一位数据(0)SCL=0;//只有时钟线(SCL)为低电平时才可以改变数据线(SDA)的状态SDA=1;//将数据1放到总线上,此位特殊,为0代表写,为1代表读SCL=1;//读入一位数据(1,读数据)SCL=0;//只有时钟线(SCL)为低电平时才可以改变数据线(SDA)的状态SDA=1;//放开数据线(SDA),以使得eeprom能够应答SCL=1;//发送第九个脉冲,让eeprom应答,应答信号从数据线(SDA)输出SCL=0;//应答结束,如果需要判断是否应答,应检查数据线(SDA)电平,本程序不检查temp=temp|SDA;//应答结束后,第1位数据(MSB D7)已经送出,直接读取SCL=1;//释放时钟线(SCL),以准备产生下降沿SCL=0;//拉低时钟线(SCL),以产生下降沿,使eeprom送出第2位数据(D6)temp=temp<<1;//临时变量移位,以准备拼合新接收到的位temp=temp|SDA;//拼合新的数据位SCL=1;//释放时钟线(SCL),以准备产生下降沿SCL=0;//拉低时钟线(SCL),以产生下降沿,使eeprom送出第3位数据(D5)temp=temp<<1;//临时变量移位,以准备拼合新接收到的位temp=temp|SDA;//拼合新的数据位SCL=1;//释放时钟线(SCL),以准备产生下降沿SCL=0;//拉低时钟线(SCL),以产生下降沿,使eeprom送出第4位数据(D4)temp=temp<<1;//临时变量移位,以准备拼合新接收到的位temp=temp|SDA;//拼合新的数据位SCL=1;//释放时钟线(SCL),以准备产生下降沿SCL=0;//拉低时钟线(SCL),以产生下降沿,使eeprom送出第5位数据(D3)temp=temp<<1;//临时变量移位,以准备拼合新接收到的位temp=temp|SDA;//拼合新的数据位SCL=1;//释放时钟线(SCL),以准备产生下降沿SCL=0;//拉低时钟线(SCL),以产生下降沿,使eeprom送出第6位数据(D2)temp=temp<<1;//临时变量移位,以准备拼合新接收到的位temp=temp|SDA;//拼合新的数据位SCL=1;//释放时钟线(SCL),以准备产生下降沿SCL=0;//拉低时钟线(SCL),以产生下降沿,使eeprom送出第7位数据(D1)temp=temp<<1;//临时变量移位,以准备拼合新接收到的位temp=temp|SDA;//拼合新的数据位SCL=1;//释放时钟线(SCL),以准备产生下降沿SCL=0;//拉低时钟线(SCL),以产生下降沿,使eeprom送出第8位数据(D0)temp=temp<<1;//临时变量移位,以准备拼合新接收到的位temp=temp|SDA;//拼合新的数据位SDA=1;//放开数据线(SDA),以使得eeprom能够应答,此次eeprom将不应答.SCL=1;//发送第九个脉冲,让eeprom应答,应答信号从数据线(SDA)输出SCL=0;//应答结束,如果需要判断是否应答,应检查数据线(SDA)电平,本程序不检查SDA=0;//拉低数据线(SDA)SCL=1;//拉高时钟线(SCL)SDA=1;//在时钟线(SCL)为高电平时,数据线(SDA)发生上跳变,停止总线return(temp);//将读到的数据返回给调用程序}//读字节程序结束void init(void)//初始化程序,打开定时器0,用于扫描4位共阳LED{//初始化程序开始EA=1;//打开总中断ET0=1;//打开定时器0(T0)中断TMOD=0X01;//设置定时器0工作模式为方式1TR0=1;//启动定时器0}//初始化程序结束void L ED_SCAN(void)//LED扫描程序,用于扫描4位共阳LED,状态机机制{static unsigned char NUM;//静态局部变量,记录状态机switch(NUM)//切换状态机{case 0://0分支P2=P2|0XF0;//关闭所有数码管P0=L ED_SEG[D1];//通过查表,将D1内容换成段码放置到P0口P2=P2&0X7F;//打开对应的PNP三极管点亮LEDNUM=1;//状态转移break;//分支结束case 1://1分支P2=P2|0XF0;//关闭所有数码管P0=L ED_SEG[D2];//通过查表,将D2内容换成段码放置到P0口P2=P2&0XBF;//打开对应的PNP三极管点亮LEDNUM=2;//状态转移break;//分支结束case 2://2分支P2=P2|0XF0;//关闭所有数码管P0=L ED_SEG[D3];//通过查表,将D3内容换成段码放置到P0口P2=P2&0XDF;//打开对应的PNP三极管点亮LEDNUM=3;//状态转移break;//分支结束case 3://3分支P2=P2|0XF0;//关闭所有数码管P0=L ED_SEG[D4];//通过查表,将D4内容换成段码放置到P0口P2=P2&0XEF;//打开对应的PNP三极管点亮LEDNUM=0;//状态转移break;//分支结束default://默认、异常分支NUM=0;//恢复状态机到正常值break;//分支结束}//switch-case结束}//扫描程序结束void t imer0(void) interrupt 1 using 2//定时器0中断程序{TH0=(65536-6000)/256;//每6ms扫描一次数码管,高八位TL0=(65536-6000)%256;//每6ms扫描一次数码管,低八位D1=ADDR>>4;//获得高四位数据D2=ADDR&0X0F;//获得低四位数据,左边两位数码管显示地址D3=INDEX>>4;//获得高四位数据D4=INDEX&0X0F;//获得低四位数据,右边两位数码管显示数据LED_SCAN();//数据准备完毕,开始扫描}//定时器0中断程序结束void main(void)//主程序{//主程序开始init();//初始化while(1)//主循环{//主循环开始if(!K EY1){while(!K EY1);ADDR++;}//如果按钮1被按下,则地址+1if(!K EY2){while(!K EY2);ADDR--;}//如果按钮2被按下,则地址-1if(!K EY3){while(!K EY3);INDEX++;}//如果按钮3被按下,则数据+1if(!K EY4){while(!K EY4);INDEX--;}//如果按钮4被按下,则数据-1if(!K EY5){while(!K EY5);INDEX=e eprom_read_byte(ADDR);}//如果按钮5被按下,则在当前地址读出数据if(!K EY6){while(!K EY6);e eprom_write_byte(ADDR,INDEX);}//如果按钮6被按下,则在当前地址写入数据if(!K EY7)//如果按钮7被按下,则进行256字节读写测试 {unsigned char loop,readback;//循环计数变量,回读临时变量srand(T L0);//置随机数种子,不同的种子,将返回不同的随机数序列 BEEP=1;//关闭报警蜂鸣器do//使用do-while循环{//循环开始ADDR=loop;//地址跟随循环计数值变化INDEX=rand();//取随机数eeprom_write_byte(ADDR,INDEX);//在当前地址写入取到的随机数readback=e eprom_read_byte(ADDR);//立即将刚才写入的数据读出来if(INDEX!=readback){BEEP=0;while(K EY7);BEEP=1;}//判断写入的数据和读出的数据是否一致,如不一致则报警//报警后,需要再次按动按钮7来消除报警}while(--loop);//do-while循环结构}//按钮7处理程序结束}//主循环结束}//主程序结束。
I2C串行AT24C02实验

第4章实验01-I2C串行AT24C02实验
一、实验目的:
1、了解I2C总线的工作原理;
2、学习I2C总线与单片机的接口方法;
3、学习串行E2PROM芯片24CXX系列的读写方法;
4、单片机I2C总线接口的编程方法。
二、实验内容:
1、向24C02写入数据,然后读出数据检验,检验正确,点亮8个发光二极管;检验错误,熄灭8个发光二极管。
原理图:
流程图:
子程序开始子程序开始开始
发送启动条件发送启动条件I/O端口初始化
I2C初始化送出器件地址,设为送出器件地址,设为
“写”模式;“写”模式;I2C写1个字节
送出写入地址;送出写入地址;
送出写入数据;I2C读出1个字节
送出重启条件否
发送停止条件读出=写入?
送出器件地址,设为“读”是延时10ms 接收24C02送出的数据
灯灭灯亮
返回发送非应答条件
发送停止条件踏步
返回
2、编制程序,分别按字节模式和页模式向24C02芯片写入数据,比较写入速度的差别。
原理图:
流程图:
字节子程序主程序
一个字节程序I/O端口初始化
N I2C初始化
是否8次定时初始化
Y
返回启动定时0
页模式程序
页模式子程序关闭定时0
发送启动条件启动定时1
送出器件地址,设置字节子程序
“写”模式;关闭定时1
送出写入地址;N
T0<T1
Y
送出写入数据灯亮灯灭
N
是否8次?
Y 踏步
返回
T0 为定时器0的定时时间;T1为定时器T1的定时时间。
ATMEL 24c02使用详解(汇编及C程序都有)

ATMEL 24c02使用详解原文地址: /Blog/cns!2FEAB5F0F11F7A67!296.entryATMEL 24c02使用详解I2C总线是一种用于IC器件之间连接的二线制总线。
它通过SDA(串行数据线)及SCL (串行时钟线)两根线在连到总线上的器件之间传送信息,并根据地址识别每个器件:不管是单片机、存储器、LCD驱动器还是键盘接口。
1.I2C总线的基本结构采用I2C总线标准的单片机或IC器件,其内部不仅有I2C 接口电路,而且将内部各单元电路按功能划分为若干相对独立的模块,通过软件寻址实现片选,减少了器件片选线的连接。
CPU不仅能通过指令将某个功能单元电路挂*或摘离总线,还可对该单元的工作状况进行检测,从而实现对硬件系统的既简单又灵活的扩展与控制。
I2C总线接口电路结构如图1所示。
2.双向传输的接口特性传统的单片机串行接口的发送和接收一般都各用一条线,如MCS51系列的TXD和RXD,而I2C总线则根据器件的功能通过软件程序使其可工作于发送或接收方式。
当某个器件向总线上发送信息时,它就是发送器(也叫主器件),而当其从总线上接收信息时,又成为接收器(也叫从器件)。
主器件用于启动总线上传送数据并产生时钟以开放传送的器件,此时任何被寻址的器件均被认为是从器件。
I2C总线的控制完全由挂接在总线上的主器件送出的地址和数据决定。
在总线上,既没有中心机,也没有优先机。
总线上主和从(即发送和接收)的关系不是一成不变的,而是取决于此时数据传送的方向。
SDA和SCL均为双向I/O线,通过上拉电阻接正电源。
当总线空闲时,两根线都是高电平。
连接总线的器件的输出级必须是集电极或漏极开路,以具有线“与”功能。
I2C总线的数据传送速率在标准工作方式下为100kbit/s,在快速方式下,最高传送速率可达400kbit/s。
3.I2C总线上的时钟信号在I2C总线上传送信息时的时钟同步信号是由挂接在SCL 时钟线上的所有器件的逻辑“与”完成的。
24c02读写程序大全

CLR SCLK24
CALL START24;启动
MOV A,#0A0H
CALL SHIFT8;移位
CALL ACK;响应
POP ACC
>SETB;应答毕,SDA置1
>RET
>程序中多处调用了DELAY子程序(仅两条NOP指令),这是为了满足I2C总线上数据传
送速率的要求,只有当SDA数据线上的数据稳定下来之后才能进行读写(即SCL线发出正
脉冲)。另外,在读最后一数据字节时,置应答信号为“1”,表示读操作即将完成。
>
>下面是本人编写的源程序,已经调试成功,下载就可以使用,程序编写的不是很规范
>ACALL SUBS
>MORE: ACALL SUBR
>MOV@R1,A
>INCR1
>DJNZ R7,MORE
>CLR
>ACALL DELAY
>SETB
>ACALL DELAY
>SETB;送停止信号
>RET
>SUBR: MOVR0,#08H ;接受单字节子程序
>LOOP2: SETB
>ACALL DELAY
TT2:MOV30H,A
MOVCA,@A+DPTR
CLR;开数码管
MOVP0,A;送显示
MOVA,30H
INCA
MOVB,A
MOVA,#00H
LCALLWT24
AJMP$
TAB:DB28H,7EH,0A2H,62H,74H,61H,21H,7AH,20H,60H
RD24: PUSH ACC;读24C02子程序。
24c02写入字符串程序 及管脚说明

//测试ACK
bit testack()
{
bitack;
sda=1;
scl=1;
ack=sda;
scl=0;
return(ack);
}
//写入8个bit到24c02
void write_bit(uchar input)
{
uchar temp;
for(temp=8;temp!=0;temp--)
{
sda=(bit)(input&0x80);
testack();
write_bit(ch);
testack();
stop_IIC();
delayms(10);
}
void main(void) //主程序
{
uchar i;
for(i=0;str[i]!=0;i++)
{
write24c02(str[i],i);//逐个写入到24c02的中
}
write24c02(0x00,i); //写入最后一个0
include52头文件defineucharunsignedchar定义变量类型方便使用defineuintunsignedintdefinewritedeviceaddress0xae定义器件在iic总线中的地址最后一位看你a2a1a0所接电平definereaddviceaddress0xafucharcodestryouarebest
{
uchari,j;
for(;number!=0;number--)
{
for(temp=110;temp!=temp--) ;
}
}
//开始
void start_IIC()
STM32F103读写24C02 C程序 有硬件电路图和程序

向有子地址器件读取多字节数据函数
函数原型: bit RecndStr(UCHAR sla,UCHAR suba,ucahr *s,UCHAR no);
功能: 从启动总线到发送地址,子地址,读数据,结束总线的全过程,从器件
地址 sla,子地址 suba,读出的内容放入 s 指向的存储区,读 no 个字节。
Delay_us_24C02(1);
//发送结束条件的时钟信号
SCL(1) ; //SCL=1; 结束条件建立时间大于 4μs
Delay_us_24C02(5);
SDA(0); //SDA=1; 发送 I2C 总线结束信号
Delay_us_24C02(4);
}****************************************** 字节数据发送函数
注意:
如果返回 1 表示操作成功,否则操作有误。 使用前必须已结束总线。
********************************************************************/
u8 IRcvStr(unsigned char sla,unsigned char suba,unsigned char *s,unsigned char no)
//实验 24C02 连接在 PF 口 //WP、A0、A1、A2 都接地,如下图所示。 //单片机:STM32F103
#include "stm32f10x_flash.h" #include "stm32f10x_gpio.h" #include "stm32f10x_rcc.h" #define AT24C02 0xa0 //AT24C02 地址 /******************************** 变量定义 ---------------------------------------------------------*/ GPIO_InitTypeDef GPIO_InitStructure; //GPIO ErrorStatus HSEStartUpStatus; unsigned char Count1 , Count2; unsigned int USEC; static vu32 TimingDelay; unsigned char Readzfc; unsigned char pDat[8] = {0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55};//实验数据 unsigned char R_Dat[8]; /*********************************声明函数 -----------------------------------------------*/ void RCC_Configuration(void); void SysTick_Configuration(void); void Delay_us_24C02(u32 nTime); /************************************24C02 硬件接口 ******************************/
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
void write_byte(uchar x)
{
uchar i;
for(i=0;i<8;i++)
{
sda=(bit)(x&0x80);
_nop_();
scl=1;
_nop_();_nop_();
scl=0;
x<<=1;
}
}
出口参数:dat(存储读出的数据)
********************************************/
uchar read_current()
{
uchar dat;
start();
write_byte(OP_READ);
ack();
dat=read_byte();
stop();
sbit sda=P0^0;
sbit scl=P0^1;
sbit rs=P3^2;//寄存器选择位,将RS位定义为P3.0引脚
sbit rw=P3^1;//读写选择位,将RW位定义为P3.1引脚
sbit e=P3^0;//使能信号位,将E位定义为P3.2引脚
void delay(uint i)//延时函数
delay_nms(255);
//init_i2c();
j=read_i2c(2);
dis_tab[2]=j%10+'0';
dis_tab[1]=j%100/10+'0';
dis_tab[0]=j/100+'0';
dis_tab[3]='\0';
lcd12864_display(1,2,"开机次数:") ;
rw=0;
e=0; //E置低电平(根据表8-6,写指令时,E为高脉冲,
//就是让E从0到1发生正跳变,所以应先置"0"
_nop_();
_nop_(); //空操作两个机器周期,给硬件反应时间
D12864_bus=dictate; //将数据送入D12864_bus,即写入指令或地址
_nop_();
lcd12864_display(2,2,"请按复位或是断") ;
lcd12864_display(3,1,"电,如果计数增加") ;
lcd12864_display(4,1,"恭喜你成功!") ;
lcd12864_display(1,7,dis_tab) ;
j++;
write_dat(2,j);
while(1) ;
void lcd12864_display(uchar y,uchar x,uchar *p)
{
switch (y)
{
case 1:lcd12864_write_instruction(0x7f+x);break; //液晶第一行
case 2:lcd12864_write_instruction(0x8f+x);break; //0x8f+x
晶的数据总线(P20--D0...P27--D7),
E连至P30,RW连至P31,RS连至P32,
**********************************************/
#include<reg52.h> //包含单片机寄存器的头文件
#include<intrins.h> //包含_nop_()函数定义的头文件
_nop_();
_nop_();
_nop_(); //空操作四个机器周期,给硬件反应时间
e=1; //E置高电平
_nop_();
_nop_();
_nop_();
_nop_(); //空操作四个机器周期,给硬件反应时间
e=0; //当E由高电平跳变成低电平时,液晶模块开始执行命令
}
/*****************************************************
/********************************************
函数功能:从24C**中的指定地址写入数据
入口参数:add(需写入的存储器地址)
dat(写入存储器的数据)
********************************************/
void write_dat(uchar add,uchar dat)
函数功能:将24c**初始化
********************************************/
void init_i2c()
{
scl=1;
sda=1;
}
void main()
{
uint j;
uchar dis_tab[4];
init_i2c();
lcd12864_initialize();
12864液晶设置为并行方式将24c02sda引脚接至p00scl引脚接至p01将单片机的p2口用杜邦线线连于j151连至p30rw连至p31rs连至p32includereg52h包含单片机寄存器的头文件includeintrinsh包含nop函数定义的头文件defineucharunsignedchardefineuintunsignedintdefined12864busp2定义液晶数据口线defineopwrite0xa0器件地址以及写入操作defineopread0xa1器件地址以及读取操作sbitsdap00
}
函数功能:将数据(字符的标准ASCII码)写入液晶模块
入口参数:y(为字符常量)
***************************************************/
void lcd12864_write_data(unsigned char y)
{
rs=1; //RS为高电平,RW为低电平时,可以写入数据
ack_dat=sda;
scl=0;
return ack_dat;
}
/*************************************
函数功能:向at24c**读出一字节数据
出口参数:dat(读出数据)
*************************************/
uchar read_byte()
入口参数:dictate
***************************************************/
void lcd12864_write_instruction (unsigned char dictate)
{
rs=0; //根据规定,RS和R/W同时为低电平时,可以写入指令
{
while(i--)
;
}
/*****************************************************
函数功能:延时1ms
(3j+2)*i=(3×33+2)×10=1010(微秒),可以认为是1毫秒
***************************************************/
delay_nms(5); //延时5ms
lcd12864_write_instruction(0x38);
delay_nms(5);
lcd12864_write_instruction(0x38);
delay_nms(5);
lcd12864_write_instruction(0x0c); //显示模式设置:显示开,有光标,光标闪烁
***************************************************/
void lcd12864_initialize(void)
{
delay_nms(15); //延时15ms,首次写指令时应给LCD一段较长的反应时间
lcd12864_write_instruction(0x38); //显示模式设置:16×2显示,5×7点阵,8位数据接口
{
start();
write_byte(OP_WRITE);
ack();
write_byte(add);
ack();
write_byte(dat);
ack();
stop();
delay_nms(4);
}
/********************************************
函数功能:从24C**中的当前地址读取数据
return dat;
}
/********************************************
函数功能:从24C**中的指定地址读取数据
入口参数:add(需读出的存储器地址)
出口参数:dat(存储读出的数据)
********************************************/
case 3:lcd12864_write_instruction(0x87+x);break;
case 4:lcd12864_write_instruction(0x97+x);
}
while(*p)
lcd12864_write_data(*p++);
}
void start()
{
sda=1;
scl=1;
rw=0;
e=0; //E置低电平(根据表8-6,写指令时,E为高脉冲,