练习STC51单片机,使用24C02完成技术,掉电保存功能数码管显示当前计数,断电后再次上电可以走上次断点出重新计数;
制作出来的实物图如下:
实物断电前
实物断电后
单片机源程序如下:
- #include <reg51.h>
- #include <intrins.h>
- #define OP_READ 0xa1 // 器件地址以及读取操作
- #define OP_WRITE 0xa0 // 器件地址以及写入操作
- #define MAX_ADDR 0x7f // AT24C02最大地址
- #define uint unsigned int
- #define uchar unsigned char
- sbit P2_0 = P2^0;
- sbit P2_1 = P2^1;
- sbit P2_2 = P2^2;
- sbit P2_3 = P2^3;
- unsigned char code dis_code[] = {0x7F,0xBF,0xDF,0xEF,0xF7,0xFB,0xFD,0xFE}; // 写入到AT24C01的数据串
- sbit SDA = P2^5;
- sbit SCL = P2^6;
- sbit k1 = P3^5; //手动清零按键
- void start();
- void stop();
- unsigned char shin();
- bit shout(unsigned char write_data);
- unsigned char read_random(unsigned char random_addr);
- void write_byte( unsigned char addr, unsigned char write_data);
- void fill_byte(unsigned char fill_data);
- void delayms(unsigned int ms);
- uint x,zz;
- unsigned char aa;
- uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,
- 0xf8,0x80,0x90};
- void delay(unsigned ii)
- {
- uint j,k;
- for(j=ii;j>0;j--)
- for(k=1;k>0;k--);
- }
- void display(uint x)
- {
-
- P0=table[x/1000];
- P2_0 = 0;
- delay(20);
- P2_0 = 1;
-
- P0=table[(x%1000)/100];
- P2_1 = 0;
- delay(20);
- P2_1 = 1;
- P0=table[((x%1000)%100)/10];
- P2_2 = 0;
- delay(20);
- P2_2 = 1;
- P0=table[((x%1000)%100)%10];
- P2_3 = 0;
- delay(20);
- P2_3 = 1;
-
- }
- main(void)
- {
- unsigned char p,q; // p,q为计数的形参赋值
- SDA = 1;
- SCL = 1;
- TMOD|=0x11; //设T0为方式1,GATE=1;
- TL0 = 0x00;
- TH0 = 0xDC;
- TR0=1; ET0=1;
- EA=1; //全局中断开
- EX0=1; //外部中断0开
- IT0=1;
- //fill_byte(0x00); // 全部填充0x00
- /************************************
- for(i = 1 ; i < 8; i++) //写入显示代码到AT24Cxx
- {
- write_byte(i, dis_code[i]);
- // write_byte(0, 0);
- }
- *************************************/
- delayms(500);
- p = read_random(0);
- q= read_random(1);
- // p++;
- // if(p>=255) //手动上电计数
- // q++;
- // write_byte(0, p);
- // write_byte(1, q);
- // delayms(1);
- while(1)
- {
- zz=q*255+p ;
- if(zz>=9999)
- zz=0;
- display(zz);
- delayms(50);
-
- if(TF0==1)
- { TF0=0;
- TL0 = 0x00;
- TH0 = 0xDC;
- aa++;
- if(aa>=100)
- {
- p++;
- if(p>=255)
- {p=0;q++;}
- aa=0;
- write_byte(0, p);
- write_byte(1, q);
- }
- }
- if(k1==0)
- fill_byte(0x00); // 全部填充0x00
- }
- }
- void start()
- // 开始位
- {
- SDA = 1;
- SCL = 1;
- _nop_();
- _nop_();
- SDA = 0;
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- SCL = 0;
- }
- void stop()
- // 停止位
- {
- SDA = 0;
- _nop_();
- _nop_();
- SCL = 1;
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- SDA = 1;
- }
- unsigned char shin()
- // 从AT24Cxx移入数据到MCU
- {
- unsigned char i,read_data;
- for(i = 0; i < 8; i++)
- {
- SCL = 1;
- read_data <<= 1;
- read_data |= (unsigned char)SDA;
- SCL = 0;
- }
- return(read_data);
- }
- bit shout(unsigned char write_data)
- // 从MCU移出数据到AT24Cxx
- {
- unsigned char i;
- bit ack_bit;
- for(i = 0; i < 8; i++) // 循环移入8个位
- {
- SDA = (bit)(write_data & 0x80);
- _nop_();
- SCL = 1;
- _nop_();
- _nop_();
- SCL = 0;
- write_data <<= 1;
- }
- SDA = 1; // 读取应答
- _nop_();
- _nop_();
- SCL = 1;
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- ack_bit = SDA;
- SCL = 0;
- return ack_bit; // 返回AT24Cxx应答位
- }
- void write_byte(unsigned char addr, unsigned char write_data)
- // 在指定地址addr处写入数据write_data
- {
- start();
- shout(OP_WRITE);
- shout(addr);
- shout(write_data);
- stop();
- delayms(10); // 写入周期
- }
- void fill_byte(unsigned char fill_data)
- // 填充数据fill_data到EEPROM内
- {
- unsigned char i;
- for(i = 0; i < MAX_ADDR; i++)
- {
- write_byte(i, fill_data);
- }
- }
- unsigned char read_current()
- // 在当前地址读取
- {
- unsigned char read_data;
- start();
- shout(OP_READ);
- read_data = shin();
- stop();
- return read_data;
- }
- unsigned char read_random(unsigned char random_addr)
- // 在指定地址读取
- {
- start();
- shout(OP_WRITE);
- shout(random_addr);
- return(read_current());
- }
- void delayms(unsigned int ms)
- // 延时子程序
- {
- unsigned char i;
- while(ms--)
- {
- for(i = 0; i < 120; i++);
- }
- }
复制代码
所有资料51hei提供下载:
24C02与STC12单片机数码管中断记忆计数.rar
(30.05 KB, 下载次数: 28)
|