《电子系统设计》实验实验五:51单片机最小系统应用3班级:11电科2班姓名:张俊为学号:Xb11640218一、实验目的和要求利用AT24C02断电以后存储的数据不消失的特点,可以做一个断电保护装置。要求能够改变AT24C02某个单元的内容,并显示到数码管上。1.首先利用单片机做一个自动计时器。2.对AT24C02里某个特定单元每隔一秒加一,并实时显示数值。然后随机关断电源,在通电以后计时器接着断电前的状态继续计时。二、设计方案利用24C02,设计实现流水灯效果,设计框图如下:利用24C02断电以后存储的数据不消失的特点,可以做一个断电保护装置。首先利用单片机做一个0—99秒的自动计时器。然后随机关断电源,在通电以后计时器接着断电前的状态继续计时。三、程序设计#includereg51.h#includeintrins.h#defineuintunsignedint#defineucharunsignedcharunsignedcharsec;//定义计数值,每过1秒,sec加1unsignedinttcnt;//定时中断次数bitwrite=0;//写24C08的标志;sbitsda=P2^0;//I2C接口SDA定义sbitscl=P2^1;//IIC接口SCL定义sbitdula=P2^6;sbitwela=P2^7;unsignedcharj,k;voiddelay(unsignedchari)//延时程序{for(j=i;j0;j--)for(k=125;k0;k--);}ucharcodetable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,//数码管编码0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};voiddisplay(ucharbai_c,ucharsh_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);}voiddelay1(unsignedcharx)//延时子函数{unsignedinti;for(i=0;ix;i++);}voidflash()//延时子函数{;;}voidx24c08_init()//24c02初始化子程序{scl=1;flash();sda=1;flash();}voidstart()//启动I2C总线{sda=1;flash();scl=1;flash();sda=0;flash();scl=0;flash();}voidstop()//停止I2C总线{sda=0;flash();scl=1;flash();sda=1;flash();}voidwritex(unsignedcharj)//写一个字节{unsignedchari,temp;temp=j;for(i=0;i8;i++){temp=temp1;scl=0;flash();sda=CY;flash();scl=1;flash();}scl=0;flash();sda=1;flash();}unsignedcharreadx()//读一个字节{unsignedchari,j,k=0;scl=0;flash();sda=1;for(i=0;i8;i++){flash();scl=1;flash();if(sda==1)j=1;elsej=0;k=(k1)|j;scl=0;}flash();return(k);}voidclock()//I2C总线应答子函数{unsignedchari=0;scl=1;flash();while((sda==1)&&(i255))i++;scl=0;flash();}unsignedcharx24c08_read(unsignedcharaddress){unsignedchari;start();writex(0xa0);clock();writex(address);clock();start();writex(0xa1);clock();i=readx();stop();delay1(10);return(i);}voidx24c08_write(unsignedcharaddress,unsignedcharinfo){EA=0;start();writex(0xa0);clock();writex(address);clock();writex(info);clock();stop();EA=1;delay1(50);}voidt0(void)interrupt1using0//定时中断服务函数{TH0=(65536-50000)/256;//对TH0TL0赋值TL0=(65536-50000)%256;//重装计数初值tcnt++;//每过250usttcnt加一if(tcnt==20)//计满20次(1秒)时{tcnt=0;//重新再计sec++;write=1;//1秒写一次24C02if(sec==100)//定时100秒,在从零开始计时{sec=0;}}}voidmain()//主函数{unsignedchari;TMOD=0x01;//定时器工作在方式1ET0=1;EA=1;//开中断x24c08_init();//初始化24C08sec=x24c08_read(2);//读出保存的数据赋于secTH0=(65536-50000)/256;//对TH0TL0赋值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);}}}//在24c02的地址2中写入数据sec#includereg52.h#includeintrins.h#defineucharunsignedchar#defineuintunsignedint#defineOP_WRITE0xa0//器件地址以及写入操作#defineOP_READ0xa1//器件地址以及读取操作ucharcodedisplay[72]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F,0xBF,0xDF,0xEF,0xF7,0xFB,0xFD,0xFE,0xFF,0xFE,0xFC,0xF8,0xF0,0xE0,0xC0,0x80,0x00,0x80,0xC0,0xE0,0xF0,0xF8,0xFC,0xFE,0xFF,0xFC,0xF9,0xF3,0xE7,0xCF,0x9F,0x3F,0x9F,0xCF,0xE7,0xF3,0xF9,0xFC,0xFF,0xE7,0xDB,0xBD,0x7E,0xBD,0xDB,0xE7,0xFF,0xE7,0xC3,0x81,0x00,0x81,0xC3,0xE7,0xFF,0xAA,0x55,0x18,0xFF,0xF0,0x0F,0x00,0xFF,0x00,0xFF};sbitSDA=P2^0;sbitSCL=P2^1;voidstart();voidstop();ucharshin();bitshout(ucharwrite_data);voidwrite_byte(ucharaddr,ucharwrite_data);voidfill_byte(ucharfill_size,ucharfill_data);voiddelayms(uintms);ucharread_current();ucharread_random(ucharrandom_addr);#definedelayNOP();{_nop_();_nop_();_nop_();_nop_();};main(void){uchari;SDA=1;SCL=1;fill_byte(72,0xff);//将前72字节填充0xfffor(i=0;i72;i++)//写入显示代码到AT24C02{write_byte(i,display[i]);}for(i=0;i72;i++)//从AT24C02移出数据送到P0口显示{P1=read_random(i);delayms(350);}}voidstart()//开始位{SDA=1;SCL=1;delayNOP();SDA=0;delayNOP();SCL=0;}voidstop()//停止位{SDA=0;delayNOP();SCL=1;delayNOP();SDA=1;}ucharshin()//从AT24C02移出数据到MCU{uchari,read_data;for(i=0;i8;i++){SCL=1;read_data=1;read_data|=SDA;SCL=0;}return(read_data);}bitshout(ucharwrite_data)//从MCU移出数据到AT24C02{uchari;bitack_bit;for(i=0;i8;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;returnack_bit;}//返回AT24C02应答位voidwrite_byte(ucharaddr,ucharwrite_data)//在指定地址addr处写入数据write_data{start();shout(OP_WRITE);shout(addr);shout(write_data);stop();delayms(10);}//写入周期voidfill_byte(ucharfill_size,ucharfill_data)//填充数据fill_data到EEPROM内fill_size字节{uchari;for(i=0;ifill_size;i++){write_byte(i,fill_data);}}ucharread_current()//在当前地址读取{ucharread_data;start();shout(OP_READ);read_data=shin();stop();returnread_data;}ucharread_random(ucharrandom_addr)//在指定地址读取{start();shout(OP_WRITE);shout(random_addr);return(read_current());}voiddelayms(uintms)//延时子程序{uchark;while(ms--){for(k=0;k120;k++);}}四、调试及结果【流水灯效果】【计时效果】五、总结本次实验的内容对于我们的专业水平有了显著的提高。在过程中,我和搭档工作分配合理,积极的学习。这次课程我们对于查资料看关键有了更进一步的认识,对于编程动手能力也有了一定提高,在程序的理解上相较于以前能够更快的进入思路,更好的理解。总之,我获益匪浅,也会珍惜这次机会。