最好的24C02储存开机次数实验 读写程序
STM32F103读写24C02程序,使用过肯定能用

//实验24C02连接在PF口//WP、A0、A1、A2都接地#include "stm32f10x_flash.h"#include "stm32f10x_gpio.h"#include "stm32f10x_rcc.h"#define AT24C02 0xa0 //AT24C02 地址/******************************** 变量定义---------------------------------------------------------*/GPIO_InitTypeDef GPIO_InitStructure; //GPIOErrorStatus 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硬件接口******************************/#define SData GPIO_Pin_6 //I2C 时钟#define SCLK GPIO_Pin_7 //I2C 数据/********************************宏定义*******************************************/#define SCL(x) x ? GPIO_SetBits(GPIOF , SCLK) : GPIO_ResetBits(GPIOF , SCLK) #define SDA(x) x ? GPIO_SetBits(GPIOF , SData) : GPIO_ResetBits(GPIOF , SData)/********************************变量*******************************************/u8 ack;/*******************************************************************起动总线函数函数原型: void Start_I2c();功能: 启动I2C总线,即发送I2C起始条件.********************************************************************/ void Start_I2c(){SDA(1); //SDA=1; 发送起始条件的数据信号Delay_us_24C02(1);SCL(1); //SCL=1;Delay_us_24C02(5); //起始条件建立时间大于4.7us,延时SDA(0); //SDA=0; /*发送起始信号*/Delay_us_24C02(5); // 起始条件锁定时间大于4μsSCL(0); //SCL=0; /*钳住I2C总线,准备发送或接收数据 */Delay_us_24C02(2);}/*******************************************************************结束总线函数函数原型: void Stop_I2c();功能: 结束I2C总线,即发送I2C结束条件.********************************************************************/ void Stop_I2c(){SDA(0); //SDA=0; //发送结束条件的数据信号Delay_us_24C02(1); //发送结束条件的时钟信号SCL(1) ; //SCL=1; 结束条件建立时间大于4μsDelay_us_24C02(5);SDA(0); //SDA=1; 发送I2C总线结束信号Delay_us_24C02(4);}/*******************************************************************字节数据发送函数函数原型: void SendByte(UCHAR c);功能: 将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对此状态位进行操作.(不应答或非应答都使ack=0)发送数据正常,ack=1; ack=0表示被控器无应答或损坏。
AT24C02实验程序

//试验AT24C02EEPROM芯片程序#include<reg51.h>#include <intrins.h>#define uint unsigned int#define uchar unsigned charunsigned char sec; //定义计数值,每过1秒,sec加1unsigned int tcnt; //定时中断次数bit write=0; //写24C08的标志;sbit sda=P2^0; //IO口定义sbit scl=P2^1;sbit dula=P2^6;sbit wela=P2^7;unsigned char j,k;void delay(unsigned char i) //延时程序{for(j=i;j>0;j--)for(k=125;k>0;k--);}uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d, //数码管编码0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};void display(uchar bai_c,uchar sh_c) //显示程序{dula=0;P0=table[bai_c]; //显示百位dula=1;dula=0;wela=0;P0=0x7e;wela=1;wela=0;delay(5);dula=0;P0=table[sh_c]; //显示十位dula=1;dula=0;wela=0;P0=0x7d;wela=1;wela=0;delay(5);}/////////24C08读写驱动程序////////////////////void 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() //启动I2C总线{sda=1; flash(); scl=1; flash(); sda=0; flash(); scl=0; flash();}void stop() //停止I2C总线{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() //I2C总线时钟{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);}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(){unsigned char i;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){i=10;while(i--){display(sec/10,sec%10);}if(write==1) //判断计时器是否计时一秒{write=0; //清零x24c08_write(2,sec); //在24c08的地址2中写入数据sec }}}。
外部存储器24c02的读写操作..

/*------51单片机-----------------------名称:外部存储器24c02..芯片:STC89C51..邮箱:MG_TCCX@QQ:2424488418编写:C.ROOKIE日期:2012.9.13 (21:31)内容:定义一个数组,把数组的数据写入24c02存储,然后清楚数组,把24c02的数据读取到数组里,然后显示在数码管上..--------------------------------------*/#include<reg52.h>#include<intrins.h> //这个文件里有空操作指令..#define _Nop() _nop_() //定义空操作指令..unsigned char code dofly_DuanMa[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};// 显示段码值0~Funsigned char code dofly_WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码sbit SCL=P2^0; //模拟IIC总线时钟控制位。
sbit SDA=P2^1; //模拟IIC总线数据传送位。
sbit LATCH1=P2^2; //数码管段选。
sbit LATCH2=P2^3; //数码管位选。
bit ack; //模拟应答标志位。
//声明延时程序。
void DelayUs(unsigned char);void DelayMs(unsigned char);//定义延时程序。
void DelayUs(unsigned char t){while(--t){}}void DelayMs(unsigned char t){while(--t){DelayUs(245);DelayUs(245);}}//启动IIC总线..void Start_IIC(){SDA=1; //SCL=1的情况下,SDA从高电平到低电平就能启动IIC总线.. _Nop();SCL=1; //起始条件建立的时间大概4.7us .._Nop();_Nop();_Nop();_Nop();_Nop();SDA=0; //已经启动IIC总线.._Nop(); //起始条件锁定时间大概4.7us .._Nop();_Nop();_Nop();_Nop();SCL=0; //钳住IIC总线。
STM32-24C02读写程序(亲自编写测试可用)

