⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 p532flash.c

📁 ISP升级FLASH程序C51源代码
💻 C
字号:
/*
创建时间:2004年8月23日
*/    
#include "AT892051.H"
#include "intrins.h" 
//***************************************************************
#define uchar unsigned char
#define uint unsigned int 
#define ulong unsigned long
//------------------------------------------------------
uchar code DataValid[]={"GRIPS-P4II"};
//------------------------------------------------------
sbit I2C_DATA=P1^1;     
sbit I2C_CLK=P1^0;

sbit FLASH_MOSI=P1^5;
sbit FLASH_MISO=P1^4;
sbit FLASH_SCK=P1^2;
sbit FLASH_RST=P1^3;

sbit FLASH_LED=P1^6;
sbit FLASH_KEY=P3^7;
//全局定义---------------------------------------------------------------- 	
ulong  g_lTimer;        		//定时器 
uchar  keyCheckSum;        		//按键检测记数                                    
struct LoadType{
uchar  Status:4;			//第二运行状态
uchar  Second:1;       			//秒事件
uchar  HalfSec:1;			//半秒事件
uchar  Key:1;                   	//=0,没有按键,=1,有按键
uint   iCheckSumCard;			//数据校验和
uint   iCodeLenth;			//数据长度
uint   iCalCheckSum;			//计算的校验值
uint   iReadLenth;			//读取的长度 
} LoadData;    
//系统状态-------------------------------------------------------
bit g_bFirstEntry;			//首次进入某状态标志
uchar DispType;
//函数声明-------------------------------------------------------
void InitCpuRegister();    
void MainPro();
void LedDisp(uchar);
//***************************************************************
//系统程序          
//***************************************************************
void main()
/*
功能: 初始化MCU,进入主处理程序
返值: 无
入口参数说明:无
*/
{   
    EA=0;
    SP=0x67;		    //STACK 0X67-0X7F,25字节
    InitCpuRegister();
    EA=1;
    MainPro();
}
//--------------------------------------------------------------
/*
函数名:void Timer10ms() interrupt 1 using 1
功能: 10ms中断服务程序
返值: 无
入口参数说明:无
*/
void Timer0() interrupt 1 using 2
{    
    TH0=0xec;     					//EC78,设OSC=6MHz,定时10MS
    TL0=0x85;
     
    g_lTimer++;	    					//定时器
    if(g_lTimer%100==0) LoadData.Second=1;		//秒事件
    if(g_lTimer%15==0)  LoadData.HalfSec=1;		//秒事件
    
    LedDisp(DispType);
    
    FLASH_KEY=1;
    if(!FLASH_KEY) 	                            	//键检测
      {  keyCheckSum++;
         if(keyCheckSum==10) LoadData.Key=1;
      }
    else
      {  keyCheckSum=0;
         LoadData.Key=0;
      }
}

