24C02的C控制程序
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为例的。
二十。掉电保护24c02

#include <reg52.H>#include <stdio.h>#include <absacc.h>unsigned char code table[]={ 0xc0,0xf9,0xa4,0xb0,0x99,0x92, 0x82,0xf8,0x80,0x90,0x40};unsigned char sec; //定义计数值,每过1 秒,sec加1 unsigned int tcnt; //定时中断次数bit write=0; //写24C08 的标志;sbit gewei=P2^5; //个位选通定义sbit shiwei=P2^4; //十位选通定义/////////24C08 读写驱动程序////////////////////sbit scl=P3^4; // 24c08 SCLsbit sda=P3^5; // 24c08 SDAvoid delay1(unsigned char x){ unsigned int i;for(i=0;i<x;i++);;}void flash(){ ; ; }void x24c08_init() //24c08 初始化子程序{scl=1; flash(); sda=1; flash();}void start() //启动(I方C)总线{sda=1; flash(); scl=1; flash(); sda=0; flash(); scl=0; flash();} void stop() //停止(I方C)总线{sda=0; flash(); scl=1; flash(); sda=1; flash();}void writex(unsigned char j) //写一个字节{ unsigned char i,temp;temp=j;for (i=0;i<8;i++){temp=temp<<1; scl=0; flash(); sda=CY; flash(); scl=1; flash();} scl=0; flash(); sda=1; flash();}unsigned char readx() //读一个字节{unsigned char i,j,k=0;scl=0; flash(); sda=1;for (i=0;i<8;i++){flash(); scl=1; flash();if (sda==1) j=1;else j=0;k=(k<<1)|j;scl=0;}flash(); return(k);}void clock() //(I方C)线时钟{unsigned char i=0;scl=1; flash();while ((sda==1)&&(i<255))i++;scl=0; flash();}////////从24c02 的地址address 中读取一个字节数据/////unsigned char x24c08_read(unsigned char address){unsigned char i;start(); writex(0xa0);clock(); writex(address);clock(); start();writex(0xa1); clock();i=readx(); stop();delay1(10);return(i);}//////向24c02 的address 地址中写入一字节数据info///// void x24c08_write(unsigned char address,unsigned char info){EA=0;start(); writex(0xa0);clock(); writex(address);clock(); writex(info);clock(); stop();EA=1;delay1(50);}/////////////24C08 读写驱动程序完/////////////////////void Delay(unsigned int tc) //延时程序{while( tc != 0 ){unsigned int i;for(i=0; i<100; i++);tc--;}}void LED() //LED显示函数{shiwei=0; P0=table[sec/10]; Delay(8); shiwei=1;gewei=0; P0=table[sec%10]; Delay(5); gewei=1;}void t0(void) interrupt 1 using 0 //定时中断服务函数{TH0=(65536-50000)/256; //对TH0 TL0 赋值TL0=(65536-50000)%256; //重装计数初值tcnt++; //每过250ust tcnt 加一if(tcnt==20) //计满20次(1 秒)时{tcnt=0; //重新再计sec++;write=1; //1 秒写一次24C08if(sec==100) //定时100 秒,在从零开始计时{sec=0;}}}void main(void){TMOD=0x01; //定时器工作在方式1ET0=1; EA=1;x24c08_init(); //初始化24C08sec=x24c08_read(2);//读出保存的数据赋于secTH0=(65536-50000)/256; //对TH0 TL0 赋值TL0=(65536-50000)%256; //使定时器0.05 秒中断一次TR0=1; //开始计时while(1){LED();if(write==1) //判断计时器是否计时一秒{write=0; //清零x24c08_write(2,sec); //在24c08 的地址2 中写入数据sec}}}。
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处理程序结束}//主循环结束}//主程序结束。
24c02典型程序

iic_write(adwrite); //24c02写地址
iic_ack();
iic_write(address); //24c02起始存储地址写入可自动+1
iic_ack();
for(i=0;i<num;i++) //循环写入num个字节
{
iic_write(date[i]);
iic_ //读数据
iic_noack();
iic_stop(); //最后非应答
return q; //读回该地址存储的数
}
/*******************************************
函数名称:main()
功能:初始化及循环调用子函数显示
函数名称:rom_write()
功能:循环写进num个字节
参数:如下
返回值:无
********************************************/
void rom_write(uchar date[],uchar address,uchar num)
{
uchar i; //循环次数
unsigned char rom_read (uchar address)
{uchar q;
iic_start();
iic_write(0xae);//写入芯片地址
iic_ack();
iic_write(address); //写入存储地址
iic_ack();
iic_start();
iic_write(0xaf); //读回地址
参数:无
返回值:无
********************************************/
基于51的扩展存储器24C02的程序源代码

#include<reg51.h>#include<intrins.h>sbitsda=P2^0; //SDA线sbitscl=P2^1; //SCL线sbitrst=P2^4; //关掉时钟芯片输出sbit hc573_sg_le=P2^6; //对用于锁存段数据的573锁存LE端进行定义sbit hc573_bit_le=P2^7; //对用于锁存位选通数据的573锁存LE端进行定义unsigned char dis_num;unsigned char sec_1,sec_2; //数码管显示的数值,分别代表个位和十位unsigned char sec_5,sec_6; //数码管显示的数值,分别代表个位和十位unsigned char code display_table[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; //0-f 16个数码管显示编码unsigned char code display_en[7]={0xff,0xfe,0xfd,0xfb,0xf7,0xef,0xdf}; //数码管位选通数据数组void delay_ms(unsigned int t) //tms的延时函数{unsignedinta,b;for(a=0;a<t;a++){for(b=0;b<113;b++){;}}}void _nop5_() //5个机器周期的延时,大约延时5us{_nop_();_nop_();_nop_();_nop_();_nop_();}void start(){scl=0; //SCL线拉低,以便让SDA线准备变化sda=1; //SDA线拉高,准备产生开始信号scl=1; //SCL线拉高_nop5_(); //SDA线高电平持续5us,以符合开始信号定义的要求(>4.7us)sda=0; //SDA线拉低,产生开始信号_nop5_(); //SDA线低电平持续5us, 以符合开始信号定义的要求(>4us)}void stop(){scl=0; //SCL线拉低,以便让SDA线准备变化sda=0; //SDA线拉低,准备产生停止信号scl=1; //SCL线拉高_nop5_(); //SDA线低电平持续5us,以符合停止信号定义的要求(>4us)sda=1; //SDA线拉高,产生停止信号_nop5_(); //SDA线的高电平持续5us, 以符合停止信号定义的要求(>4.7us)}void ack() //检测从机应答信号的函数{unsigned char i;i=255;scl=0; //SCL线拉低,以便让SDA线准备变化sda=1; //SDA线拉高,准备检测从机的应答信号while(sda==1) //当SDA为高电平时,则等待从机的应答将SDA拉低{if(i>0)i--;else return; //如果i自减到0了,从机还没响应,则不再等待,返回} //这种情况极少发生,一般是从机器件出问题了才会发生scl=1; //从机已经应答,将SDA线拉低了_nop5_(); //SDA线的低电平持续5us,以符合应答信号定义的要求(>4us)scl=0; //SCL线拉低,以便让从机把SDA线释放}/*void send_ack() //主机给从机发送应答信号{scl=0; //SCL线拉低,以便让SDA线准备变化sda=0; //SDA线拉低,即将发送应答信号给从机scl=1; //SCL线拉高,将应答信号发送过去_nop5_(); //SDA线的低电平持续5us,以符合应答信号定义的要求(>4us) scl=0; //SCL线拉低,以便让SDA线准备变化sda=1; //释放SDA线}*/ //本例程未用到此函数void send_no_ack() //主机给从机发送非应答信号{scl=0; //SCL线拉低,以便让SDA线准备变化sda=1; //SDA线拉高,即将发送非应答信号给从机scl=1; //SCL线拉高,将应答信号发送过去_nop5_(); //SDA线的高电平持续5us,以符合非应答信号定义的要求(>4us)}void write(unsigned char dat) //主机向从机写操作函数{unsigned char i;for(i=0;i<8;i++){scl=0; //SCL线拉低,以便让SDA线准备变化sda=(bit)(0x80&dat); //取字节数据的最高位,发送到SDA线dat=dat<<1; //发送的数据都是由高位到低位顺序发送的,所以要将所//需发送的那位移到数据的最高位,以发送到SDA线上scl=1; //SCL线拉高,数据被发送过去}}unsigned char read() //主机向从机读操作的函数{unsigned char i;unsigned char dat; //定义一个字节变量,用来存储读出的从机数据dat=0;for(i=0;i<8;i++){dat=dat<<1; //将位数据不断地往高位移动,将接收到的位数据转换为字节数据scl=0; //SCL线拉低,以便让SDA线准备变化dat=dat|(unsigned char)sda; //将接收到的位数据强制转换成字节数据,并存到dat 中scl=1; //SCL线拉高,接收下一位数据}return dat; //数据接收完毕,带数据返回}void display(unsigned char num,unsigned char i){P0=display_table[num]; //将数值的编码送入锁存器的输入端准备段数据的锁存hc573_sg_le=1; // 将段数据送给段数据线hc573_sg_le=0; //锁存段数据,让出P0口以供位选通锁存器使用P0=display_en[i]; //准备点亮第i个数码管hc573_bit_le=1; //将位选通数据送到数码管,数码管亮hc573_bit_le=0; //锁存位选通数据,让出P0口以供段数据锁存器使用}void main(){unsigned char data1; //用于存储从24C02中读出的数据rst=0; //关闭DS1302时钟芯片,避免引起干扰start(); //开始write(0xa0); //发送寻址字节给从机,通知从机要写数据ack(); //检测从机的应答信号write(0x06); //发送要写入的地址,为24C02的0x06位置ack(); //检测从机的应答信号write(0x0d); //向24C02发送数据0x0cack(); //检测从机的应答信号stop(); //写入完毕,停止通信delay_ms(100); //延时100ms,让24C02有足够的时间写入刚接收到的数据start(); //开始write(0xa0); //发送寻址字节给从机,通知从机要写数据ack(); //检测从机的应答信号write(0x06); //发送要读的地址,为24C02的0x06位置ack(); //检测从机的应答信号start(); //重复一次开始信号write(0xa1); //发送寻址字节给从机,通知从机要读刚才地址中的数据ack(); //检测从机的应答信号data1=read(); //读出数据,并把数据存到data1中send_no_ack(); //读数据完毕,发送非应答信号stop(); //发送停止信号,停止通信while(1){display(data1,1); //将数据显示到数码管中while(1);}}。
最好的24C02储存开机次数实验读写程序

24C02储存开机次数实验24C02是2K字节的串行EEPROM, 内部含有256个8位字节,该器件通过总线操作,并有专门的写保护功能。
串行EEPROM简称I2C总线式串行器件。
串行器件不仅占用很少的资源和I/O线,而且体积大大缩小,同时具有工作电源宽、抗干扰能力强、功耗低、数据不易丢失和支持在线编程等特点。
I2C总线是一种用于IC器件之间连接的二线制总线。
它通过SDA(串行数据线)及SCL(串行时钟线)两根线在连到总线上的器件之间传送信息,并根据地址识别每个器件:不管是单片机、存储器、LCD驱动器还是键盘接口。
我们通过一个实验来了解24C02的读写操作过程:该实验功能是单片机复位一次,自动从24C02中读取数据,然后加1,最终数码管中的数据就是开机的次数,具有一定的实用意义。
相关原理:程序运行的照片:接线方法:1、接8位数码管的数据线。
将数码管部份的数据口 JP5接到CPU部份的P0口JP51.2、接8位数码管的显示位线。
将数码管部份的显示位口 JP8接到CPU部份的P2口JP52.3、用一根2PIN数据线一端插入CPU部份JP53(P3口)的P3.6,P3.7另外一端插入24C02部份的控制端JP38。
烧写后用手按复位键可以看到数码管每按一下加一。
程序流程图:汇编语言参考程序: SDA24 EQU P3.7 SCLK24 EQU P3.6 ORG 0000HAJMP MAINORG 0080HMAIN:CLR P3.7 ;打开写保护MOV DPTR,#TABMOV A,#00H ;读地址LCALL RD24CJNE A,#10,TTTT: JNC TT1AJMP TT2TT1: MOV A,#00TT2: MOV 30H,AMOVC A,@A+DPTRCLR P2.6 ;开数码管MOV P0,A ;送显示MOV A,30HINC AMOV B,AMOV A,#00HLCALL WT24AJMP $TAB: DB 28H,7EH,0A2H,62H,74H,61H,21H,7AH,20H,60HRD24: PUSH ACC ;读24C02子程序。
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编写程序步骤
1、位传输I2C总线每传送一位数据必须有一个时钟脉冲。
被传送的数据在时钟SCL的高电平期间保持稳定,只有在SCL低电平期间才能够改变,示意图如下图所示,在标准模式下,高低电平宽度必须不小于4.7us。
开始信号:当SCL为高电平时,SDA发生从高到低的跳变,就定义为开始信号。
停止信号:当SCL为高电平时,SDA发生从低到高的跳变,就定义为结束信号。
2、数据传输的字节格式SDA传送数据是以字节为单位进行的。
每个字节必须是8位,但是传输的字节数量不受限制,首先传送的是数据的最高位。
每次传送一个字节完毕,必须接收到从机发出的一个应答位,才能开始下一个字节的传输。
如果没有接受到应答位,主机则产生一个停止条件结束本次的传送。
那么从机应该发出什么信号算是产生了应答呢?这个过程是这样的。
当主器件传送一个字节后,在第9个SCL时钟内置高SDA线,而从器件的响应信号将SDA拉低,从而给出一个应答位3、I2C数据传输协议I2C总线的数据传输协议如下:(1)、主器件发出开始信号(2)、主器件发出第一个字节,用来选通相应的从器件。
其中前7位为地址码,第8位为方向位(R/W)。
方向位为“0”表示发送,方向位为“1”表示接受。
(3)、从机产生应答信号,进入下一个传送周期,如果从器件没有给出应答信号,此时主器件产生一个结束信号使得传送结束,传送数据无效。
(4)、接下来主、从器件正式进行数据的传送,这时在I2C总线上每次传送的数据字节数不限,但每一个字节必须为8位(传送的时候先送高位,再送低位)。
当一个字节传送完毕时,再发送一个应答位(第9位),如上一条所述,这样每次传送一个字节都需要9个时钟脉冲。
数据的传送过程如下图所示:从左面的电路连接知:A2A1A0=000,可见如果要对24C02进行写操作,寻址字节是1010 000 0;如果对24C02进行读操作,寻址字节是1010 000 1。
用单片机的P1.6脚作为串行时钟线,用P1.7脚作串行数据线。
24C02程序
//重新发送
val = IIc_write_byte(Address_24C02);//写器件地址
}
IIc_write_byte(add);//写存储的地址
for(i=0;number>0;number--)
{
IIc_write_byte(*p++);//写存储的数据
}
IIc_stop();
return(1);
/*在 24c02 的 add 地址中写入一个数据
date;返回 1 设备正常*/
/******************************************************************************
************
用页写 CAT24WC01 可一次写入 8 个字节数据,CAT24WC02/04/08/16 可以一次写入 16 个字
IIc_Sad = 1; IIc_Scl = 1; _NOP_(); IIc_Sad = 0; _NOP_(); IIc_Scl = 0; }
/*停止 I2C 总线*/ void IIc_stop() {
IIc_Sad = 0; _NOP_(); IIc_Scl = 1;
_NOP_(); IIc_Sad = 1; //总线置于空闲状态 }
vaule++;
IIc_Scl = 0;
_NOP_();
}
IIc_Sad = !Master_ack;//主机应答信号
_NOP_();
IIc_Scl = 1;
_NOP_();
IIc_Scl = 0;
_NOP_();
return vaule;
}
I2C总线芯片AT24C02程序设计
I2C总线芯片AT24C02程序设计AT24C02是一种常见的I2C总线芯片,具有2K字节的存储空间。
在程序设计方面,主要需要考虑以下几个方面:初始化、读取数据、写入数据。
首先,需要考虑的是初始化芯片。
在初始化过程中,主要有两个关键的步骤,一个是设置I2C总线的速率,另一个则是设置芯片地址。
以下是AT24C02初始化的伪代码:```void init_AT24C0//设置I2C总线速率i2c_set_speed(I2C_SPEED);//设置AT24C02芯片地址i2c_write_byte(AT24C02_ADDR);if (!i2c_check_ack()//错误处理机制}```在初始化完成后,就可以进行数据的读取和写入。
以下是读取数据的伪代码:```uint8_t read_AT24C02(uint16_t addr)//发送开始信号i2c_start(;//发送芯片地址和写入模式i2c_write_byte(AT24C02_ADDR , I2C_WRITE); if (!i2c_check_ack()//错误处理机制}//发送要读取的地址高位和低位i2c_write_byte(addr >> 8);if (!i2c_check_ack()//错误处理机制}i2c_write_byte(addr & 0xFF);if (!i2c_check_ack()//错误处理机制}//发送重新开始信号i2c_restart(;//发送芯片地址和读取模式i2c_write_byte(AT24C02_ADDR , I2C_READ);if (!i2c_check_ack()//错误处理机制}//读取数据uint8_t data = i2c_read_byte(;//发送停止信号i2c_stop(;//返回读取到的数据return data;```以上是读取数据的伪代码,对应地,写入数据的伪代码如下:```void write_AT24C02(uint16_t addr, uint8_t data)//发送开始信号i2c_start(;//发送芯片地址和写入模式i2c_write_byte(AT24C02_ADDR , I2C_WRITE);if (!i2c_check_ack()//错误处理机制}//发送要写入的地址高位和低位i2c_write_byte(addr >> 8);if (!i2c_check_ack()//错误处理机制}i2c_write_byte(addr & 0xFF); if (!i2c_check_ack()//错误处理机制}//写入数据i2c_write_byte(data);if (!i2c_check_ack()//错误处理机制}//发送停止信号i2c_stop(;```需要注意的是,在读取或写入数据之前,必须实现I2C总线的相关函数,如设置速率、发送信号、写入数据等。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
24C02的C控制程序
24C02的C控制程序
#define uchar unsigned char
#define uint unsigned int
#include
#include
#include
sbit scl=P3^5; //24c02 SCL
sbit sda=P3^4; //24c02 SDA
sbit DOG=P1^7; //狗
uchar x24c02_read(uchar address); //从24c02的地址address中读取一个字节数据
void x24c02_write(uchar address,uchar info); //向24c02的address地址中写入一字节数据info
void x24c02_init(); //24c02初始化子程序
void delay1(uchar x);
void flash();
void x24c01_init();
void start();
void stop();
void writex(uchar j);
uchar readx();
void clock();
void delay1(uchar x)
{
uint i;
for(i=0;i
}
void flash()
{
uchar u;
DOG=~DOG;
}
void x24c02_init()
{
scl=1; flash(); sda=1; flash();
}
void start()
{
sda=1; flash(); scl=1; flash(); sda=0; flash(); scl=0; flash();
}
void stop()
{
sda=0; flash(); scl=1; flash(); sda=1; flash();
}
void writex(uchar j)
{
uchar i,temp;
temp=j;
for (i=0;i<8;i++){
temp=temp<<1; scl=0; flash(); sda=CY; flash(); scl=1; flash();
}
scl=0; flash(); sda=1; flash();
}
uchar readx()
{
uchar i,j,k=0;
scl=0; flash(); sda=1;
for (i=0;i<8;i++){
flash(); scl=1; flash();
if (sda==1) j=1;
else j=0;
k=(k<<1)|j; scl=0;
}
flash(); return(k);
}
void clock()
{
uchar i=0;
scl=1; flash();
while ((sda==1)&&(i<255))i++;
scl=0; flash();
}
uchar x24c02_read(uchar address)
{
uchar i;
start(); writex(0xa0);
clock(); writex(address);
clock(); start();
writex(0xa1); clock();
i=readx(); stop();
delay1(10);
return(i);
}
void x24c02_write(uchar address,uchar info)
{
EA=0;
start(); writex(0xa0);
clock(); writex(address);
clock(); writex(info);
clock(); stop();
EA=1;
delay1(50);
}