单片机源程序下载(7)——51单片机操作U盘文件和目录(C51)
推荐给好友
打印
加入收藏
更新于2010-12-03 21:38:47

单片机操作U盘文件和目录(C51

  

//K5-1.c

//该程序的功能是通过控制芯片CH376U盘文件和目录进行操作

//在单片机系统中使用U,主要目的是长期保存大批量的文件数据,并方便与PC机进行数据交换

//在一般情况下,这些数据会转移到PC,并由它做进一步的后续处理

//所以该实验安排了以下的硬件环境:51实验主板+keil仿真器+CH376读写U盘扩展板

//在该扩展板上还安排有转接PCUSB口的电缆接口和切换开关

//系统所用CH376SSOP20封装的CH376T,与单片机的通信采用软件模拟SPI,系统时钟为11.0592MHz,

//该程序首先对CH376按主机工作方式进行初始化,然后等待U盘的插入和就绪

//此后,用户可通过按键以字节操作方式(另一种为扇区操作方式)实现以下功能

//K1--打开或创建1级子目录/20yy,修改它的生成日期和时间,然后关闭

//K2--在前一操作的基础上,打开或创建2级子目录/20yy/mm-dd,修改它的生成日期和时间,然后关闭

//K3--2级子目录下打开或创建文本文件DEMO1.TXT,追加模拟数据块,修改目录项后关文件

//K4--1:1级子目录下创建二进制文件DEMO2.DAT,写入18B20测温数据2B和读1302得到的时间数据6B

//修改目录项后关文件;2:再次打开该文件,读取文件中的8B数据,先显示十六进制原始数据

//经处理后再显示实际的温度,年月日和时分秒

//若程序运行出错(如中途拔出U),它就会进入一个出错处理的死循环,此时实验主板上的8个红色LED会不断闪烁

//注意程序中的C函数分别来自本书作者(函数名全部小写)和沁恒公司(函数名大小写并用)

//由沁恒公司提供的源代码以文件包含的形式被利用,其中

//1,文件SPI_SW.CHAL_BASE.C中的一些源码要根据系统的具体硬件连接和时钟频率进行修改

//2,文件DEBUG.C中的源码用于系统出错指示和调试时能通过串口来输出调试信息,一般也要适当修改

//3,文件FILE_SYS.C中的源码不会全部用到,对那些没有用到C函数最后应进行清理(一般是将它们注释掉)

//该程序在运行中会输出较多的调试信息,注意它们将显示在串口窗口#1,这些信息与输出到文件中的数据不是一回事

//还要注意程序对文件DEMO1.TXTDEMO2.DAT的操作有以下不同

//1,文件打开方式不同:前者是打开文件,若原先没有则创建;后者是创建文件,若原先有将抹去重建

//2,数据表示形式不同:前者是写入文本,并以逗号来间隔数据,以回车换行来结束记录;后者是直接写入原始数据

//3,数据写入方式不同:前者是追加数据到文件尾;后者是从头写入数据,所以原有数据将被覆盖

//Program Size: data=121.2 xdata=0 code=7411

//以下头文件由uVision提供,存于系统子目录

#include <reg52.h>

#include <stdio.h>

#include <string.h>

#include <intrins.h>

#include <absacc.h>

//以下文件由沁恒公司提供,存于当前项目,有些经过修改

#include "CH376INC.H"                               //说明操作CH376需要用到的数据和数据结构

#include "HAL.H"                                    //说明软件延时函数

#include "HAL_BASE.C"                               //经修改,内含2个软件延时函数

#include "SPI_SW.C"                                //经修改,内含软件模拟SPI需要用到的一批函数

#include "DEBUG.H"                                  //说明系统出错处理和UART串口初始化函数

#include "DEBUG.C"                                  //经修改,内含出错处理和UART串口初始化函数

#define EN_DIR_CREATE 1                            //允许新建多级子目录

#include "FILE_SYS.H"                              //说明一批文件目录操作类的函数和数据

#include "FILE_SYS.C"                              //内含一批文件目录操作类的函数

 

#define uchar unsigned char

#define uint unsigned int

#define ON 0

#define OFF 1

#define  FILE_MODIFY 0

#define FILE_CREATE    1

#define RST_1302 A15=0;A14=A13=1;                  //1302复位有效

#define NRST_1302 A15=A14=A13=0;                   //1302复位无效

#define skiprom_cmd1820(); wr_byte1820(0xcc);      //跳过ROM操作(不识别芯片)

#define convert_cmd1820(); wr_byte1820(0x44);      //启动测温转换

#define wrscrat_cmd1820(); wr_byte1820(0x4e);      //拟写高速暂存

#define rdscrat_cmd1820(); wr_byte1820(0xbe);      //拟读高速暂存

#define copyscrat_cmd1820(); wr_byte1820(0x48);    //将高速暂存复制到EERAM保存

sbit BEEP=P1^3;                                    //蜂鸣器控制端

sbit DQ_1820=P1^0;                                 //18B20DQ

sbit DIO_1302=P1^1;                                //1302DIO

sbit CLK_1302=P1^2;                                //1302CLK

sbit DAT_164=P3^4;                                  //74HC164串入端DAT

sbit CLK_164=P3^5;                                 //74HC164时钟端CLK

uchar time[7]={0,0,8,1,4,4,0x10};                  //初始时间设为2010418:00:00星期4

uchar disbuf[6];                                   //数码管显示缓冲区

uchar keyvalue;                                     //存按键键值

bit KEY_FLG;                                       //键按下标志

union                                               //利用该结构来分离测温数据中的高/8

{ int i;

  uchar c[2];

}temp;                                              //拟存温度数据volatile

uchar idata buf[52],buf1[6];                       //文件操作时作数据缓冲区使用

uint fdate,fclk;                                    //修改目录项中时间数据时使用

uint len;                                          //保存读文件数据块时实际读到的数据长度

uchar s;                                           //保存CH376的操作状态或出错代码

uchar i;                                            //循环控制用

uchar code seg[]={                                 //七段码表

0x3f,0x06,0x5b,0x4f,0x66,                          //0~4

0x6d,0x7d,0x07,0x7f,0x6f,                          //5~9

0x77,0x7c,0x39,0x5e,0x79,                          //A~E

0x71,0x40,0x46,0x00,0x76,                          //F,-,-1,全灭

0xbf,0x86,0xdb,0xcf,0xe6,                          //0.~4.

0xed,0xfd,0x87,0xff,0xef                           //5.~9.

};

void delay_10us(uchar n)                            //10微秒级延时

{ do

  { _nop_();

    _nop_();

    _nop_();

    _nop_();

    _nop_();

  }while(--n);

}

void delay_ms(uint n)                              //毫秒级延时

{ do delay_10us(131);

  while(--n);

}

void sendchar(uchar ch)                            //向数码管送1位显示数码

{ uchar i;

  for(i=0;i<8;i++)

  { DAT_164=ch&0x01;

    CLK_164=0;

    CLK_164=1;

    ch>>=1;

  }

}

void display()                                      //将显示缓冲区数据送数码管显示

{ uchar i;

  for(i=0;i<6;i++) sendchar(seg[disbuf[i]]);

}

void wr_byte1302(uchar dat)                        //底层函数,1B1302

{ uchar i;

  for(i=8;i>0;i--)

  { DIO_1302=dat&0x01;

    CLK_1302=1;

    CLK_1302=0;

    dat>>=1;

  }

}

uchar rd_byte1302()                                 //底层函数,13021B

{ uchar i,dat=0;

  for(i=8;i>0;i--)

  { dat>>=1;

    if(DIO_1302) dat|=0x80;

    CLK_1302=1;

    CLK_1302=0;

  }

  return(dat);

}

void wr_addr_byte1302(uchar addr, uchar dat)       //向指定地址写单字节数据

{ RST_1302                                          //复位1302

  CLK_1302=0;

  NRST_1302

  wr_byte1302(addr);                                //写地址/命令

  wr_byte1302(dat);                                 //写数据

  CLK_1302=1;

  RST_1302                                          //复位1302

}

void wr_time_burst1302(uchar *ptr)                 //突发方式写1302时钟,ptr为写数据指针

{ uchar i;

  wr_addr_byte1302(0x8e,0x00);                      //去写保护

  RST_1302                                          //复位1302

  CLK_1302=0;

  NRST_1302

  wr_byte1302(0xbe);                                //0xbe为突发写时钟命令

  for(i=7;i>0;i--)                                  //7B时钟

  { wr_byte1302(*ptr);                              //1B数据

    ptr++;

  }

  wr_byte1302(0x80);                                //加写保护

  CLK_1302=1;

  RST_1302                                          //复位1302

}

void rd_time_burst1302(uchar *ptr)                 //突发方式读1302时钟,ptr读数据指针

{ uchar i;

  RST_1302                                          //复位1302

  CLK_1302=0;

  NRST_1302

  wr_byte1302(0xbf);                                //0xbf为突发读时钟命令

  for(i=7;i>0;i--)

  { *ptr=rd_byte1302();                             //1B数据

    ptr++;

  }

  RST_1302                                          //复位1302

}

void reset_1820()                                  //复位18B20

{ DQ_1820=0;

  delay_10us(60);                                   //延时约500us(要求>480us)

  DQ_1820=1;                                        //主机上拉DQ_1820

  delay_10us(7);                                    //延时约60uS

  while(!DQ_1820);                                  //18B20送出0

}

void wr_byte1820(uchar dat)                         //18B20

{ uchar i;

  for(i=0;i<8;i++)                                  //依次发送8位数据

  { DQ_1820=0;

    delay_10us(2);                                  //延时约20us

    DQ_1820=dat&0x01;

    dat>>=1;

    delay_10us(7);                                  //延时约60us

    DQ_1820=1;                                      //主机上拉DQ_1820

  }

}

uchar rd_byte1820()                                //18B20

{ uchar i,dat=0;

  for(i=0;i<8;i++)                                  //依次接收8位数据

  { dat>>=1;

    DQ_1820=0;                                      //主机下拉DQ_1820

    DQ_1820=1;                                      //主机上拉DQ_1820

    if(DQ_1820) dat|=0x80;

    delay_10us(7);                                  //满足延时要求58us

  }

  return dat;

}

void res1820_to_disbuf()                            //处理转换结果并送显示缓冲区

{ uchar i;

  uchar tint;                                       //用它处理温度数据的整数部分

  uint tdec;                                        //用它处理温度数据的小数部分

  disbuf[0]=18;                                    //正数时显示空格

  if(temp.i<0)

  { disbuf[0]=16;                                   //显示"-"

    temp.i=-temp.i;                                 //负数取绝对值

  }

  tint=temp.i>>4;                                   //右移4位后得8位整数(折合3位十进制)

  disbuf[1]=tint/100;                               //取百位上数据

  disbuf[2]=tint/10%10;                             //取十位上数据

  disbuf[3]=tint%10+20;                             //取个位上数据并加小数点

  i=1;                                             //消隐数码显示前导0

  while(disbuf[i]==0) disbuf[i++]=18;

  tdec=temp.c[1]&0x0f;                              //4位小数,最低位权重=0.0625

  tdec=tdec*625+50;                                //小数作整数处理避免浮点运算(保留2位小数)

  disbuf[4]=tdec/1000;                              //取十分之一位数据

  disbuf[5]=tdec/100%10;                            //取百分之一位数据

}

void key_prc()                                     //按键处理

{ uchar key;

  key=XBYTE[0x2000];                                //读键盘口

  if(key!=0xff)                                    //有按键

  { BEEP=ON;                                        //延时去抖,蜂鸣器鸣响

    delay_ms(10);

    BEEP=OFF;

    KEY_FLG=1;                                      //设置标志

    if((key=XBYTE[0x2000])!=0xff)                   //再读键盘口

    { keyvalue=0;                                   //获取键值

      while(key&0x01!=0)

      { key>>=1;

        keyvalue++;

      }

      if(!INT1) keyvalue+=8;                        //扩展键

      if(keyvalue>=16) KEY_FLG=0;                   //无效键

      while(XBYTE[0x2000]!=0xff);                   //等释放

      delay_ms(15);                                  //延时去抖

    }

  }

}

void get_ftime()                                    //1302读时间换算成目录项中的日期时间形式

{ uchar t1,t2,t3;

  rd_time_burst1302(time);                          //突发读1302时间数据

  t1=2000+time[6]/16*10+time[6]%16;                 //年数据从压缩BCD码换算为十进制(20yy)

  t2=time[4]/16*10+time[4]%16;                      //月数据从压缩BCD码换算为十进制

  t3=time[3]/16*10+time[3]%16;                      //日数据从压缩BCD码换算为十进制

  fdate=MAKE_FILE_DATE(t1,t2,t3);                   //得到目录项中需要的日期数据形式

  t1=time[2]/16*10+time[2]%16;                      //时数据从压缩BCD码换算为十进制

  t2=time[1]/16*10+time[1]%16;                      //分数据从压缩BCD码换算为十进制

  t3=time[0]/16*10+time[0]%16;                      //秒数据从压缩BCD码换算为十进制

  fclk=MAKE_FILE_TIME(t1,t2,t3);                    //得到目录项中需要的时间数据形式

}

void modify_ftime(uchar mod)                        //文件/目录打开后修改目录项中的创建/修改时间

{ s=CH376DirInfoRead();                            //读目录项信息,相关数据调芯片内存

  if(s==USB_INT_SUCCESS)

  { buf[0]=(uchar)fdate;                            //形成日期低8

    buf[1]=(uchar)(fdate>>8);                       //形成日期高8

    buf[2]=(uchar)fclk;                             //形成时间低8

    buf[3]=(uchar)(fclk>>8);                        //形成时间高8

    if(mod)                                         //写文件/目录创建的日期时间

    { CH376WriteOfsBlock(buf,STRUCT_OFFSET(FAT_DIR_INFO,DIR_CrtDate),2);   //2B创建日期

      CH376WriteOfsBlock(buf+2,STRUCT_OFFSET(FAT_DIR_INFO,DIR_CrtTime),2);  //2B创建时间

    }

    else                                            //写文件/目录最近一次修改的日期时间

    { CH376WriteOfsBlock(buf,STRUCT_OFFSET(FAT_DIR_INFO,DIR_WrtDate),2);   //2B修改日期

      CH376WriteOfsBlock(buf+2,STRUCT_OFFSET(FAT_DIR_INFO,DIR_WrtTime),2);  //2B修改时间

    }

    s=CH376DirInfoSave();                           //保存目录项

    mStopIfError(s);                                //出错处理

  }

}

void work0()                                       //打开或新建1级子目录并修改目录项中的时间数据

{ printf("Open or create Dir.:\n");                //PC显示将打开或生成1级子目录

  sprintf(buf,"/20%b02X",time[6]);                  //1级目录名格式化到字符数组buf

  printf(buf);printf("\n");                         //PC显示1级目录为\20yy

  s=CH376DirCreate(buf);                            //打开或新建目录

  mStopIfError(s);                                  //出错处理

  get_ftime();                                      //得到用于文件/目录的时间数据

  modify_ftime(FILE_CREATE);                        //修改目录创建时间

  modify_ftime(FILE_MODIFY);                        //修改目录修改时间

  printf("Close the Dir.\n\n");                     //PC显示将关闭该目录

  s=CH376FileClose(FALSE);                          //关闭该目录

  mStopIfError(s);                                  //出错处理

}

void work1()                                       //打开或新建2级子目录并修改目录项中的时间数据

{ printf("Open or create Dir.:\n");                //PC显示将打开或生成2级子目录

  sprintf(buf,"/20%b02X/%b02X-%b02X",time[6],time[4],time[3]);    //将路径格式化到字符数组buf

  printf(buf);printf("\n");                         //PC显示2级目录为\20yy\mm-dd

  s=CH376DirCreatePath(buf);                        //打开或新建目录

  mStopIfError(s);                                  //出错处理

  get_ftime();                                      //得到用于文件/目录的时间数据

  modify_ftime(FILE_CREATE);                        //修改目录创建时间

  modify_ftime(FILE_MODIFY);                        //修改目录修改时间

  printf("Close the Dir.\n\n");                     //PC显示将关闭该目录

  s=CH376FileClose(FALSE);                          //关闭该目录

  mStopIfError(s);                                  //出错处理

}

void work2()                                       //2级目录下建文件DEMO1.TXT并添加模拟数据

{ printf("Open or create file:\n");                //PC显示打开或新建文件DEMO1.TXT

  sprintf(buf,"/20%b02X/%b02X-%b02X",time[6],time[4],time[3]);    //将路径格式化到字符数组buf

  strcat(buf,"/DEMO1.TXT");                         //路径名连接文件名

  printf(buf);printf("\n");                         //PC显示文件的完整路径

  s=CH376FileOpenPath(buf);                         //打开文件,若已存在则先删再建

  if(s==USB_INT_SUCCESS)                            //文件存在时打开,移动指针到文件尾

  { printf("Open and locate tail\n");               //PC显示文件打开指针移到文件尾

    s=CH376ByteLocate(0xFFFFFFFF);                  //指针移到文件尾

    mStopIfError(s);                                //出错处理

  }

  else if(s==ERR_MISS_FILE)                         //未找到文件需要新建

  { printf("Create\n");                             //PC显示新建文件

    s=CH376FileCreatePath(NULL);                    //新建文件,文件名刚才已提供

    mStopIfError(s);                                //出错处理

    get_ftime();                                    //得到用于文件/目录的时间数据

    modify_ftime(FILE_CREATE);                      //修改文件创建时间

  }

  else

    mStopIfError(s);                                //打开文件时出错

  printf("File size=%ldB\n",CH376GetFileSize());    //PC显示文件原先的长度

  printf("Write begin\n");                          //PC显示写数据开始

  buf[0]='\0';                                      //将多个数据依次格式化并连接到字符数组buf

  for(i=0;i<15;i++)                                 //15个数据

  { sprintf(buf1,"%b2d,",i);                        //格式化到字符数组buf1

    strcat(buf,buf1);                               //连接到字符数组buf

    printf(buf1);                                   //PC显示要写入的数据

  }

  sprintf(buf1,"%b2d\r\n",i);                       //最后1个数据格式化到字符数组buf1

  strcat(buf,buf1);                                 //连接到字符数组buf

  printf(buf1);                                     //PC显示要写入的最后一个数据

  s=CH376ByteWrite(buf,strlen(buf),NULL);           //以字节写形式将数据块写入文件

  mStopIfError(s);                                  //出错处理

  printf("Write end\n");                            //PC显示写数据结束

  printf("File size=%ldB\n",CH376GetFileSize());    //提示文件现在的长度

  get_ftime();                                      //得到用于文件/目录的时间数据

  modify_ftime(FILE_MODIFY);                        //修改文件修改时间

  printf("Close DEMO1.TXT\n\n");                    //PC显示将关闭文件DEMO1.TXT

  s=CH376FileClose(TRUE);                           //关闭文件并更新文件的字节长度

  mStopIfError(s);

}

void work3()                                       //1级子目录下创建文件DEMO2.DAT

{ printf("Create file:\n");                        //PC显示新建文件

  sprintf(buf,"/20%b02X/DEMO2.DAT",time[6]);        //将文件名格式化到字符数组buf

  printf(buf);printf("\n");                         //PC显示文件的完整路径

  s=CH376FileCreatePath(buf);                       //新建文件,若文件原来存在将删除重建

  mStopIfError(s);                                  //出错处理

  printf("File size=%ldB\n",CH376GetFileSize());    //PC显示文件原先的长度

 

  reset_1820();                                     //复位18B20

  skiprom_cmd1820();                                //跳过ROM操作(不进行芯片识别)

  convert_cmd1820();                                //启动测温

  delay_ms(750);                                    //延时等转换结束,12位精度约需750ms

  reset_1820();                                     //复位18B20

  skiprom_cmd1820();                                //跳过ROM操作

  rdscrat_cmd1820();                                //拟读高速暂存

  temp.c[1]=buf[0]=rd_byte1820();                   //18B20测温2B数据中的低字节

  temp.c[0]=buf[1]=rd_byte1820();                   //18B20测温2B数据中的高字节

  reset_1820();                                     //复位18B20,强迫读过程中止

  printf("Temp.=%6.2f\n",temp.i*0.0625);            //PC显示测得的当前温度

  res1820_to_disbuf();                              //数据送显示缓冲区

  display();                                        //数码管显示数据,格式:(-)xxx.xx

  printf("Write Temp.\n");                          //PC显示写测温数据(2B二进制补码)

  s=CH376ByteWrite(buf,2,NULL);                     //2B原始测温数据写入文件

  mStopIfError(s);                                  //出错处理

 

  rd_time_burst1302(time);                          //突发读1302时间数据共7B

  printf("Date=20%b02X.%b02X.%b02X\n",time[6],time[4],time[3]);   //提示当前日期

  printf("Clk.=%b02X:%b02X:%b02X\n",time[2],time[1],time[0]);     //提示当前时间

  buf[0]=time[6];                                   //年数据(压缩BCD)存写入缓冲区

  buf[1]=time[4];                                   //月数据(压缩BCD)存写入缓冲区

  buf[2]=time[3];                                   //日数据(压缩BCD)存写入缓冲区

  buf[3]=time[2];                                   //时数据(压缩BCD)存写入缓冲区

  buf[4]=time[1];                                   //分数据(压缩BCD)存写入缓冲区

  buf[5]=time[0];                                   //秒数据(压缩BCD)存写入缓冲区

  printf("Write Time\n");                           //PC显示写时间数据(6B压缩BCD)

  s=CH376ByteWrite(buf,6,NULL);                     //6B时间数据(压缩BCD)写入文件

  mStopIfError(s);                                  //出错处理

  printf("Write end\n");                           //PC显示写数据结束

  printf("File size=%ldB\n",CH376GetFileSize());    //PC显示文件现在的长度

  get_ftime();                                      //得到用于文件/目录的时间数据

  modify_ftime(FILE_CREATE);                        //修改文件创建时间

  modify_ftime(FILE_MODIFY);                        //修改文件修改时间

  printf("Close DEMO2.DAT\n\n");                    //PC显示将关闭文件DEMO2.DAT

  s=CH376FileClose(TRUE);                           //关闭文件并更新文件的字节长度

  mStopIfError(s);

}

void work4()                                       //在打开文件DEMO2.DAT读出其中数据并显示

{ printf("Open file:\n");                          //PC显示打开文件

  sprintf(buf,"/20%b02X/DEMO2.DAT",time[6]);        //将文件名格式化到字符数组buf

  printf(buf);printf("\n");                         //PC显示文件的完整路径

  s=CH376FileOpenPath(buf);                         //打开文件,若文件原来存在将删除重建

  mStopIfError(s);                                  //出错处理

  printf("Read 8 Byte\n");                          //PC显示读8B文件数据

  s=CH376ByteRead(buf,8,&len);                      //8B数据块,实际读取长度将返回到flen

  mStopIfError(s);                                  //出错处理

  for(i=0;i<8;i++)                                  //PC显示从文件中读取的8B原始数据

    printf("%b02X ",buf[i]);

  printf("\nTemp.=%6.2f\n",(buf[1]*256+buf[0])*0.0625);      //显示文件中的温度数据

  printf("Date=20%b02X.%b02X.%b02X\n",buf[2],buf[3],buf[4]); //显示文件中的日期数据

  printf("Clk.=%b02X:%b02X:%b02X\n",buf[5],buf[6],buf[7]);   //显示文件中的时间数据

  printf("Close DEMO2.DAT\n\n");                    //PC显示将关闭文件DEMO2.DAT

  s=CH376FileClose(FALSE);                          //关闭文件

  mStopIfError(s);

}

void main()

{ for(i=0;i<6;i++) disbuf[i]=18;                   //令数码管熄灭显示

  display();

  XBYTE[0x2000]=XBYTE[0x4000]=0;                    //令所有LED熄灭

  wr_time_burst1302(time);                          //突发读1302获得7B时间数据

  mInitSTDIO();                                     //为在串口输出调试信息初始化串口

 

  s=mInitCH376Host();                               //初始化CH376,主机工作模式

  mStopIfError(s);

  printf("Wait Udisk");                             //PC显示等待U盘插入

  while(CH376DiskConnect()!=USB_INT_SUCCESS)        //检查U盘是否连接,等待U盘插入

  { mDelaymS(100);                                 //延时100ms

    printf(".");                                    //PC显示仍在等U盘插入

  }

  printf("\nFound Udisk!\n");                       //PC显示发现U

  mDelaymS(200);                                    //可选延时操作,有的USB存储器需几十毫秒延时

 

  for(i=0;i<10;i++)                                 //多次测U盘是否就绪最长可等10*50ms

  { mDelaymS(50);

    printf("Ready?\n");                             //PC显示U盘尚未就绪

    if(CH376DiskMount()==USB_INT_SUCCESS) break;    //U盘就绪时退出

  }

  printf("Wait key\n");                             //PC显示等待用户按键

 

  while(1)

  { key_prc();                                      //查有无按键

    if(KEY_FLG)                                     //有按键

    { KEY_FLG=0;                                    //清有按键标志

      switch(keyvalue)

      { case 0:                                      //若按下K0

          work0();                                   //打开或新建1级子目录/20yy

          break;

        case 1:                                      //若按下K1

          work1();                                   //打开或新建2级子目录/20yy/mm-dd

          break;

        case 2:                                      //若按下K2,2级目录下打开或创建文本文件

          work2();                                   //DEMO1.TXT,并追加16个以逗号分隔的模拟数据

          break;

        case 3:                                      //若按下K3,1级目录下创建二进制文件

          work3();                                   //DEMO2.DAT,并写入8B温度时间数据

          work4();                                   //再次打开该文件读取其中数据计算并显示

      }

    }

  }

}

以下是对几个包含在程序中由沁恒公司提供的C源文件所做的具体改动。

//对文件HAL_BASE.C所做改动

void mDelayuS(UINT8 us)                            //微秒级延时,不精确

{ while(us--);

}

void mDelaymS(UINT8 ms)                            //毫秒级延时,不精确

{ while(ms--)

  { mDelayuS(250);

    mDelayuS(250);

    mDelayuS(250);

  }

}

//对文件SPI_SW.C所做改动

sbit A13=P2^5;                                     //3-8译码器的3个输入端

sbit A14=P2^6;

sbit A15=P2^7;

#define E_CH376_SPI_SCS A15=A14=1;A13=0;           //#CS6有效选中CH376

#define N_CH376_SPI_SCS A15=A14=1;A13=1;           //#CS6无效不选中CH376

sbit P15=P1^5;                                     //用这3个引脚模拟SPI总线

sbit P16=P1^6;

sbit P17=P1^7;

#define CH376_SPI_SDI  P15                          //模拟SPI总线的SDI

#define CH376_SPI_SDO  P16                          //模拟SPI总线的SDO

#define CH376_SPI_SCK  P17                          //模拟SPI总线的SCK

//对文件DEBUG.C所做改动

void mStopIfError(UINT8 iError)

{ if(iError==USB_INT_SUCCESS) return;              //操作成功时返回

  printf("Error: %02X\n",(UINT16)iError);           //否则输出错误编号

  while(1)                                          //并进入以下死循环

  { XBYTE[0x2000]=0xff;                             //主板上的红色LED灯闪烁

    mDelaymS(200);

    XBYTE[0x2000]=0x00;

    mDelaymS(200);

  }

}

void mInitSTDIO(void)                               //为输出调试信息初始化串口

{ SCON=0x52;                                       //串口工作在方式1,允许接收,TI=1

  TMOD=0x20;                                        //定时器1用作波特率发生器

  TH1=TL1=0xfd;                                     //晶振11.0592MHz时波特率9600

  TR1=1;                                            //启动定时器1

}

   

相关链接