最近正在学习CH376S操作U盘,我试着在U盘的根目录下新建一个TXT文件并在文件里写入一些字符串。程序打印出来的信息显示文件创建成功,字符串写入也成功,可是插到电脑上打开优盘发现创建的这些文件的文件名里面含有特殊的字符,而且文件打不开,如下图所示
程序见二楼。求大神指点
最近正在学习CH376S操作U盘,我试着在U盘的根目录下新建一个TXT文件并在文件里写入一些字符串。程序打印出来的信息显示文件创建成功,字符串写入也成功,可是插到电脑上打开优盘发现创建的这些文件的文件名里面含有特殊的字符,而且文件打不开,如下图所示
程序见二楼。求大神指点
/*
* main.c
*
* Created on: 2010-10-8
* Author: Administrator
*/
#include "alt_types.h"
#include "altera_avalon_pio_regs.h"
#include "sys/alt_irq.h"
#include "system.h"
#include
#include
//CH375命令定义
#define GET_IC_VER0x01//获取CH376芯片以及固件版本
#define SET_BAUDRATE 0x02//设置串口通讯波特率
#define ENTER_SLEEP0x03//进入低功耗睡眠挂起状态
#define RESET_ALL 0x05//执行硬件复位
#define CHECK_EXIST0x06//测试工作状态,按位取反
//#define GET_MAX_LUN0x0a//获取USB存储设备最大逻辑单元号
//#define SET_DISK_LUN 0x0b//设置USB存储设备的当前逻辑单元号
//#define SET_PKT_P_SEC 0x0b//设置USB存储设备的每扇区数据包总数
#define SET_USB_MODE 0x15//设置USB工作模式命令
#define TEST_CONNECT 0x16//检查USB设备的连接状态
#define ABORT_NAK 0x17//放弃当前NAK的重试
#define GET_STATUS 0x22//获取中断状态并取消请求
#define RD_USB_DATA 0x27//从当前USB中断的端点缓冲区读取数据块
#define WR_USB_DATA7 0x2c//向USB主机端点的输出缓冲区写入数据块
#define DISK_INIT 0x51//初始化USB存储设备
#define DISK_SIZE 0x53//获取USB存储设备的容量
#define DISK_READ 0x54 //从USB存储设备读数据块
#define DISK_RD_G0 0x55//继续USB存储设备的读操作
#define DISK_WRITE 0x56//向USB存储设备写数据块
#define DISK_WR_GO 0x57//继续USB存储设备的写操作
//#define DISK_INQUIRY 0x58//查询USB存储设备的特性
#define DISK_READY 0x59//检查USB存储设备是否就绪
//#define DISK_R_SENSE 0x5a//检查USB存储设备的错误
#define SET_FILE_NAME 0x2f
#define FILE_CREATE 0x34
#define FILE_CLOSE 0x36
#define BYTE_WRITE 0x3c
#define BYTE_WR_GO 0x3d
#define WR_REQ_DATA 0x2d
//CH375中断状态定义
#define USB_INT_SUCCESS 0x14//USB事务或者传输操作成功
#define USB_INT_CONNECT 0x15 //检查到USB设备连接事件
#define USB_INT_DISCONNECT 0x16 //检查到USB设备断开事件
#define USB_INT_BUF_OVER 0x17//USB传输的数据有误或者数据太多缓冲区溢出
#define USB_INT_DISK_READ 0x1d//USB存储设备读操作,请求数据读出
#define USB_INT_DISK_WRITE 0x1e//USB存储设备写操作,请求数据写入
#define USB_INT_DISK_ERR 0x1f//USB 存储设备操作失败
//函数申明
alt_u8 init_usb(void);//CH376初始化并等待U盘插入
alt_u8 init_umem(void);//U盘存储器初始化
alt_u8 umem_sec_read(alt_u32 lab);//读取U盘一个扇区
alt_u8 umem_sec_write(alt_u32 lab);//U盘一个扇区写入
void write_command_to_usb(alt_u8 command);//写命令到CH376
void write_data_to_usb(alt_u8 data);//写数据到CH376
alt_u8 read_data_from_usb(void);//从CH376读出数据
void delayus(alt_u32 cnt);//短延时函数
alt_u8 ch375_intflag;//CH375中断标志位,1表示产生中断
alt_u8 ch375_status;//CH375中断状态数据
alt_u8 URD_BUFFER[512];//U盘数据读取缓冲(512B)
alt_u8 UWR_BUFFER[512];//U盘数据写入缓冲(512B)
//////////////////////////////////////////////////////////////////////
//函数名:handle_usbirq_interrupts
//功 能:CH375中断函数
//输 入:无
//返 回:无
//////////////////////////////////////////////////////////////////////
static void handle_usbirq_interrupts(void)
{
//获取中断状态并取消请求
write_command_to_usb(GET_STATUS);//发送命令
ch375_status = read_data_from_usb();//读取当前状态
ch375_intflag = 1;//中断标志位置位
}
//////////////////////////////////////////////////////////////////////
//函数名:main
//功 能:主函数
//输 入:无
//返 回:alt_u8
//////////////////////////////////////////////////////////////////////
alt_u8 main()
{
alt_u16 i;
init_usb();//CH375初始化并等待U盘插入
init_umem();//U盘存储器初始化
while(1)
{
printf("创建一个TXT文件... ...\n");
write_command_to_usb(SET_FILE_NAME);
delayus(1000);
send_string_to_usb("/HOW.TXT\0",9);
delayus(1000);
write_command_to_usb(FILE_CREATE);
while(ch375_intflag != 1);
ch375_intflag = 0;
if(ch375_status == USB_INT_SUCCESS)
{
printf("成功\n");
}
else
{
printf("失败--%d\n",ch375_status);
while(1);
}
write_command_to_usb(BYTE_WRITE);
write_data_to_usb(28);
write_data_to_usb(0);
while(ch375_intflag != 1);
ch375_intflag = 0;
if(ch375_status == USB_INT_DISK_WRITE)
{
write_command_to_usb(WR_REQ_DATA);
delayus(1000);
printf("需要写入txt的数据量为: %d\n",read_data_from_usb());
}
else
{
printf("失败--%d\n",ch375_status);
while(1);
}
send_string_to_usb("Hello,USB!",10);
send_string_to_usb("U盘TXT文本创建成功",18);
write_command_to_usb(BYTE_WR_GO);
while(ch375_intflag != 1);
ch375_intflag = 0;
if(ch375_status == USB_INT_SUCCESS)
{
printf("txt文本数据写入成功\n");
}
else
{
printf("第二次TXT文本数据写入失败--%d\n",ch375_status);
while(1);
}
write_command_to_usb(FILE_CLOSE);
write_data_to_usb(1);
printf("TXT文本创建并写入完成!\n");
while(1);
}
//umem_sec_read(0);//读取U盘第0扇区
/*
umem_sec_read(1000000);//读取U盘第1000000扇区
for(i=0;i<512;i++)
{
UWR_BUFFER[i] = i;
}
umem_sec_write(1000000);//U盘第1000000扇区写入
umem_sec_read(1000000);//读取U盘第1000000扇区
*/
return 0;
}
void send_string_to_usb(alt_8 *str,alt_u8 str_len)
{
alt_u8 i;
//向USB主机端点的输出缓冲区写入数据块,WR_USB_DATA7命令
write_command_to_usb(WR_USB_DATA7);
/*该命令向USB主机端点的输出缓冲区或者USB 端点2的上传缓冲区写入数据块。首先写入的输入
数据是数据块长度,也就是后续数据流的字节数。数据块长度的有效值是0 至64,如果长度不为0,
则单片机必须将后续数据逐个写入CH375。*/
delayus(1000);
//写入数据块长度数据
write_data_to_usb(str_len);
//写入固定长度数据字节
for(i=0;i
{
//写入数据
write_data_to_usb(str[i]);
}
}
//////////////////////////////////////////////////////////////////////
//函数名:init_usb
//功 能:CH376初始化并等待U盘插入
//输 入:无
//返 回:alt_u8 1:成功,0--失败
//////////////////////////////////////////////////////////////////////
alt_u8 init_usb(void)
{
//alt_u8 tmp;
alt_u8 temp = 0;//临时变量
//初始化全局变量
ch375_intflag = 0;//清除CH375中断标志位
ch375_status = 0;//清除 CH375中断寄存器
//初始化CH376控制端口
IOWR_ALTERA_AVALON_PIO_DATA(PIO_USB_RD_BASE,1);
IOWR_ALTERA_AVALON_PIO_DATA(PIO_USB_WR_BASE,1);
IOWR_ALTERA_AVALON_PIO_DATA(PIO_USB_A0_BASE,1);
IOWR_ALTERA_AVALON_PIO_DATA(PIO_USB_CS_BASE,1);
//使能CH376中断信号
IOWR_ALTERA_AVALON_PIO_IRQ_MASK(PIO_USB_INT_BASE,1);
IOWR_ALTERA_AVALON_PIO_EDGE_CAP(PIO_USB_INT_BASE,0);
alt_irq_register(PIO_USB_INT_IRQ,PIO_USB_INT_BASE,handle_usbirq_interrupts);//注册中断函数
//设置USB工作模式
write_command_to_usb(SET_USB_MODE);//送命令
delayus(200);
write_data_to_usb(0x06);//切换到已启用的USB设备方式,外部固件模式
delayus(200);
/*
模式代码为04H时切换到未启用的USB主机方式;
模式代码为05H时切换到已启用的USB主机方式,不产生SOF包;
模式代码为06H时切换到已启用的USB主机方式,自动产生SOF包;
模式代码为07H时切换到已启用的USB主机方式,复位USB总线;
*/
//CH375芯片读写测试
printf("CH375芯片读写测试……\n");
//读取并打印固件版本号
write_command_to_usb(GET_IC_VER);//发送命令
temp = read_data_from_usb()-0x40;//读取版本信息
printf("固件版本号为:0x%x\n",temp);//打印版本信息
//测试工作状态,按位取反
write_command_to_usb(CHECK_EXIST);//发送命令
write_data_to_usb(0xaa);//写入数据0xaa
temp = read_data_from_usb();//读取写入数据取反结果,即0xaa取反应为0x55
if(temp == 0x55) printf("测试工作状态:成功\n");//打印测试结果
else
{
printf("测试工作状态:失败\n");
return(0);
}
printf("等待USB设备连接事件……\n");//打印事件
do{//查询当前USB设备的连接状态
write_command_to_usb(TEST_CONNECT);
temp = read_data_from_usb();//读取USB设备的连接状态
delayus(600000);
} while(temp != 0x15);//检测到USB设备连接事件
printf("检测到USB设备连接事件:检查到U盘插入\n");//打印事件
return(1);
}
//////////////////////////////////////////////////////////////////////
//函数名:init_umen
//功 能:U盘存储器初始化
//输 入:无
//返 回:alt_u8 1:成功,0--失败
//////////////////////////////////////////////////////////////////////
alt_u8 init_umem(void)
{
alt_u8 i;
alt_u8 mem[8];//U盘存储量
//初始化USB存储设备
printf("\n初始化USB存储设备……\n");//打印事件
ch375_intflag = 0;//清除CH375中断标志位
write_command_to_usb(DISK_INIT);//发送命令
while(ch375_intflag != 1);//等待中断产生
ch375_intflag = 0;//清除CH375中断标志位
if(ch375_status == USB_INT_SUCCESS) printf("初始化USB存储设备:成功\n");
else
{
printf("初始化USB存储设备:失败——0x%x\n",ch375_status);
while(1);
}
//检查USB存储设备是否就绪
printf("等待USB存储设备就绪……\n");//打印事件
do{
delayus(10000);
ch375_intflag = 0;//清除CH375中断标志位
write_command_to_usb(DISK_READY);//发送命令
while(ch375_intflag != 1);//等待中断产生
} while(ch375_status != USB_INT_SUCCESS);
printf("USB存储设备已经就绪\n");//打印事件
ch375_intflag = 0;//清除CH375中断标志位
//获取USB存储设备的容量
printf("获取USB存储设备的容量……\n");//打印事件
write_command_to_usb(DISK_SIZE);//发送命令
while(ch375_intflag != 1);//等待中断产生
ch375_intflag = 0;//清除CH375中断标志位
if(ch375_status == USB_INT_SUCCESS)
{
printf("获取USB存储设备的容量:成功\n");
write_command_to_usb(RD_USB_DATA);//发送命令
//读取并打印USB存储设备容量
read_data_from_usb();//读取第一个字节,即后续数据长度,为8
for(i=0;i<8;i++)//连续读取8个字节数据
{
mem[i] = read_data_from_usb();
}
printf("\t总扇区数为:%d\n",((mem[0]<<24)+(mem[1]<<16)+(mem[2]<<8)+mem[3]));
printf("\t每个扇区字节数为:%dB\n",((mem[4]<<24)+(mem[5]<<16)+(mem[6]<<8)+mem[7]));
printf("\t总存储量为:%dMB\n",((((mem[0]<<24)+(mem[1]<<16)+(mem[2]<<8)+mem[3]))>>12)*((((mem[4]<<24)+(mem[5]<<16)+(mem[6]<<8)+mem[7]))>>8));
return(1);
}
else
{
printf("获取USB存储设备的容量:失败——0x%x\n",ch375_status);
return(0);
}
}
//////////////////////////////////////////////////////////////////////
//函数名:umem_sec_read
//功 能:读取U盘一个扇区
//输 入:alt_u32 lab:LAB地址,即扇区号(此外使用了全局数组URD_BUFFER)
//返 回:alt_u8 1:成功,0--失败
//////////////////////////////////////////////////////////////////////
alt_u8 umem_sec_read(alt_u32 lab)
{
alt_u8 i;
alt_u16 cnt = 0;
alt_u8 temp = 0;//临时变量
//从USB存储设备读数据块
printf("\n从U盘读取第%d扇区数据块……\n",lab);//打印事件
write_command_to_usb(DISK_READ);//发送命令
write_data_to_usb(lab);//起始地址:LAB地址的最低字节0x00
write_data_to_usb(lab>>8);//起始地址:LAB地址的较低字节0x00
write_data_to_usb(lab>>16);//起始地址:LAB地址的较高字节0x00
write_data_to_usb(lab>>24);//起始地址:LAB地址的最高字节0x00
write_data_to_usb(0x01);//数据长度:扇区数0x01
while(1)//执行数据读取操作
{
while(ch375_intflag != 1);//等待中断产生
ch375_intflag = 0;//清除CH375中断标志位
if(ch375_status == USB_INT_DISK_READ)//USB存储设备读操作,请求数据读出
{
write_command_to_usb(RD_USB_DATA);//发送读取数据命令
temp = read_data_from_usb();//读取第一个字节,即后续数据长度,应为64
for(i=0;i
{
URD_BUFFER[cnt++] = read_data_from_usb();
printf("0x%2x,",URD_BUFFER[cnt-1]);
if((i==15) || (i==31) || (i==47) || (i==63)) printf("\n");//每16个数据换行
}
write_command_to_usb(DISK_RD_G0);//发送继续USB存储设备的读操作命令
}
else if(ch375_status == USB_INT_SUCCESS)
{
printf("读取U盘第%d扇区数据:成功\n",lab);
break;
}
else
{
printf("读取U盘第%d扇区数据:失败——0x%x\n",lab,ch375_status);
return(0);
}
}
return(1);
}
//////////////////////////////////////////////////////////////////////
//函数名:umem_sec_write
//功 能:U盘一个扇区写入
//输 入:alt_u32 lab:LAB地址,即扇区号(此外使用了全局数组UWR_BUFFER)
//返 回:alt_u8 1:成功,0--失败
//////////////////////////////////////////////////////////////////////
alt_u8 umem_sec_write(alt_u32 lab)
{
alt_u8 i;
alt_u16 cnt = 0;
//从USB存储设备读数据块
printf("\n向U盘写入第%d扇区数据块……\n",lab);//打印事件
write_command_to_usb(DISK_WRITE);//发送命令
write_data_to_usb(lab);//起始地址:LAB地址的最低字节0x00
write_data_to_usb(lab>>8);//起始地址:LAB地址的较低字节0x00
write_data_to_usb(lab>>16);//起始地址:LAB地址的较高字节0x00
write_data_to_usb(lab>>24);//起始地址:LAB地址的最高字节0x00
write_data_to_usb(0x01);//数据长度:扇区数0x01
while(1)//执行数据写入操作
{
while(ch375_intflag != 1);//等待中断产生
ch375_intflag = 0;//清除CH375中断标志位
if(ch375_status == USB_INT_DISK_WRITE)//USB存储设备读操作,请求数据写入
{
write_command_to_usb(WR_USB_DATA7);//发送写入数据命令
write_data_to_usb(64);//写入第一个字节,即后续数据长度,为64
for(i=0;i<64;i++)//连续写入64个字节数据
{
write_data_to_usb(UWR_BUFFER[cnt++]);
}
write_command_to_usb(DISK_WR_GO);//发送继续USB存储设备的读操作命令
}
else if(ch375_status == USB_INT_SUCCESS)
{
printf("写入U盘第%d扇区数据:成功\n",lab);
break;
}
else
{
printf("写入U盘第%d扇区数据:失败——0x%x\n",lab,ch375_status);
return(0);
}
}
return(1);
}
//////////////////////////////////////////////////////////////////////
//函数名:write_command_to_usb
//功 能:写命令到CH375
//输 入:alt_u8 command----写入命令
//返 回:无
//////////////////////////////////////////////////////////////////////
void write_command_to_usb(alt_u8 command)
{
//命令操作 A0=1
IOWR_ALTERA_AVALON_PIO_DATA(PIO_USB_A0_BASE,1);
//设置USB_DB为输出
IOWR_ALTERA_AVALON_PIO_DIRECTION(PIO_USB_DB_BASE,0xff);
//送命令到USB_DB
IOWR_ALTERA_AVALON_PIO_DATA(PIO_USB_DB_BASE,command);
//拉低USB_CS
IOWR_ALTERA_AVALON_PIO_DATA(PIO_USB_CS_BASE,0);
//拉低USB_WR
IOWR_ALTERA_AVALON_PIO_DATA(PIO_USB_WR_BASE,0);
//延时
delayus(10);
//拉高USB_WR
IOWR_ALTERA_AVALON_PIO_DATA(PIO_USB_WR_BASE,1);
//拉高USB_CS
IOWR_ALTERA_AVALON_PIO_DATA(PIO_USB_CS_BASE,1);
}
//////////////////////////////////////////////////////////////////////
//函数名:write_data_to_usb
//功 能:写数据到CH376
//输 入:alt_u8 data----写入数据
//返 回:无
//////////////////////////////////////////////////////////////////////
void write_data_to_usb(alt_u8 data)
{
//数据操作 A0=0
IOWR_ALTERA_AVALON_PIO_DATA(PIO_USB_A0_BASE,0);
//设置USB_DB为输出
IOWR_ALTERA_AVALON_PIO_DIRECTION(PIO_USB_DB_BASE,0xff);
//送数据到USB_DB
IOWR_ALTERA_AVALON_PIO_DATA(PIO_USB_DB_BASE,data);
//拉低USB_CS
IOWR_ALTERA_AVALON_PIO_DATA(PIO_USB_CS_BASE,0);
//拉低USB_WR
IOWR_ALTERA_AVALON_PIO_DATA(PIO_USB_WR_BASE,0);
//延时
delayus(10);
//拉高USB_WR
IOWR_ALTERA_AVALON_PIO_DATA(PIO_USB_WR_BASE,1);
//拉高USB_CS
IOWR_ALTERA_AVALON_PIO_DATA(PIO_USB_CS_BASE,1);
}
//////////////////////////////////////////////////////////////////////
//函数名:read_data_from_usb
//功 能:从CH376读出数据
//输 入:无
//返 回:alt_u8----读出数据
//////////////////////////////////////////////////////////////////////
alt_u8 read_data_from_usb(void)
{
alt_u8 data = 0;//返回数据变量定义
//数据操作 A0=0
IOWR_ALTERA_AVALON_PIO_DATA(PIO_USB_A0_BASE,0);
//设置USB_DB为输入
IOWR_ALTERA_AVALON_PIO_DIRECTION(PIO_USB_DB_BASE,0x00);
//拉低USB_CS
IOWR_ALTERA_AVALON_PIO_DATA(PIO_USB_CS_BASE,0);
//拉低USB_RD
IOWR_ALTERA_AVALON_PIO_DATA(PIO_USB_RD_BASE,0);
//延时>30ns数据输出有效,可以读取
delayus(10);
//读取数据
data = IORD_ALTERA_AVALON_PIO_DATA(PIO_USB_DB_BASE);
//拉高USB_RD
IOWR_ALTERA_AVALON_PIO_DATA(PIO_USB_RD_BASE,1);
//拉高USB_CS
IOWR_ALTERA_AVALON_PIO_DATA(PIO_USB_CS_BASE,1);
//延时,读取结束
delayus(1);
return data;
}
//////////////////////////////////////////////////////////////////////
//函数名:delayus
//功 能:短延时函数
//输 入:alt_u32 cnt----延时值
//返 回:void
//////////////////////////////////////////////////////////////////////
void delayus(alt_u32 cnt)
{
int i;
for(i=0;i
}
你好:
你程序里的send_string_to_usb("/HOW.TXT\0",9);这个函数就写错了,使用SET_FILE_NAME命令后面跟随的直接是文件名字符串,不需要长度等。具体实现参考我们提供的例程中的FILE_SYS.c文件中CH376SetFileName( name )这个函数。
非常感谢帮助,已经修改了程序,可以正常工作了