📄 at45main.c
字号:
//
//.................................................
void Uart0() interrupt 4
{
BYTE cRecvData;
if(RI0) // 如果收到数据
{
RI0=0; // 清除收到数据标志
cRecvData = SBUF0; // 读取数据
SBUF0 = cRecvData; // 回显
if(cRecvData=='\r')
{// 回车符作为结束标志
g_cRecvBuffer[g_cRecvPointer]=0; // 接收结束
g_cRecvPointer = 0;
g_cMainSignal|=UART0RECV_SIGNAL; // 接收完成信号
}
else if(cRecvData==0x08)
{// CTRL+H控制键,退格
if(g_cRecvPointer>0) g_cRecvPointer--;
}
else
{
if(g_cRecvPointer<RECVBUF_LEN)
{
/*
// 检查是否有数据需要转换为小写
if(isupper(cRecvData))
{// 大写字符转换为小写
cRecvData = _tolower(cRecvData);
}
*/
g_cRecvBuffer[g_cRecvPointer++]=cRecvData;
}
else
{// 数据长度错误
g_cRecvPointer = 0;
}
}
}
if(TI0) // 如果数据发送结束
{
TI0=0;
}
}
//------------------------------------------------------------------
// 主函数开始
//-------------------------------------------------------------------
void main()
{
BYTE nDeviceID;
Init_Device(); // 初始化系统
InitVariable(); // 初始化变量
EA=0; // 禁止看门狗
WDTCN = 0xDE; // 实验中不使用看门狗
WDTCN = 0xAD;
EA = 1; // 打开中断控制位
TR0 = 1; // 启动定时器0
SendString("C8051F02x core Module EC1,v1.0\r\n");
SendString("Serial Flash Test\r\n");
//////////////////////////////////////////////////
// 检查Flash
/////////////////////////////////////////////////
SendString("Flash ID:");
SendString(GetFlashType());
SendString("\r\n");
////////////////////////////////////////////////
while(1)
{
if(g_cMainSignal&SECD_SIGNAL)
{// 秒信号
g_cMainSignal&=~SECD_SIGNAL;
P_LED2 = !P_LED2;
}
if(g_cMainSignal&MINU_SIGNAL)
{// 分信号
g_cMainSignal&=~MINU_SIGNAL;
}
if(g_cMainSignal&UART0RECV_SIGNAL)
{// UART0接收完成信号
g_cMainSignal&=~UART0RECV_SIGNAL;
// 确保接收缓冲区内的字符串有结尾
g_cRecvBuffer[RECVBUF_LEN-1] = 0;
// 分析接收的命令
CommandProc(g_cRecvBuffer);
}
}
}
//------------------------------------------------------------------
// 功能:分析接收的串口命令
// 输入参数:pRecvString,char *:输入字符串
// 输出参数:无
//..................................................................
void CommandProc(char *pRecvString)
{
BYTE cRet=0;
int iPos,iPage,i;
// 使用strncmps进行不区分大小写的比较
if(strncmps("setled=",pRecvString,7)==0)
{// 设置LED状态命令
pRecvString+=7;
iPos=strpos(pRecvString,',');
if(iPos==-1)
{// 无效命令
cRet = 0;
}
else
{
if(strncmps(pRecvString,"2",1)==0)
{// 控制LED2
pRecvString+=2;
if(strncmps(pRecvString,"on",2)==0)
{// 打开LED
P_LED2 = 1;
cRet = 1;
}
else if(strncmps(pRecvString,"off",3)==0)
{// 关闭LED
P_LED2 = 0;
cRet = 1;
}
else
{
cRet = 0;
}
}
}
}
else if(strncmps(pRecvString,"erasepage=",10)==0)
{// 擦除指定扇区
pRecvString+=10;
iPage = atoi(pRecvString);
cRet=FlashPageErase(iPage);
}
else if(strncmps(pRecvString,"eraseblock=",11)==0)
{// 擦除指定块
pRecvString+=11;
iPage = atoi(pRecvString);
cRet=FlashBlockErase(iPage);
}
else if(strncmps(pRecvString,"writepage=",10)==0)
{// 写入Flash
pRecvString+=10;
iPos=strpos(pRecvString,',');
if(iPos==-1) cRet=0;
else
{// 查找扇区
pRecvString[iPos]=0;
iPage = atoi(pRecvString);
if(pRecvString[iPos+1]!=0)
{
pRecvString+=iPos+1;
// 通过Buffer1直接将数据写入到页面中,因此,除用户本次传送过来的数据外
// 其它写入PAGE中的内容由BUFFER1中原来的内容决定
cRet=FlashProgViaBuffer1(0,strlen(pRecvString),pRecvString,iPage);
// 注释的部分通过先将数据写入Buffer,然后用命令将数据写入到主存的方法
//FlashBuffer1Write(0,strlen(pRecvString),pRecvString);
//FlashBuffer1ProgAutoErase(iPage);
}
else
{
cRet = 0;
}
}
}
else if(strncmps(pRecvString,"readpage=",9)==0)
{// 读出一个扇区的指定内容
pRecvString+=9;
iPage = atoi(pRecvString);
// 数据首先读取到buffer1,然后从buffer1中读出
if(PageToBuffer1(iPage)==1)
{
// AT45DB041,081的页面为256+8B
// AT45DB161的页面为512+16B
cRet=FlashBuffer1Read(0,264,g_cFlashReadBuffer);
g_cFlashReadBuffer[264]=0;
}
else cRet = 0;
if(cRet==1)
{
// 扇区内容传送到计算机
SendString("\r\nHex Value:\r\n");
for(i=0;i<254;i++)
{
SendHex(g_cFlashReadBuffer[i]);
SendString("(");
SendBuffer(&g_cFlashReadBuffer[i],1);
SendString(")");
SendString(" ");
}
}
}
else
{// 无效命令
cRet = 0;
}
// 向主机发送应答
if(cRet)
{
SendString("\r\nOK\r\n");
}
else
{
SendString("\r\nError\r\n");
}
}
//-----------------------------------------------------
// 函数功能:循环方式发送字符串
// 输出参数:pSendString,char*:欲发送的字符串的缓冲区
// 输出:无
//-----------------------------------------------------
void SendString(char *pSendString)
{
// 循环发送,首先关闭中断
ES0 =0;
while(*pSendString!=0)
{
SBUF0 = *pSendString++;
while(TI0==0);
TI0=0;
}
ES0 = 1;
}
void SendBuffer(BYTE *pSend,WORD len)
{
// 循环发送,首先关闭中断
ES0 =0;
while(len)
{
SBUF0 = *pSend++;
while(TI0==0);
TI0=0;
len--;
}
ES0 = 1;
}
void SendHex(BYTE buf)
{
ES0 = 0;
SBUF0 = ASCII_CODE[(buf>>4)&0x0F];
while(TI0==0){}
TI0 = 0;
SBUF0 = ASCII_CODE[(buf&0x0F)];
while(TI0==0){}
TI0 = 0;
ES0 = 1;
}
//---------------------------------------------------------
// 软件延时函数
//---------------------------------------------------------
// ;时钟周期数
// lcall ;4
void dly(BYTE cnt){while(cnt){cnt--;}} // delay: mov a,r7 ;1
// jz quit ;2
// dec r7 ;1
// sjmp delay ;2
// quit: ret ;1
// 6n+5 sysclk @c8051f022(0.5425)
// 延时(6n+5)*0.0904us @11.0592MHZ
//....................................................................................
// 延时ms毫秒
//....................................................................................
void Dlyms(WORD ms) // 延时cnt(ms)@11.0592MHZ
{
while(ms)
{
dly(250);
dly(210);
dly(250);
dly(210);
dly(250);
dly(210);
dly(250);
dly(210);
dly(250);
dly(210);
dly(250);
dly(210);
dly(250);
dly(210);
dly(250);
dly(210);
ms--;
}
}
//----------------------------------------------------------
// 功能:不区分大小写的字符串比较函数
// 参数:pString1,char*:字符串1
// pString2,char*:字符串2
// iLen,int:长度
// 返回值:-1:字符串相同;0:字符串不同
//-----------------------------------------------------------
char strncmps(char *pString1,char *pString2,int iLen)
{
char cTemp;
int i;
if(strlen(pString1)<iLen) return -1;
if(strlen(pString2)<iLen) return -1;
for(i=0;i<iLen;i++)
{
cTemp = pString1[i];
if(cTemp!=pString2[i])
{
if((cTemp>='A')&&(cTemp<='Z'))
{
cTemp = cTemp-'A'+'a';
if(cTemp!=pString2[i]) return -1;
}
else if((cTemp>='a')&&(cTemp<='z'))
{
cTemp = cTemp-'a'+'A';
if(cTemp!=pString2[i]) return -1;
}
else return -1;
}
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -