- #include <reg52.h>//52單片機頭文件
- #include <intrins.h>//intrins.h文件
- #define uchar unsigned char // 自定義uchar為unsigned char(即無符號字符型數據,數據范圍:0到255。)
- #define uint unsigned int //自定義uint為unsigned int(即有符號整數型數據,數據范圍:0到65535。)
- #define ISP_ReadCommand 0x01 //自定義ISP的讀字節操作
- #define ISP_WriteCommand 0x02 //自定義ISP的寫字節操作
- #define ISP_EraseCommand 0x03 //自定義ISP的擦除扇區操作
- #define ERROR 0
- #define OK 1
- sbit duanxuan=P2^6;
- sbit weixuan=P2^7;
- uint count,value;//聲明定時器0中斷次數變量、數值變量
- uint ge,shi,bai,qian;//聲明數碼管個位變量、數碼管十位變量、數碼管百位變量、數碼管千位變量
- uint valuege,valueshi,valuebai,valueqian;//聲明數值變量個位變量、數值變量十位變量、數值變量百位變量、數值變量千位變量
- uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f} ; //共陰數碼管段碼數字0~9字碼表,高電平點亮數碼管段碼數字0~9。
- //#define WAIT_TIME 0x00 //mcu clock 小于 40mhz
- //#define WAIT_TIME 0x01 //mcu clock 小于 20mhz
- //#define WAIT_TIME 0x02 //mcu clock 小于 10mhz
- #define WAIT_TIME 0x03 //mcu clock 小于 5mhz
- sfr ISP_DATA=0xe2; //Flash數據寄存器
- sfr ISP_ADDRH=0xe3; //Flash高字節地址寄存器
- sfr ISP_ADDRL=0xe4; //Flash低字節地址寄存器
- sfr ISP_CMD=0xe5; //Flash命令模式寄存器
- sfr ISP_TRIG=0xe6; //Flash命令觸發寄存器
- sfr ISP_CONTR=0xe7; //ISP/IAP 控制寄存器
- // void Delay100us() //晶振11.0592MHz,100微妙延時。
- //{
- // unsigned char i, j;
- // _nop_();
- // _nop_();
- // i = 2;
- // j = 15;
- // do
- // {
- // while (--j);
- // }
- // while (--i);
- // }
- void Delay(uint z)//延時程序
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=110;y>0;y--);
- }
- void OPEN_ISP_IAP()//打開ISP/IAP功能函數
- {
- EA=0;//關中斷
- ISP_CONTR=ISP_CONTR&0x18;//0001,1000
- ISP_CONTR=ISP_CONTR|WAIT_TIME;//寫入硬件延時
- ISP_CONTR=ISP_CONTR|0x80;//ISPEN=1
- }
- void CLOSE_ISP_IAP()//關閉ISP/IAP功能函數
- {
- ISP_CONTR=ISP_CONTR&0x7f;//ISPEN=0
- ISP_TRIG=0x00;//關掉與ISP有關的特殊功能寄存器
- EA=1;//開中斷
- }
- void ActiveOperate(void)//觸發執行函數
- {
- OPEN_ISP_IAP(); //打開ISP/IAP功能
- ISP_TRIG=0x46; //觸發ISP_IAP命令字節1
- ISP_TRIG=0xb9; // 觸發ISP_IAP命令字節2
- _nop_();//延時
- }
- uchar ReadByte(uint byteaddress)//讀字節函數
- {
- ISP_ADDRH=(uchar)(byteaddress>>8);//高8位字節地址
- ISP_ADDRL=(uchar)(byteaddress&0x00ff);//低8位字節地址
- ISP_CMD=ISP_CMD&0xf8;//清除低3位
- ISP_CMD=ISP_CMD|ISP_ReadCommand;//寫入讀命令
- ActiveOperate();//觸發執行
- CLOSE_ISP_IAP();//關閉ISP/IAP功能
- return (ISP_DATA);//返回讀到的數據
- }
- void SectorErase(uint sectoraddress)//刪除扇區函數
- {
- uint isectoraddress;//聲明扇區地址變量
- isectoraddress=(sectoraddress&0xfe00);//扇區地址賦值
- ISP_ADDRH=(uchar)(isectoraddress>>8);//高8位字節地址
- ISP_ADDRL=0x00;//低8位字節地址復位
- ISP_CMD=ISP_CMD&0xf8;//清除低3位
- ISP_CMD=ISP_CMD|ISP_EraseCommand;//擦除命令3
- ActiveOperate();//觸發執行
- CLOSE_ISP_IAP();//關閉ISP/IAP功能
- }
- void WriteByte(uint byteaddress,uchar originaldata)//寫字節函數
- {
- ISP_ADDRH=(uchar)(byteaddress>>8);//高8位字節地址
- ISP_ADDRL=(uchar)(byteaddress&0x00ff);//低8位字節地址
- ISP_CMD=ISP_CMD&0xf8;//清除低3位
- ISP_CMD=ISP_CMD|ISP_WriteCommand;//寫命令2
- ISP_DATA=originaldata;//寫入數據準備
- ActiveOperate();//觸發執行
- CLOSE_ISP_IAP();//關閉ISP/IAP功能
- }
- void ShuMaGuanDisplayValue(uint value)//數碼管顯示數值函數
- {
- qian=value/1000;//數碼管千位變量
- bai=value%1000/100;//數碼管百位變量
- shi=value%100/10;//數碼管十位變量
- ge=value%10;//數碼管個位變量
-
- //
- // P2=0xfe;//數碼管千位顯示位
- // P0=table[qian];//數碼管千位數值顯示
- // Delay(5);//延時
- // P2=0xfd;//數碼管百位顯示位
- // P0=table[bai];//數碼管百位數值顯示
- // Delay(5);//延時
- // P2=0xfb;//數碼管十位顯示位
- // P0=table[shi];//數碼管十位數值顯示
- // Delay(5);//延時
- // P2=0xf7;//數碼管個位顯示位
- // P0=table[ge];//數碼管個位數值顯示
- // Delay(5);//延時
- weixuan=1;
- P0=0xfe;//數碼管千位顯示位
- weixuan=0;
- duanxuan=1;
- P0=table[qian];//數碼管千位數值顯示
- duanxuan=0;
- P0=0xff;
- Delay(5);//延時
- weixuan=1;
- P0=0xfd;//數碼管百位顯示位
- weixuan=0;
- duanxuan=1;
- P0=table[bai];//數碼管百位數值顯示
- duanxuan=0;
- P0=0xff;
- Delay(5);//延時
-
- weixuan=1;
- P0=0xfb;//數碼管十位顯示位
- weixuan=0;
- duanxuan=1;
- P0=table[shi];//數碼管十位數值顯示
- duanxuan=0;
- P0=0xff;
- Delay(5);//延時
- weixuan=1;
- P0=0xf7;//數碼管個位顯示位
- weixuan=0;
- duanxuan=1;
- P0=table[ge];//數碼管個位數值顯示
- duanxuan=0;
- P0=0xff;
- Delay(5);//延時
- }
- void Timer0Init()//定時器0初始化
- {
- TMOD=0x01;//設定定時器類型為定時器0,定時器工作模式為模式0。
- TH0=(65536-50000)/256;//TH0裝初值
- TL0=(65536-50000)%256;//TL0裝初值
- EA=1;//開啟定時器總中斷
- ET0=1;//開啟定時器0中斷開關
- TR0=1;//啟動定時器0
- }
- void Timer0() interrupt 1//定時器0中斷函數
- {
- TH0=(65536-50000)/256;//TH0重新裝值
- TL0=(65536-50000)%256;//TL0重新裝值
- count++;//定時器0中斷次數變量先賦值再加
- }
- void main()//主函數
- {
- Timer0Init();//定時器0初始化函數
- value=ReadByte(0x2004)*1000+ReadByte(0x2003)*100+ReadByte(0x2002)*10+ReadByte(0x2001);//斷電后,讀取EEPROM存儲器掉電保存的數據。
- if(value>=3600)//判斷數值變量是否大于等于3600
- value=0;//數值變量置0
- while(1)//固定循環
- {
- if(count==18)//判斷定時器0中斷次數變量是否為18次
- {
- count=0;//定時器0中斷次數變量歸零
- value++;//數值變量先賦值再加
- valueqian=value/1000;//數值變量千位變量
- valuebai=value%1000/100;//數值變量百位變量
- valueshi=value%100/10;//數值變量十位變量
- valuege=value%10;//數值變量個位變量
- SectorErase(0x2000);//擦除EEPROM第一扇區
- WriteByte(0x2004,valueqian);//對EEPROM第一扇區第4個扇區地址(從第0個扇區地址數起)重新寫入數據
- WriteByte(0x2003,valuebai);//對EEPROM第一扇區第3個扇區地址(從第0個扇區地址數起)重新寫入數據
- WriteByte(0x2002,valueshi);//對EEPROM第一扇區第2個扇區地址(從第0個扇區地址數起)重新寫入數據
- WriteByte(0x2001,valuege);//對EEPROM第一扇區第1個扇區地址(從第0個扇區地址數起)重新寫入數據
- if(value==3600)//判斷數值變量是否達到3600
- {
- value=0;//數值變量歸零
- }
- }
- ShuMaGuanDisplayValue(value);//數碼管顯示數值
- }
- }
復制代碼
|