📄 p532flash.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 + -