操作STC單片機(如:STC89C52RC單片機)自帶EEPROM掉電保存數據存儲器存儲數碼管顯示按秒遞增四位數字的項目工程


#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);//數碼管顯示數值     
   }
 }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM