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

📄 download.c

📁 对W29c040读写程序
💻 C
字号:
#include <reg52.h>
//#include "upsd3300.h"
//#include "PSD_Register.h"

#include "ext_var.h"
#include "SerialPort.h"
#include "w29c040drv.h"
#include "download.h"

#include <stdio.h>
#include <string.h>


//串口接收结构
typedef struct
{
	uchar Finish; 				//设定未接收完毕
	uint  Len;					//已接收长度
	uint  CmdLen;				//命令总长度
	uchar Buffer[128+1];		//接收缓冲区
	uchar Data[PAGE_SIZE+1];	//页数据
	int   DataLen;				//页数据长度
}RS232_REC;

//文件信息结构
typedef struct
{
	uint  Pages;		//总共要写页数
	uint  Addr;			//写入起始地址
}FILE;


static RS232_REC Rec;	//串口接收
static FILE File;	//文件信息

/**********************************************************************
* 函 数 名: InitRec
* 功能描述: 初始化接收相关变量
* 函数说明: 
* 调用函数: 
* 全局变量:	
* 输    入: 无
* 返    回: 无
* 设 计 者: wangyong                         日期:2007-03-24
* 修 改 者: wangyong                         日期:2007-03-30
* 版    本: WTFISCAL04 KEYBOARDV1.0D100
**********************************************************************/
void InitRec( void )
{
	Rec.Finish=FALSE; //设定未接收完毕
	Rec.Len=0;	//已接收长度
	Rec.CmdLen=0; //PC发给下位机的命令的总长度
	Rec.DataLen=0;	//页数据长度
}

/**********************************************************************
* 函 数 名: SendCmdStr
* 功能描述: 向PC发送命令字串
* 函数说明: 
* 调用函数: 
* 全局变量:	
* 输    入: Cmd--命令字串
			Len--命令字串长度
* 返    回: 无
* 设 计 者: wangyong                         日期:2007-03-25
* 修 改 者: wangyong                         日期:2007-03-30
* 版    本: WTFISCAL04 KEYBOARDV1.0D100
**********************************************************************/
void SendCmdStr(uchar *Cmd,uint Len)
{
	
	uchar CS;
	uchar cmdstr[20];
	uint  i;
	uint  cmdlen;


	//命令头
	cmdstr[0]=0x55;
	cmdstr[1]=0xAA;

	//LH + LL + /LH + /LL + CMD + DATA + CS相加的长度(除命令头外)
	cmdlen=5+Len;

	//长度
	cmdstr[2]=cmdlen/256;
	cmdstr[3]=cmdlen%256;

	//长度取反
	cmdstr[4]=~cmdstr[2];
	cmdstr[5]=~cmdstr[3];

	//保存命令字
	//cmdstr[6]=Cmd;
	memcpy(cmdstr+6,Cmd,Len);

	//计算出抑或校验和CS
	//cmdlen+1为完整命令长度减去CS长度(1字节)
	CS=cmdstr[0];
	for(i=1;i<cmdlen+1;i++)
	{
		CS=CS^cmdstr[i];
	}
	cmdstr[6+Len]=CS;

	//串口发送命令
	//cmdlen+2为完整命令长度
	for(i=0;i<cmdlen+2;i++)
	{
		SerialPort_send(cmdstr[i]);
	}
}

/**********************************************************************
* 函 数 名: VerifyCmdStr
* 功能描述: 验证命令串合法性并解析出命令字,数据,数据长度
* 函数说明: 
* 调用函数: 无
* 全局变量:
* 输    入: *Cmd--命令字
			*DataLen--数据长度
* 返    回: TRUE--通过合法性
			FALSE--未通过合法性
* 设 计 者: wangyong                         日期:2007-03-25
* 修 改 者: wangyong                         日期:2007-03-25
* 版    本: 
**********************************************************************/
bool VerifyCmdStr(uchar *Cmd,uint *DataLen)
{
	uchar CS;
	uint  i;
	
	//命令头错误
	if(Rec.Buffer[0]!=0x55 || Rec.Buffer[1]!=0xaa) return FALSE;

	//判断cs是否正确
	CS=Rec.Buffer[0];

	//计算异或和
	for(i=1;i<Rec.Len-1;i++)
	{
		CS=CS^Rec.Buffer[i];
	}

	//校验位出错
	if(CS!=Rec.Buffer[Rec.Len-1]) return FALSE;

	//得到命令字
	*Cmd=Rec.Buffer[6];

	//数据长度
	*DataLen=(Rec.Buffer[2]*256+Rec.Buffer[3])-5;

	return TRUE;
}

/**********************************************************************
* 函 数 名: Download
* 功能描述: 下载处理
* 函数说明: 
* 调用函数: 无
* 全局变量:
* 输    入: 无
* 返    回: 无
* 设 计 者: wangyong                         日期:2007-03-24
* 修 改 者: wangyong                         日期:2007-03-24
* 版    本: 
**********************************************************************/
void Download( void )
{
	uchar Cmd; //命令字
	uint  DataLen;  //数据长度
	uint  TempLen;
	bool  CommOk; //命令通讯状态
	//uint i;

	//串口初始化
	SerialPort_init();

restart:

	//初始化串口接收结构体
	InitRec();

	//通讯状态
	CommOk=FALSE;

	while(1)
	{
		//命令接收完毕
		if(Rec.Finish)
		{
			//验证命令合法性
			if(!VerifyCmdStr(&Cmd,&DataLen))
			{
				Cmd=0x0f;
				SendCmdStr(&Cmd,1);
				goto restart;
			}

			//通讯状态
			CommOk=FALSE;

			//解析命令
			switch(Cmd)
			{
				case 0x5a:	//握手通讯
	
					//返回握手成功的命令
					SendCmdStr(&Cmd,1);
					CommOk=TRUE;
					break;
	
				case 0x04:	//发送文件页数

					//文件页数
					File.Pages=Rec.Buffer[7]*256+Rec.Buffer[8];

					SendCmdStr(&Cmd,1);
					CommOk=TRUE;
					break;

				case 0x05:	//发送起始地址

					//写入的起始地址
					File.Addr=Rec.Buffer[7]*256+Rec.Buffer[8];

					//返回OK
					SendCmdStr(&Cmd,1);

					CommOk=TRUE;

					break;

				case 0x06:	//下载文件数据

					//本次接收的数据长度, 6是 LH,LL,/LH,/LL,CMD,CS的长度
					TempLen = Rec.Buffer[2]*256+Rec.Buffer[3]-6;

					//暂存数据
					memcpy(Rec.Data+Rec.DataLen,Rec.Buffer+7,TempLen);

					//长度增加
					Rec.DataLen+=TempLen;

					//达到256字节
					if(Rec.DataLen>=PAGE_SIZE)
					{
					/* //测试文件接收256字节后自动向PC发送256字节
						SerialPort_send(0xdd);
						SerialPort_send(0xdd);
						SerialPort_send(0xdd);
						SerialPort_send(0xdd);
						for(i=0;i<Rec.DataLen;i++)
						{
							SerialPort_send(Rec.Data[i]);
						}

						i=0;

						if(i==0) while(1);
					*/

						//写到W29C040存储器
						if(!WritePage(0,0,0,Rec.Data))
						{
							//发送出错命令
							Cmd=0x0f;
							SendCmdStr(&Cmd,1);

							//重新开始接收
							goto restart;
						}
						else //页写flash成功
						{
							Rec.DataLen=0; //数据长度清0
						}
					}

					//发送下载成功命令
					SendCmdStr(&Cmd,1);

					CommOk=TRUE;

					break;

				case 0x07:	//下载完成

					SendCmdStr(&Cmd,1);

					CommOk=TRUE;

					break;

				default:  //错误

					//发送出错命令
					Cmd=0x0f;
					SendCmdStr(&Cmd,1);

					//重新开始接收
					goto restart;

					break;
			}
		
			//命令接收正常
			if(CommOk)
			{
				Rec.Finish=FALSE; 	//设定未接收完毕
				Rec.Len=0;			//已接收长度
				Rec.CmdLen=0; 		//PC发给下位机的命令的总长度
			}
		}
	}
}

/**********************************************************************
* 函 数 名: serial1
* 功能描述: 串口1中断处理
* 函数说明: 
* 调用函数: 无
* 全局变量:
* 输    入: 无
* 返    回: 无
* 设 计 者: wangyong                         日期:2007-03-24
* 修 改 者: wangyong                         日期:2007-03-24
* 版    本: 
**********************************************************************/
void serial1() interrupt 4
{
	//接收
	if(RI)
	{
		RI=0;

		//还没接完
		if(!Rec.Finish)
		{
			//放入数据
			Rec.Buffer[Rec.Len++]=SBUF;

			//若已接收了4个字节,则可以算出
			//整个命令串的总长度
			if(Rec.Len==4)
			{
				Rec.CmdLen=(uint)(Rec.Buffer[2]*16+Rec.Buffer[3])+2; //命令总长度
			}
			else if(Rec.Len>4) //判断是否全部接收完命令
			{
				//已接收完,做标志
				if(Rec.Len==Rec.CmdLen) Rec.Finish=TRUE;
			}
		}
	}
}

⌨️ 快捷键说明

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