本文档内容为在STM32条件下的24C02读写程序。
全文共分四部分,第一部分24C02的C程序,第二部分为24C02的.h程序,第三部分为端口与时钟配置函数,第四部分为主函数。
下面分别进行介绍。
第一部分:24C02的.c函数******************************************************************************/ #include "stm32f10x.h"#include "system_config.h"#include "24C02.h"u8 savedata[10]={10,9,8,7,6,5,4,3,2,1};/****************************************************************************** ** Function Name : AT24C02_SDA_IO_SET(uchar io_set)* Description : SDA方向控制* Input : None* Output : None* Return : None******************************************************************************* /void AT24C02_SDA_IO_SET(unsigned char io_set){GPIO_InitTypeDef GPIO_InitStructure;if(io_set){GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 ;//SDA 设置为输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_Init(GPIOB, &GPIO_InitStructure);}else{GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 ;//SDA 设置为输入GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(GPIOB, &GPIO_InitStructure);}}/****************************************************************************** ** Function Name : delay2* Description : 延时函数* Input : None* Output : None* Return : None******************************************************************************* /void delay2(u8 x){u8 i;for(i=0;i<x;i++);}/****************************************************************************** ** Function Name : delay2* Description : 延时函数* Input : None* Output : None* Return : None******************************************************************************* /void delay_nop(void){uint8_t i=10;//延时1.5uswhile(i--);}/****************************************************************************** ** Function Name : 24C02_init()* Description : 初始化函数* Input : None* Output : None* Return : None******************************************************************************* /void I2C_init(void){//SCL=1SCL_H;delay_nop();//SDA=1SDA_H;delay_nop();}/****************************************************************************** ** Function Name : I2C_start()* Description : 开始信号* Input : None* Output : None* Return : None******************************************************************************* /void I2C_start(){SDA_H;delay_nop();SCL_H;delay_nop();SDA_L;delay_nop();SCL_L;delay_nop();}/****************************************************************************** ** Function Name : I2C_stop()* Description : 开始信号* Input : None* Output : None* Return : None******************************************************************************* /void I2C_stop(){SDA_L;delay_nop();SCL_H;delay_nop();SDA_H;delay_nop();}/****************************************************************************** ** Function Name : I2C_write_bit()* Description : 开始信号* Input : None* Output : None* Return : None******************************************************************************* /void I2C_write_bit(int j){int i,temp,temp1;temp=j;//AT24C02_SDA_IO_SET(1);//发送数据for(i=0;i<8;i++){temp1=temp&0x80;//高位在前相与temp=temp<<1;SCL_L;//时钟线设为低delay_nop();if(temp1==0x80)//发送数据到SDA线上{SDA_H;delay_nop();}else{SDA_L;delay_nop();}SCL_H;//时钟线设为高,开始传输数据delay_nop();}SCL_L;//一个字节发送完成delay_nop();SDA_H;delay_nop();}/****************************************************************************** ** Function Name : I2C_read_bit()* Description : 读取一个字节数据* Input : None* Output : None* Return : None******************************************************************************* /u8 I2C_read_bit(){u8 i,j,k=0;SCL_L;delay_nop();SDA_H;delay_nop();A T24C02_SDA_IO_SET(0);//SDA设置为输入for(i=0;i<8;i++){delay_nop();SCL_H;delay_nop();if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7)==1)j=1;elsej=0;k=(k<<1)|j;SCL_L;delay_nop();}A T24C02_SDA_IO_SET(1);//SDA设置为输出delay_nop();return(k);}/****************************************************************************** ** Function Name : I2C_reply()* Description : 读取应答信号* Input : None* Output : None* Return : None******************************************************************************* /void I2C_reply(){u16 i=0;A T24C02_SDA_IO_SET(0);//SDA设置为输入SCL_H;delay_nop();while((GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7)==1)&&(i<5000))i++;SCL_L;delay_nop();A T24C02_SDA_IO_SET(1);//SDA设置为输出}/****************************************************************************** ** Function Name : I2C_write_addr()* Description : 指定地址写* Input : None* Output : None* Return : None******************************************************************************* /void I2C_write_addr(u8 addr,u8 data){I2C_start();//开始信号I2C_write_bit(0xa0);//发送写命令I2C_reply();//等待应答I2C_write_bit(addr);//发送写地址I2C_reply();//等待应答I2C_write_bit(data);//发送写数据I2C_reply();//等待应答I2C_stop();//停止信号delay2(250);}/****************************************************************************** ** Function Name : I2C_read_addr()* Description : 指定地址读* Input : None* Output : None* Return : None******************************************************************************* /int I2C_read_addr(int addr){int i=0;I2C_start();//开始信号I2C_write_bit(0xa0);//发送写命令因为要先写入要读的地址I2C_reply();//等待应答I2C_write_bit(addr);//发送读地址I2C_reply();//等待应答I2C_start();//开始信号I2C_write_bit(0xa1);//发送读命令I2C_reply();//等待应答i=I2C_read_bit();I2C_stop();//停止信号delay2(250);return(i);}第二部分:24C02的.h函数#define SCL_H GPIO_SetBits(GPIOB,GPIO_Pin_6)#define SCL_L GPIO_ResetBits(GPIOB,GPIO_Pin_6)#define SDA_H GPIO_SetBits(GPIOB,GPIO_Pin_7)#define SDA_L GPIO_ResetBits(GPIOB,GPIO_Pin_7)#define Write_able GPIO_ResetBits(GPIOB,GPIO_Pin_5)//24C02写使能控制引脚void AT24C02_SDA_IO_SET(unsigned char io_set);void delay2(u8 x) ;void delay_nop(void);void I2C_init(void);void I2C_start();void I2C_stop();void I2C_write_bit(int j);u8 I2C_read_bit();void I2C_reply();void I2C_write_addr(u8 addr,u8 data) ;int I2C_read_addr(int addr) ;第三部分:端口与时钟配置函数由于我们使用的是PB6作为时钟线,PB7作为数据线,所以端口配置PB6,PB7就可以了。
基于AT24C02开机次数程序

AT2402程序记录开关机次数的程序(C)作者:高鹏#i nclude <reg51.h>#i nclude<absacc.h>#i nclude<intrins.h>// extern void DelayMs(unsigned int);//extern void Read24c02(unsigned char *RamAddress,// unsigned char RomAddress,unsigned char bytes);// extern void Write24c02(unsigned char *RamAddress,// unsigned char RomAddress,unsigned char bytes);/****************************************************************/#define WriteDeviceAddress 0xa0 //写格式#define ReadDviceAddress 0xa1 //读格式#define uchar unsigned char#define uint unsigned int#define PA8255 XBYTE[0x3ffc]#define PB8255 XBYTE[0x3ffd]#define PC8255 XBYTE[0x3ffe]#define COM8255 XBYTE[0x3fff]/***************************************************************/void DelayMs(uchar number);void Start();void Stop();void Ack(); //应答格式void NoAck(); //非应答格式bit TestAck(); //检查应答的ACKvoid Write8Bit(uchar input);//写一个字节void Write24c02(uchar *Wdata,uchar RomAddress, //写入I2C程序uchar number);uchar Read8Bit(); //读一个字节void Read24c02(uchar *RamAddress,uchar RomAddress, //读出I2C程序uchar bytes) ;void Delay(uchar i) ;sbit SCL=P1^4;sbit SDA=P1^5;sbit DOG=P3^7;sbit cs138=P1^6;sbit led0=P1^0;sbit led1=P1^1;sbit led2=P1^2;sbit led3=P1^3;/***************************************************************/uchar T[1]; //I2C数据存储区uchar code tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f, 0x77,0x7c,0x39,0x5e,0x79,0x71};//0~fvoid main(){uchar tmp;cs138=0;P1=0;COM8255=0X88;Read24c02(T,0x00,1);//读程序从0X00单元开始,读出一个字节while(1){{tmp=T[0];if(tmp>9){T[0]=0;tmp=0;}else{T[0]++;}Write24c02(T,0x00,1);//写程序从0X00单元开始,写入一个字节}while(1){PB8255=tab[tmp];led3=1;Delay(2);led3=0;}}}void DelayMs(uchar number){uchar temp;for(;number!=0;number--,DOG=!DOG){for(temp=112;temp!=0;temp--) {}}}/*******************启动I2C*/void Start(){SDA=1;SCL=1;SDA=0;SCL=0;}/*********************///停止I2Cvoid Stop(){SCL=0;SDA=0;SCL=1;SDA=1;}/**********************/void Ack() //应答格式{SDA=0;SCL=1;SCL=0;SDA=1;}/***********************/void NoAck() //应答格式{SDA=1;SCL=1;SCL=0;}/*************************************/bit TestAck() //检查应答的ACK{bit ErrorBit;SDA=1;SCL=1;ErrorBit=SDA;SCL=0;return(ErrorBit);}/*************************************/void Write8Bit(uchar input) //写一个字节{uchar temp;for(temp=8;temp!=0;temp--){if(input&0x80)SDA=1;else SDA=0;SCL=1;SCL=0;input=input<<1;}}/****************************************/void Write24c02(uchar *Wdata,uchar RomAddress, //写入I2C程序uchar number){Start(); //开始条件Write8Bit(WriteDeviceAddress); //写8位设备地址TestAck();Write8Bit(RomAddress);TestAck();for(;number!=0;number--){Write8Bit(*Wdata);TestAck();Wdata++;}Stop();DelayMs(10);}/***************************************************/uchar Read8Bit() //读一个字节{uchar temp,rbyte=0;for(temp=8;temp!=0;temp--){SCL=1;rbyte=rbyte<<1;if(SDA)rbyte|=0x01;else rbyte|=0x00;SCL=0;}return(rbyte);}void Read24c02(uchar *RamAddress,uchar RomAddress, //读出I2C程序uchar bytes){Start();Write8Bit(WriteDeviceAddress);TestAck();Write8Bit(RomAddress);TestAck();Start();Write8Bit(ReadDviceAddress);TestAck();while(bytes!=0){*RamAddress=Read8Bit();Ack(); //应答RamAddress++;bytes--;}*RamAddress=Read8Bit();NoAck(); //非应答Stop(); //结束条件}//延时程序void Delay(uchar i) //延时程序,i是形式参数{uchar j;while(i--) //变量i由实际参数传入一个值,因此i不能赋初值for(j=0;j<125;j++);}。
IIC总线有关24C02 实验程序