//***************************************************************
//底层程序  
//***************************************************************
/*
函数名: void InitCpuRegister()
功能: 初始化CPU
返值: 无
入口参数说明:
*/
void InitCpuRegister()
{   
    TMOD=0x11;		    		//T0方式1,T1方式1
    TH0=0xec;     	    		//OSC=6MHz,定时10MS
    TL0=0x78;                           
    //TH1=0x3c;             		//OSC=6MHz,定时100MS  
    //TL1=0xb0;                
    
    IT0=1;		    		//INT0边沿触发     
    EX0=1;		    		//INT0中断禁止
    
    IT1=1;		   		//INT1边沿触发
    EX1=0;		    		//INT1中断允许
    ET0=1;		    		//T0中断允许
    //ET1=0;		    		//T1中断允许 
    TR0=1;                  		//启动T0
    //TR1=1;                		//启动T1 
    
    PT0=0; 		    		//定时器0中断优先0 
    PT1=0; 		    		//定时器1中断优先0 
    //PX0=0;		    		//外部中断0优先0
    //PX1=1;		    		//外部中断1优先0
    //%%%%%%%%%%%%初始化IO
    P1=0xf7;
    //%%%%%%%%%%%%初始化系统变量 
    g_lTimer=0; 
    LoadData.Key=0;
    keyCheckSum=0; 
    LoadData.Second=0;
    LoadData.HalfSec=0;    
}	
//***************************************************************************
//定时器
//***************************************************************************
/*
函数名:ulong StartTimer()
功能: 启动定时器
返值:定时起始的定时器值
入口参数说明: 无
使用的全局变量:g_iTimer
*/
ulong StartTimer()
{ 
  return g_lTimer;
}  
//---------------------------------------------------------------------------
/*
函数名:uchar TimerIsOver(uint iStartTime,uint iTime)
功能: :判断定时时间是否到
返值:0---定时时间未到
	1---定时时间已到
入口参数说明:iStartTime---定时起始的定时器值
            iTime---定时时长(单位10ms)
使用的全局变量:g_lTimer
*/
uchar TimerIsOver(ulong lStartTime,ulong lTime)
{ uchar cIsOver;
  ulong lTmp; 
  
  lTmp=lStartTime+lTime;
  if(lStartTime<lTmp)
    { if(g_lTimer>=lStartTime&&g_lTimer<lTmp) cIsOver=0;
      else cIsOver=1;
    }
  else 
    { if(g_lTimer>=lTmp&&g_lTimer<lStartTime) cIsOver=1;
      else cIsOver=0;
    }
  return cIsOver; 
}      
//---------------------------------------------------------
/*
函数名:void Delay(unsigned long lTime)
功能: 延时
返值:无
入口参数说明:
    lTime---延时时长(单位10ms)
使用的全局变量:无
*/
void Delay(ulong lTime)
{  ulong lTemp;
   lTemp=StartTimer(); 
   
   while(1)
     { //WDT=1;
       if(TimerIsOver(lTemp,lTime)) break;
     }  
}
//*********************************************************************
//****************************************************************
//FLASH 编程
/*--------------------------------------------------
函数名: void McuSendByte()
功能: 发送4个字节
*/
void McuSendByte(uchar *PTemp,uchar num)
{   uchar i,j,m;
	for(i=0;i<num;i++) 
  	  {   m=0x80;
  	      FLASH_SCK=0;
  		  for(j=0;j<8;j++)
  		  { _nop_();					//td9>2u
            _nop_();
            //_nop_();
  		    if (m&PTemp[i]) FLASH_MOSI=1;
  		    else FLASH_MOSI=0;
  		    FLASH_SCK=1;
  		    _nop_();					//td9>2u
            _nop_();
            //_nop_();
      	        FLASH_SCK=0;
      	        m=m>>1;
  	      }  
  	  }
}
/*--------------------------------------------------
函数名: void McuFlashReset()
功能: FLASH芯片复位,允许在线编程
*/
void McuFlashReset()
{  uchar PTemp[4];
   FLASH_RST=0;
   Delay(2);
   
   PTemp[0]=0xac;
   PTemp[1]=0x53;
   PTemp[3]=0x00;
   McuSendByte(PTemp,4);
   
}
//--------------------------------------------------
/*
函数名: void McuFlashWrite(uchar cData,uint iAddr)
功能: 写一字节到Flash 
返值: 无
入口参数说明:
    cData:编程数据
    iAddr:编程地址
*/
void McuFlashWrite(uchar cData,uint iAddr)
{  uchar PTemp[4];
   
   PTemp[0]=0x40;
   PTemp[1]=iAddr/0x100;
   PTemp[2]=iAddr&0x00ff;
   PTemp[3]=cData;
   McuSendByte(PTemp,4); 	           
} 
//--------------------------------------------------
/*
函数名: uchar McuFlashRead(uint iAddr)
功能: 从Flash读取一字节 
返值: 读出数据
入口参数说明:
    iAddr:数据地址
*/
/*uchar McuFlashRead(uint iAddr)
{  uchar PTemp[4],cData,i,m;
   
   PTemp[0]=0x20;
   PTemp[1]=iAddr/0x100;
   PTemp[2]=iAddr&0x00ff;
   McuSendByte(PTemp,3);
   
   cData=0;
   m=0x80;
   for(i=0;i<8;i++)
     {
     	_nop_();					//td9>2u
        _nop_();
        FLASH_SCK=1;
        if (FLASH_MISO) cData=cData|m;
        _nop_();					//td9>2u
        _nop_();
        FLASH_SCK=0;
        m=m>>1;
     } 
   return cData;
} 
//--------------------------------------------------*/
/*
函数名: void McuSectorEraser)
功能: FLASH Sector擦除
返值: 无
入口参数说明:
    iSectorAddr:Sector地址
*/
void McuSectorErase()
{ uchar PTemp[4];
   
   PTemp[0]=0xac;
   PTemp[1]=0x80;
   McuSendByte(PTemp,4); 	 
}
//*****************************************************************************
//24C64 底层驱动
//*****************************************************************************
//------24c64-----------------------------------------------------
void I2cAck(uchar cType)
{  
    I2C_DATA=cType;		//
    I2C_CLK=1;
    _nop_();
    cType++;   //nop
    I2C_CLK=0;
    I2C_DATA=1;	
    cType--;   //nop
    _nop_();
}
//----------------------------------------------------------------
void I2cStart(void)
{ uchar i;
    I2C_DATA=1;
    I2C_CLK=1; 
    i=0;     //NOP(); 
    _nop_();
    I2C_DATA=0;	
    i++;     //NOP(); 
    _nop_();
    I2C_CLK=0;
    i--;     //NOP(); 
    _nop_();
}
//----------------------------------------------------------------
void I2cStop(void)
{ uchar i; 
    I2C_DATA=0;
    I2C_CLK=1;
    i=0;  //
    _nop_();
    I2C_DATA=1;
    i++;  //
    _nop_();
    I2C_CLK=0;
    i--;  //
    _nop_();
}
//----------------------------------------------------------------
void I2cWriteByte(uchar cData)
{ uchar m,i;
   m=0x80;
   for(i=0;i<8;i++)	
    	{  if(m&cData) I2C_DATA=1;
           else I2C_DATA=0;
    	    I2C_CLK=1;
    	    i++;  //NOP();
    	    _nop_();
    	    I2C_CLK=0;
    	    i--;  //NOP();
    	    _nop_();
    	    m=m>>1;
    	}
}
//----------------------------------------------------------------
uchar I2cReadByte(void)
{  uchar cData,m,i;

    m=0x80;
    cData=0;
    for(i=0;i<8;i++)	
    	{   I2C_CLK=1;
    	    i++;    //NOP();
    	    _nop_();
    	    if(I2C_DATA) cData=cData|m;
    	    I2C_CLK=0;
    	    i--;    //NOP();
    	    _nop_();
    	    m=m>>1;
    	}
    return cData;
}   
//----------------------------------------------------------------
/*
函数名:void I2cReadData(uint iDataAddress,uchar *pBuf,uint iDataByte)
功能: 从I2c器件读取数据(不能跨器件)
返值:读取的数据
入口参数说明: 
		iDataAddress:数据地址
		pBuf:数据缓冲区
		iDataByte:读取的字节数
		cDeviceAddr:器件地址
		
使用的全局变量:无
*/
uchar I2cReadData(uint iDataAddress,uchar *pBuf,uint iDataByte,uchar cDeviceAddr)
{
    uchar cAddr;
    uint i;
    
    I2cStart();
    I2cWriteByte(cDeviceAddr);		//写器件写地址
    I2cAck(0);				//ACK
    cAddr=(uchar)(iDataAddress>>8);
    I2cWriteByte(cAddr);		//写数据地址1
    I2cAck(0);				//ACK
    cAddr=(uchar)(iDataAddress&0x00ff);
    I2cWriteByte(cAddr);		//写数据地址2
    I2cAck(0);				//ACK
    
    I2cStart();
    I2cWriteByte(cDeviceAddr+1);	//器件读地址
    				
    for(i=0;i<iDataByte;i++)
    { I2cAck(0);			//ACK
      pBuf[i] = I2cReadByte();
    }
    
    I2cAck(1);
    I2cStop();
    return 0;
}
//--------------------------------------------------------------------
/*
函数名: uchar MoveCardData()
功能: 写卡数据到CPU FLASH
返值: 	
	1:正常结束
	0:校验错结束
*/
uchar MoveCardData()
{   uchar cR,pBuff[4];
    uint  iChipAddr,i;
    
    McuFlashReset();
//~~~~~~~~~~~~~~~~~~~~~~~~~~
    McuSectorErase();						//擦除芯片
    Delay(40);
//~~~~~~~~~~~~~~~~~~~~~~~~~~
//将24c256中的数据单字节方式写入FLASH
//~~~~~~~~~~~~~~~~~~~~~~~~~~    
    I2cReadData(17,pBuff,4,0xa0);
    LoadData.iCodeLenth=pBuff[0]*0x100+pBuff[1];
    LoadData.iCheckSumCard=pBuff[2]*0x100+pBuff[3];
    
    for(i=0;i<LoadData.iCodeLenth;i++)
      { iChipAddr=0x80+LoadData.iReadLenth;			//卡片内地址
        I2cReadData(iChipAddr,pBuff,1,0xa0);			//读数据	
      	
        McuFlashWrite(pBuff[0],LoadData.iReadLenth);
        LoadData.iReadLenth++;
      }  
//~~~~~~~~~~~~~~~~~~~~~~~~~~ 
//校验写是否正确
//~~~~~~~~~~~~~~~~~~~~~~~~~~     
    cR=1;
    /*
    for(i=0;i<LoadData.iCodeLenth;i++) 	
      {  pBuff[0]=McuFlashRead(LoadData.iReadLenth);
         LoadData.iCalCheckSum=LoadData.iCalCheckSum+(0xff-pBuff[0]);
         LoadData.iReadLenth++;
      }
    LoadData.iCalCheckSum=0x10000-LoadData.iCalCheckSum;
    if(LoadData.iCalCheckSum==LoadData.iCheckSumCard) cR=1; */ 
    return cR;
} 
//--------------------------------------------
/*
函数名: uchar CheckDataValid()
功能: 判断数据标识是否正确
返值: 	0-不正确
	1-正确 
入口参数说明:
*/
uchar CheckDataValid()
{
  uchar i,cR,pBuff[16];
  
  cR=1;
  I2cReadData(0,pBuff,16,0xa0);					//读标识区
  for(i=0;i<16;i++) if(DataValid[i]==0||pBuff[i]!=DataValid[i]) break;	//鉴别数据合法性
  if(DataValid[i]!=0) cR=0;	
  	
  return cR;	
} 		        
//********************************************************************************************
//LED指示灯显示(1、长闪,数据错误;2、不亮,等待;3、长亮,数据写完;4、短闪,正在写数据)
//********************************************************************************************
void LedDisp(uchar LedType)
{    switch(LedType)
	{
	   case 1:
	       if(LoadData.Second) 
	       {  FLASH_LED=~FLASH_LED;
                  LoadData.Second=0;      	       
      	       }
      	       break;
	   case 2:
	       FLASH_LED=1;  
	       break;
	   case 3:
	       FLASH_LED=0; 
	       break;
	   case 4:
	       if(LoadData.HalfSec) 
	       {  FLASH_LED=~FLASH_LED;
                  LoadData.HalfSec=0;      	       
      	       }
	       break;	
	}	
}
//*******************************************************************************
//主流程控制程序
//******************************************************************************* 
/*
函数名:void MainPro()
功能: 主流程处理程序,完成各状态间的切换
返值: 无
入口参数说明:无
使用的全局变量:
*/
void MainPro()
{ 
  uchar n;
  Delay(30);
  g_bFirstEntry=0;
  if(CheckDataValid()==0) 
    { while(1) LedDisp(1);						//卡数据非法
    }
  else 
    { while(1)
      {   
          if(!g_bFirstEntry)
          {  DispType=2;						//等待
             if(LoadData.Key) 
              {  LoadData.Status=1;
                 g_bFirstEntry=1;
                 LoadData.Key=0;
              }
          }
          else
          {  switch(LoadData.Status)
                {   case 1:
                       DispType=4;              //正在写数据
                       LoadData.iReadLenth=0;  
    		       LoadData.iCalCheckSum=0;
                       n=MoveCardData();
                       if(n) LoadData.Status=2;
                       else  LoadData.Status=3;
                       break;
                    case 2:
                       DispType=3;		       	//写数据结束
                       Delay(400);
                       FLASH_RST=0;	
                       g_bFirstEntry=0;
                       break;
                    case 3:   
                       DispType=1;	            //写FLSAH错误
                       Delay(800);
                       FLASH_RST=1;	
                       g_bFirstEntry=0;
                       break;
                   default:
                       break;       
                }	
         
          }
      }
   }  
} 	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -