74LS595 AT24C02实现断电记忆五位计数C语言程序
------------------------------------------------------------------------------------------------
74LS595 AT24C02实现断电记忆五位计数C语言程序
//51芯片管脚定义头文件
#include<reg51.h>
#include<intrins.h>
#include<stdio.h>
#include<stdlib.h> //内部包含延时函数 _nop_();
#define uchar unsigned char
#define uint unsigned long int
#define AT24C02_ADDR 0xa0
uchar code
DSY_CODE[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff};
数码管段码
uchar data Buffer_Counts[]={0,0,0,0,0,0,0,0,0,0};
sbit SCLK_595 =P2^0; //移位时钟脉冲
sbit SDATA_595=P2^1; //串行数据输入
sbit RCK_595 =P2^2; //输出锁存器控制脉冲
sbit SDA = P2^3;
sbit SCL = P2^4;
sbit OUT1=P2^5;
sbit OUT2=P2^6;
sbit k1=P3^1;
——————————————————————————————————————
------------------------------------------------------------------------------------------------
sbit k2=P3^2;
uint Count_B,BW;
uchar
temp,GW,SW,DATA,DATA1,DATA2,DASW,DAGW,DABW,SD,BD,M;
// 延时子程序 5us
void delay_5us() //5us
{
_nop_();
}
//1毫秒延时函数
void delay(uint z)
{
uint x,y;
for(x = z; x > 0; x--)
for(y = 114; y > 0 ; y--);
}
//将显示数据送入74HC595内部移位寄存器
void WR_595(void)
{
uchar j;
for (j=0;j<8;j++)
{
——————————————————————————————————————
------------------------------------------------------------------------------------------------
temp=temp<<1;
SDATA_595=CY; //
SCLK_595=1; //上升沿发生移位
_nop_();
_nop_();
SCLK_595=0;
}
}
//将移位寄存器内的数据锁存到输出寄存器并显示
void OUT_595(void)
{
RCK_595=0;
_nop_();
_nop_();
RCK_595=1;
_nop_();
_nop_();
_nop_();
RCK_595=0;
}
//24C02子程序
void I2C_init() //I2C初始化
——————————————————————————————————————
------------------------------------------------------------------------------------------------
{
SDA = 1;
_nop_();
SCL = 1;
_nop_();
}
void I2C_Start() //I2C起始信号
{
SCL = 1;
_nop_();
SDA = 1;
delay_5us();
SDA = 0;
delay_5us();
}
void I2C_Stop() // I2C停止信號
{
SDA = 0;
_nop_();
SCL = 1;
delay_5us();
SDA = 1;
——————————————————————————————————————
------------------------------------------------------------------------------------------------
delay_5us();
} //上升沿将数据送到输出锁存器
void Master_ACK(bit i) // 主机发送应答
{
SCL = 0; // 拉低时钟总线允许SDA数据总线上的数据变化
_nop_(); // 让总线稳定
if (i) //如果i = 1 那么拉低数据总线 表示主机应答
{
SDA = 0;
}
else
{
SDA = 1; //发送非应答
}
_nop_();//让总线稳定
SCL = 1;//拉高时钟总线 让从机从SDA线上读走 主机的应答信
号 _nop_();
SCL = 0;//拉低时钟总线, 占用总线继续通信
_nop_();
SDA = 1;//释放SDA数据总线。
_nop_();
}
——————————————————————————————————————
------------------------------------------------------------------------------------------------
bit Test_ACK() //
从机应答
{
SCL = 1;//时钟总线为高电平期间可以读取从机应答信号
delay_5us();
if (SDA)
{
SCL = 0;
I2C_Stop();
return(0);
}
else
{
SCL = 0;
return(1);
}
}
void I2C_send_byte(uchar byte) //发送一个字节
{
uchar i;
for(i = 0 ; i < 8 ; i++)
{
SCL = 0;
——————————————————————————————————————
------------------------------------------------------------------------------------------------
_nop_();
if (byte & 0x80) //
{
SDA = 1;
_nop_();
}
else
{
SDA = 0;
_nop_();
}
SCL = 1;
_nop_();
byte <<= 1;
}
SCL = 0;
_nop_();
SDA = 1;
_nop_();
}
uchar I2C_read_byte() //读一个字节 {
uchar i, dat; ——————————————————————————————————————
------------------------------------------------------------------------------------------------
SCL = 0 ;
_nop_();
SDA = 1;
_nop_();
for(i = 0 ; i < 8 ; i++)
{
SCL = 1;
_nop_();
dat <<= 1;
if (SDA)
{
dat |= 0x01;
}
_nop_();
SCL = 0;
_nop_();
}
return(dat);
}
bit I2C_WriteData(uchar ADDR,uchar DAT) {
I2C_Start(); //I2C写数据
I2C_send_byte(AT24C02_ADDR+0); if (!Test_ACK())
——————————————————————————————————————
------------------------------------------------------------------------------------------------
{
return(0);
}
I2C_send_byte(ADDR);
if (!Test_ACK())
{
return(0);
}
I2C_send_byte(DAT);
if (!Test_ACK())
{
return(0);
}
I2C_Stop();
return(1);
}
uchar I2C_ReadData(uchar ADDR) //I2C读数据 {
uchar dat;
I2C_Start();
I2C_send_byte(AT24C02_ADDR+0); if (!Test_ACK())
{
return(0);
——————————————————————————————————————
------------------------------------------------------------------------------------------------
}
I2C_send_byte(ADDR);
if (!Test_ACK())
{
return(0);
}
Master_ACK(0);
I2C_Start();
I2C_send_byte(AT24C02_ADDR+1); if (!Test_ACK())
{
return(0);
}
dat = I2C_read_byte();
Master_ACK(0);
I2C_Stop();
return(dat);
}
void jishu() //计数
{
if(!k2)
{
if(Count_B<99999) ——————————————————————————————————————
------------------------------------------------------------------------------------------------
{
DATA++;
M=1;
if(DATA<50)
{
GW=DATA;
I2C_WriteData(DAGW,DATA); delay(1);
}
if(DATA>49)
{
DATA1++;
DATA=0;
GW=0;
SW=SD+DATA1;
I2C_WriteData(DAGW,DATA); delay(1);
I2C_WriteData(DASW,SW); delay(1);
}
if(SW>49)
{
DATA=0;
DATA1=0;
GW=0;
——————————————————————————————————————
------------------------------------------------------------------------------------------------
SW=0;
DATA2++;
BW=BD+DATA2;
I2C_WriteData(DAGW,DATA); delay(1);
I2C_WriteData(DASW,SW); delay(1);
I2C_WriteData(DABW,BW); delay(1);
}
}
}
while(!k2);
}
void qingchu() //清除数据
{
if(!k1)
{
DATA=0;
DATA1=0;
DATA2=0;
SD=0;
GW=0;
SW=0;
BW=0;
——————————————————————————————————————
------------------------------------------------------------------------------------------------
BD=0;
M=1;
OUT1=1;
OUT2=1;
if(!I2C_ReadData(DABW)==0) {
I2C_WriteData(DABW,0X00); delay(1);;
I2C_WriteData(DASW,0X00); delay(1);
I2C_WriteData(DAGW,0X00); delay(1);
}
if(!I2C_ReadData(DASW)==0) {
I2C_WriteData(DASW,0X00); delay(1);
I2C_WriteData(DAGW,0X00); delay(1);
}
else
{
I2C_WriteData(DAGW,0X00); delay(1);
}
GW=I2C_ReadData(DAGW); delay(1);
SW=I2C_ReadData(DASW); delay(1);
BW=I2C_ReadData(DABW); delay(1);
}
while(!k1);
——————————————————————————————————————
------------------------------------------------------------------------------------------------
}
void shujuxianshi_init() //初始化数据显示 {
uchar i;
Count_B=BW*2500+SW*50+GW;
delay(1);
Buffer_Counts[5]=Count_B/10000;
Buffer_Counts[4]=Count_B%10000/1000;
Buffer_Counts[3]=Count_B%1000/100;
Buffer_Counts[2]=Count_B%100/10; Buffer_Counts[1]=Count_B%10;
if( Buffer_Counts[5]==0)
{
Buffer_Counts[5]=0x0a;
if( Buffer_Counts[4]==0) {
Buffer_Counts[4]=0x0a; if( Buffer_Counts[3]==0) {
Buffer_Counts[3]=0x0a; if( Buffer_Counts[2]==0) Buffer_Counts[2]=0x0a; }
}
}
for(i=1;i<6;i++) //刷新显示在数码管上 {
temp=DSY_CODE[Buffer_Counts[i]]; WR_595();
delay(1);
}
——————————————————————————————————————
------------------------------------------------------------------------------------------------
OUT_595();
}
void shujuxianshi() //数据显示
{
uchar i;
if(M==1)
{
M=0;
Count_B=BW*2500+SW*50+GW; delay(1);
Buffer_Counts[5]=Count_B/10000;
Buffer_Counts[4]=Count_B%10000/1000;
Buffer_Counts[3]=Count_B%1000/100;
Buffer_Counts[2]=Count_B%100/10;
Buffer_Counts[1]=Count_B%10;
if( Buffer_Counts[5]==0)
{
Buffer_Counts[5]=0x0a;
if( Buffer_Counts[4]==0)
{
Buffer_Counts[4]=0x0a;
if( Buffer_Counts[3]==0)
{
——————————————————————————————————————
------------------------------------------------------------------------------------------------
Buffer_Counts[3]=0x0a;
if( Buffer_Counts[2]==0)
Buffer_Counts[2]=0x0a;
}
}
}
for(i=1;i<6;i++) //刷新显示在数码管上
{
temp=DSY_CODE[Buffer_Counts[i]];
WR_595();
delay(1);
}
OUT_595();
}
}
void main()
{
DAGW=1; //24C02 数据存储地址 0-255
DASW=2; //24C02 数据存储地址 0-255
DABW=3;
I2C_init();
GW=I2C_ReadData(DAGW); //上电后首先读出24C02第DAGW单——————————————————————————————————————
------------------------------------------------------------------------------------------------
元的值 SW=I2C_ReadData(DASW); //上电后首先读出24C02第DASW单元的值 BW=I2C_ReadData(DABW);
DATA=GW;
SD=SW;
BD=BW;
shujuxianshi_init();
while(1)
{
qingchu();
jishu();
shujuxianshi(); if(Count_B==100) OUT1=0;
if(Count_B==50) OUT2=0; }
}
——————————————————————————————————————