IIC总线有关24C02 实验程序;-----------------------------------------------------------------------;*程序名称:E2PROM.ASM? *;*功能说明:此程序为I2C总线E2PROM的读写实验程序,程序中将AT24C02 *;* 采用集几种模式写入,然后采用几种模式读出,将读出的数据 *;* 和写入的数据进行比较,如果有一个数据不相等则p1.0的LED *;* 指示灯点亮。
*;*创建时间:2003-06-23 *;*修改时间: *;---------------------------------------------------------------------------------------------------------SDA EQU P1.7 ;定义P1.7为I2C总线的数据线SCL EQU P1.6 ;定义P1.6为I2C总线的时钟线SLAW EQU 50H ;定义I2C器件的写地址存放空间SLAR EQU 51H ;定义I2C器件的读地址存放空间ADDRESS EQU 52H ;定义I2C器件的内部地址存放空间WR_DATA EQU 53H ;定义写数据的存放地址NB EQU 54H ;定义读写数据的数目的存放空间ORG 0000HLJMP MAINORG 0100HMAIN:MOV SP,#70H ;设定堆栈指针MOV SLAW,#0A0H ;初始化定义变量MOV SLAR,#0A1HMOV ADDRESS,#00HMOV WR_DATA,#00HMOV NB,#08HMOV R0,#30H ;写入缓冲区30H—38H赋初值MOV A,#00HMOV R5,NBW_DATA: MOV @R0,AINC R0INC ADJNZ R5,W_DATAMOV @R0,WR_DATAMOV R0,#30H ;写入缓冲区指向30HLCALL PAGE_WRITE ;对E2PROM进行页写操作LCALL DELAYMOV ADDRESS,#08H ;写入地址指向08LCALL BYTE_WRITE ;对E2PROM进行字节写操作LCALL DELAYMOV R0,#40H ;读出缓冲区指向40HMOV ADDRESS,#00H ;对E2PROM进行连续读操作LCALL RANDOM_READLCALL DELAYLCALL CURRENT_READ ;对E2PROM进行立即地址读操作INC R0MOV @R0,AMOV R0,#30HMOV R1,#40HMOV R5,#09HSETB P1.0COMP:MOV A,@R0 ;比较30H开始和40H开始的9个单元内容 MOV 08H,@R1CJNE A,08H,LED_OFF ;如有一个不相同,转到LED点亮并结束 INC R0INC R1DJNZ R5, COMPSETB P1.0 ;全部相同,熄灭LED,结束SJMP TEST_ENDLED_OFF:CLR P1.3TEST_END:SJMP $;—————————————————————————————————*;*函数名称:DELAY *;*功能描述:产生2MS的延时 *;*调用函数:无 *;*入口条件:无 *;*占用资源:R6、R7 * ;—————————————————————————————————* DELAY: ;2mS DELAYMOV R6,#0FFHDE1: MOV R7,#0AHDE2: DJNZ R7,DE2DJNZ R6,DE1RET ;—————————————————————————————————*;*函数名称:BYTE_WRITE *;*功能描述:对E2PROM指定地址写入数据 *;*调用函数:STA、WRBYT、CACK、STOP *;*入口条件:SLAW——I2C器件写地址 *;* ADDRESS——I2C的内部地址 *;* WR_DATA——写入的数据 *;*占用资源:ACC、F0、SLAW、ADDRESS、WR_DATA * ;—————————————————————————————————*BYTE_WRITE:LCALL STAMOV A,SLAWLCALL WRBYT ;写器件地址LCALL CACKJB F0,BYTE_WRITEMOV A,ADDRESS ;写入地址LCALL WRBYTLCALL CACKJB F0,BYTE_WRITEMOV A,WR_DATALCALL WRBYT ;写入数据LCALL CACKJB F0,BYTE_WRITELCALL STOPRET ;————————————————————————————————* ;*函数名称:PAGE_WRITE * ;*功能描述:对E2PROM指定的页写入8个字节的数据 * ;*调用函数:STA、WRBYT、CACK、STOP * ;*入口条件:SLAW——I2C器件写地址 * ;* ADDRESS——I2C的内部地址 * ;* R0——写数据的首地址 * ;*占用资源:ACC、R0、R7、F0、SLAW、ADDRESS、NB * ;————————————————————————————————* PAGE_WRITE:LCALL STAMOV A,SLAWLCALL WRBYT ;写器件的写地址LCALL CACKJB F0,PAGE_WRITEMOV A,ADDRESS ;写入地址LCALL WRBYTLCALL CACKJB F0,PAGE_WRITEMOV R7,#08HWR_16BYT: ;向E2PROM写入8个字节的数据MOV A,@R0LCALL WRBYTLCALL CACKJB F0,WR_16BYTINC R0DJNZ R7,WR_16BYTLCALL STOPRET ;————————————————————————————————* ;*函数名称:CURRENT_READ * ;*功能描述:读E2PROM当前地址计数器所指地址数据 *;*调用函数:STA、RDBYT、CACK、MNACK、STOP *;*入口条件:SLAR——I2C器件读地址 *;*占用资源:ACC * ;————————————————————————————————* CURRENT_READ:LCALL STAMOV A,SLARLCALL WRBYT ;写器件的读地址LCALL CACKJB F0,CURRENT_READLCALL RDBYT ;读数据LCALL MNACKLCALL STOPRET ;————————————————————————————————*;*函数名称:RANDOM_READ *;*功能描述:对E2PROM从指定地址读出NB个字节的数据 *;*调用函数:STA、WRBYT、CACK、STOP、MACK、MNACK *;*入口条件:SLAW——I2C器件的写地址 *;* SLAR——I2C器件的读地址 *;* ADDRESS——I2C的内部地址 *;* R0——读出数据存储区的首地址 *;*占用资源:ACC、F0、SLAW、SLAR、ADDRESS、R0 * ;————————————————————————————————*RANDOM_READ:LCALL STAMOV A,SLAWLCALL WRBYT ;写器件的写地址LCALL CACKJB F0,RANDOM_READMOV A,ADDRESSLCALL WRBYT ;读的内部地址LCALL CACKJB F0,RANDOM_READRDNBYT: LCALL STAMOV A,SLAR ;写读地址LCALL WRBYTLCALL CACKJB F0,RDNBYTRDN1: LCALL RDBYT ;读数据MOV @R0,ADJNZ NB,ACK ;判断是否读到最后一个字节,如果是发出非应答 LCALL MNACK ;信号,如果不是发出应答信号,继续读数据LCALL STOPRETACK: LCALL MACKINC R0SJMP RDN1;*******************************************************************;*并行总线P1.7,P1.6模拟IIC总线软件包 P1.7--SDA, P1.6--SCL * ;*入口:分配以下符号的内存地址: * ;* R0--读写出数据缓冲区首址指针 * ;* SLA--从器件地址存放单元(写地址或地址) * ;* NB--发送(读或写)数据字节数存放单元 * ;*出口:发送N个字节调用WRNBYT,接受N个字节调用RDNBYT,发送N * ;* 个字节但不要STOP调用WRNBYTS * ;*占用资源:F0标志位,C,R0,R1(第三组) * ;******************************************************************** STA:SETB SDA ;发启始位SETB SCLNOPNOPNOPNOPCLR SDANOPNOPNOPNOPCLR SCLRETSTOP: ;发停止位CLR SDASETB SCLNOPNOPNOPNOPNOPSETB SDANOPNOPNOPNOPCLR SCLRETMACK: ;发应答位CLR SDASETB SCLNOPNOPNOPNOPCLR SCLSETB SDARETMNACK: ;发非应答位SETB SDASETB SCLNOPNOPNOPNOPCLR SCLCLR SDARETCACK: ;发非应答位SETB SDASETB SCLCLR F0MOV A,P1JNB ACC.7,CEND ;应答位为1,不置位F0 SETB F0CEND: CLR SCLNOPRETWRBYT: ;写单字节MOV R1,#08HWLP: RLC AJC WR1AJMP WR0 ;跳入写0WLP1: DJNZ R1,WLPRETWR1: ;写1SETB SDASETB SCLNOPNOPNOPNOPCLR SCLCLR SDAAJMP WLP1WR0: ;写0CLR SDASETB SCLNOPNOPNOPNOPCLR SCLAJMP WLP1RDBYT: ;读单字节MOV R1,#08HRLP:SETB SDASETB SCLMOV A,P1JNB ACC.7,RD0 ;转读0AJMP RD1 ;转读1RLP1:DJNZ R1,RLP ;8位全接收完毕,转退出 RETRD0:CLR CMOV A,R2RLC AMOV R2,ACLR SCLAJMP RLP1RD1:SETB CMOV A,R2RLC AMOV R2,ACLR SCLAJMP RLP1END。
C51编写的AT24C02详细的读写程序
C51_AT24C02读写程序:/*void start() //开始信号void stop() //停止信号void Ack() //发确认信号void NoAck() //发无确认信号void init()//初始化信号,拉高SDA和SCL两条总线bit write_byte(uchar date)//写一字节,将date 写入AT24C02 中uchar read_byte()//读一字节,从AT24C02 中读一字节bit busy() //应答查询,stop()后,启动A T24C02内部写周期,启动查询//初始化EEPROM子程序内容为0XFF,nPage(0~31)void Init_Flash(uchar nPage) //8 bytes/1 page init 0xFFvoid write_add(uchar address,uchar date)//向AT24C02 中写数据//从AT24C02中给定的地址nAddr起,将存放在以指针nContent开头的存储空间中的nLen 个字节数据,连续写入AT24C02void write_flash(uchar *nContent,uchar nAddr, uchar nLen)uchar read_add(uchar address)//从AT24C02 中读出数据//从AT24C02中给定的地址nAddr起,读取nLen个字节数据存放在以指针nContent开头的存储空间。
void read_flash(uchar *nContent,uchar nAddr, uchar nLen)*//*单片机P2口接74HC138(三八译码器)P2.3--74HC138:/EI、P2.2--74HC138:A2、P2.1--74HC138:A1、P2.0--74HC138:A0译码器输出Y0,Y1、Y2、Y3、Y4、Y5、Y6、Y7均低电平有效,分别选通1~8个数码管。
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子程序。
IAR STM8 24C02 24cxx 读写程序
asm("nop");
asm("nop");
asm("nop");
I2C_SCL=0;
//只有在低电平时,才允许修改 SDA 数据
F_delay_5us_24Cxx();
I2C_SDA=1;
//Start 是在 SCL 为高时,SDA 为下降沿
F_delay_5us_24Cxx();
I2C_SCL=1;
F_delay_5us_24Cxx();
I2C_SDA=0;
/*发送起始信号*/
else
date &= 0xfe;
I2C_SCL=0;
F_delay_5us_24Cxx();
}
return date;
}
/*==============================================================================
=
将数据写入 24Cxx 里面
F_delay_5us_24Cxx();
for(uchar i=0;i<8;i++) /*要传送的数据长度为 8 位*/
{
I2C_SCL=1; /*置时钟线为高,通知被控器开始接收数据位*/
F_delay_5us_24Cxx();
ATMEGA16读写iic(TWI)(24c02) C语言程序
ATMEGA16读写iic(24c02) C语言程序测试通过#include <iom16v.h>#include "I2C.h"#include "1602.h"#include "delay.h"/*通过AVR往I IC写数据,并通过串口把数据读出显示出来*///===============================================================void UART_init(void) //UART初始化{ DDRD = 0x02;PORTD = 0x00;UCSRA = 0x02; /*无倍速*/UCSRB = 0x18; /*允许接收和发送*/UC SRC = 0x06; /*8位数据,1位停止位,无校验*/UBRRH = 0x00;UBRRL = 12; /*9600*/}//===============================================================void USART_TXD(float data) //发送采用查询方式{while( !(UCSRA & BIT(UDRE)) );UDR=data;while( !(UCSRA & BIT(TXC )) );UCSRA|=BIT(TXC);}void main(void){unsigned char i;//LCD_init();uart_init();//TART初始化SEI(); //全局中断使能while(1){/*I2C_Write('n',0x00);I2C_Write('c',0x01);I2C_Write('e',0x02);I2C_Write('p',0x03);I2C_Write('u',0x04);*/i=I2C_Read(0x00);//LCD_write_char(0,0,i); USART_TXD(i);i=I2C_Read(0x01);//LCD_write_data(i);USART_TXD(i);i=I2C_Read(0x02);//LCD_write_data(i);USART_TXD(i);i=I2C_Read(0x03);//LCD_write_data(i);USART_TXD(i);i=I2C_Read(0x04);//LCD_write_data(i);USART_TXD(i);}}/*上面上主函数部分*/#include <macros.h>#include "delay.h"//I2C 状态定义//MT 主方式传输 MR 主方式接受#define START 0x08#define RE_START 0x10#define MT_SLA_ACK 0x18#define MT_SLA_NOACK 0x20#define MT_DATA_ACK 0x28#define MT_DATA_NOACK 0x30 #define MR_SLA_ACK 0x40#define MR_SLA_NOACK 0x48#define MR_DATA_ACK 0x50#define MR_DATA_NOACK 0x58#define RD_DEVICE_ADDR 0xA1 //前4位器件固定,后三位看连线,最后1位是读写指令位#define WD_DEVICE_ADDR 0xA0//常用TWI操作(主模式写和读)#define Start() (TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN)) //启动I2C#define Stop() (TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN)) //停止I2C#define Wait() {while(!(TWCR&(1<<TWINT)));} //等待中断发生#define TestAck() (TWSR&0xf8) //观察返回状态#define SetAck (TWCR|=(1<<TWEA)) //做出ACK应答#define SetNoAck (TWCR&=~(1<<TWEA)) //做出Not Ack应答#define Twi() (TWCR=(1<<TWINT)|(1<<TWEN)) //启动I2C#define Write8Bit(x) {TWDR=(x);TWCR=(1<<TWINT)|(1<<TWEN);} //写数据到TWDRunsigned char I2C_Write(unsigned char Wdata,unsigned char RegAddress); unsigned char I2C_Read(unsigned RegAddress);/*********************************************I2C总线写一个字节返回0:写成功返回1:写失败**********************************************/unsigned char I2C_Write(unsigned char Wdata,unsigned char RegAddress){Start(); //I2C启动Wait();if(TestAck()!=START)return 1; //ACKWrite8Bit(WD_DEVICE_ADDR); //写I2C从器件地址和写方式Wait();if(TestAck()!=MT_SLA_ACK)return 1; //ACKWrite8Bit(RegAddress); //写器件相应寄存器地址Wait();if(TestAck()!=MT_DATA_ACK)return 1; //ACKWrite8Bit(Wdata); //写数据到器件相应寄存器Wait();if(TestAck()!=MT_DATA_ACK)return 1; //ACKStop(); //I2C停止delay_nms(10); //延时return 0;}/*********************************************I2C总线读一个字节返回0:读成功返回1:读失败**********************************************/ unsigned char I2C_Read(unsigned RegAddress){unsigned char temp;Start();//I2C启动Wait();if (TestAck()!=START)return 1; //ACKWrite8Bit(WD_DEVICE_ADDR); //写I2C从器件地址和写方式Wait();if (TestAck()!=MT_SLA_ACK)return 1; //ACKWrite8Bit(RegAddress); //写器件相应寄存器地址Wait();if (TestAck()!=MT_DATA_ACK)return 1;Start(); //I2C重新启动Wait();if (TestAck()!=RE_START)return 1;Write8Bit(RD_DEVICE_ADDR); //写I2C从器件地址和读方式Wait();if(TestAck()!=MR_SLA_ACK)return 1; //ACKTwi(); //启动主I2C读方式Wait();if(TestAck()!=MR_DATA_NOACK)return 1; //ACKtemp=TWDR;//读取I2C接收数据Stop();//I2C停止return temp;}/*以上是IIC.h头文件部分,需要对照技术文档好好研究*/*----------------------------------------------------------------------- 延时函数编译器:I CC-AVR v6.31A 日期: 2005-11-24 20:29:57目标芯片 : M16时钟: 8.0000M Hz作者:archeng504-----------------------------------------------------------------------*/ #ifndef __delay_h#define __delay_hvoid delay_nus(unsigned int n);void delay_nms(unsigned int n);void delay_1us(void);void delay_1ms(void) ;void delay_1us(void) //1us延时函数{asm("nop");}void delay_nus(unsigned int n) //N us延时函数{unsigned int i=0;for (i=0;i<n;i++)delay_1us();}void delay_1ms(void) //1ms延时函数{unsigned int i;for (i=0;i<1140;i++);}void delay_nms(unsigned int n) //N ms延时函数{unsigned int i=0;for (i=0;i<n;i++)delay_1ms();}#endif/*以上是delay.h部分,再加上IIC中自带的iom16v.h 和macros.h就可以编译通过*//*注意点:本程序在实验板ATMEGA16上测试通过,在示波器把SCL,SDA信号线有数据,移值到自己电路上可以放心使用,在ATMEGA32上一样使用,本人24C02的A2,A1,A0都是接地,若地址不一样,在程序相应位置改一下就可以,串口上调试单片机的基础,所以它一定要会用*//*本程序调试软件环境是ICC6.31*/。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
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子程序。
SETB SDA24CLR SCLK24CALL START24 ;启动MOV A,#0A0HCALL SHIFT8 ;移位CALL ACK ;响应POP ACCCALL SHIFT8CALL ACKCALL START24MOV A,#0A1HCALL SHIFT8CALL ACKSETB SDA24MOV R7,#8CLR ASETB SDA24RD000: RL A ;8个位SETB SCLK24MOV C,SDA24MOV ACC.0,CCLR SCLK24DJNZ R7,RD000RET;------------------------------- ;写入24C02程序:WT24: PUSH ACCSETB SDA24CLR SCLK24CALL START24MOV A,#0A0HCALL SHIFT8CALL ACKPOP ACCCALL SHIFT8CALL ACKMOV A,BCALL SHIFT8CALL ACKCALL STOPCALL DELAY2RET; ------------------------------- ;开始条件START24:CLR SDA24SETB SDA24SETB SCLK24CLR SDA24CLR SCLK24RET;停止条件STOP: CLR SDA24SETB SCLK24SETB SDA24RET;应答信号ACK: SETB SCLK24CLR SCLK24RET;读、写数据SHIFT8: MOV R7,#8SH01: RLC AMOV SDA24,CSETB SCLK24CLR SCLK24DJNZ R7,SH01RETDELAY2: ;延时NOPNOPNOPNOPRETENDc语言参考程序:#include<reg51.h> //头文件#include<intrins.h>#define uchar unsigned char //宏定义,为方便编程#define uint unsigned int#define DIGI P0 //宏定义,将P0口定义为ad7-ad0#define SELECT P2 //宏定义,将P2口定义为数码管选择位sbit SDA=P3^7; //定义数据线sbit SCL=P3^6; //定义时钟线uint value=0;uchardigivalue[]={0x28,0x7e,0x0a2,0x62,0x74,0x61,0x21,0x7a,0x20,0x60}; //数字数组,依次为0-9#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};#define OP_WRITE 0xa0 // 器件地址以及写入操作#define OP_READ 0xa1 // 器件地址以及读取操作void start();void stop();uchar shin();bit shout(uchar write_data);void write_byte( uchar addr, uchar write_data);void delayms(uint ms);uchar read_current();uchar read_random(uchar random_addr);/**********************************************************/ void start() //I2C启动函数//开始位{SDA = 1; //使能 SDASCL = 1;delayNOP();SDA = 0;delayNOP();SCL = 0;}/**********************************************************/ void stop() //I2C停止函数// 停止位{SDA = 0;delayNOP();SCL = 1;delayNOP();SDA = 1;}/**********************************************************/ uchar shin()// 从AT24C02移出数据到MCU{uchar i,read_data;for(i = 0; i < 8; i++){SCL = 1;read_data <<= 1; //数据左移一位read_data |= SDA;SCL = 0;}return(read_data);}/**********************************************************/ bit shout(uchar write_data)// 从MCU移出数据到AT24C02{uchar i;bit ack_bit;for(i = 0; i < 8; i++) // 循环移入8个位{SDA = (bit)(write_data & 0x80);_nop_();SCL = 1;delayNOP();SCL = 0;write_data <<= 1;}SDA = 1; // 读取应答delayNOP();SCL = 1;delayNOP();ack_bit = SDA;SCL = 0;return ack_bit; // 返回AT24C02应答位}/**********************************************************/ void write_byte(uchar addr, uchar write_data)// 在指定地址addr处写入数据write_data{start();shout(OP_WRITE);shout(addr);shout(write_data);stop();delayms(10); // 写入周期}/**********************************************************/ uchar read_current()// 在当前地址读取{uchar read_data;start();shout(OP_READ);read_data = shin();stop();return read_data;}/**********************************************************/ uchar read_random(uchar random_addr)// 在指定地址读取{start();shout(OP_WRITE);shout(random_addr);return(read_current());}/**********************************************************/ void delayms(uint ms)// 延时子程序{uchar k;while(ms--){for(k = 0; k < 120; k++);}}/**********************************************************/ void delay() //复位消抖动函数{uchar ii=0,jj=0,kk=0;for(ii=0;ii<200;ii++)for(jj=0;jj<200;jj++);}char code SST516[3] _at_ 0x003b; //仿真器保留main(){SCL = 0;delay();value=read_random(0); //读取单片机复位次数value=value+1; //读到的次数加一if(value>9) value=0;write_byte(0,value);P2=0xdf; //选择第二个数码管DIGI=digivalue[value]; //显示次数while(1);}。