可以初始化
可以CH376DiskMount( ) == USB_INT_SUCCESS
然后新建文件之后看不到,写了数据就更看不到了,不过下次执行CH376FileOpenPath的时候,程序显示找到了那个文件,但PC里看不到(有人说需要用XP系统?),SD卡已经是FAT32格式。
或者根本就没有新建成功。
总之我现在有点崩溃了,跪求大神救我,如果有技术人员愿意帮我就更好了,我可以把整个程序发过去。
下面附main函数和部分函数定义,求大神看一下。
void main(void)
{
// 步骤 1. 初始化系统控制:
// 设置PLL, WatchDog, 使能外设时钟
// 下面这个函数可以从DSP280x_SysCtrl.c文件中找到.
InitSysCtrl();
// 步骤 2. 初始化通用输入输出多路复用器GPIO:
// 这个函数在DSP280x_Gpio.c源文件中被定义了
// 这个函数使GPIO控制类寄存器初始化到默认状态
// InitGpio(); // Skipped for this example
// 次函数在DSP280x_Spi.c文件里面-----------------------------------------(1)
InitSpiaGpio(); //开发板使用SPIA
//步骤 3. 清除所有中断,初始化中断向量表:
// 禁止CPU全局中断
DINT;
// 初始化PIE控制寄存器到他们的默认状态.
// 这个默认状态就是禁止PIE中断及清除所有PIE中断标志
// 这个函数放在DSP280x_PieCtrl.c源文件里
InitPieCtrl();
// 禁止CPU中断,清除CPU中断标志位
IER = 0x0000;
IFR = 0x0000;
// 初始化PIE中断向量表,并使其指向中断服务子程序(ISR)
// 这些中断服务子程序被放在了DSP280x_DefaultIsr.c源文件中
// 这个函数放在了DSP280x_PieVect.c源文件里面.
InitPieVectTable();
// 步骤 4.初始化片内外设:--------------------------------------------------(2)
CH376_PORT_INIT( ); /* 由于使用SPI读写时序,所以进行初始化SPI,同时初始化GPIO74,初始化FIFO */
GpioDataRegs.GPCSET.bit.GPIO74 = 1; /* 防止之前未通过xEndCH376Cmd禁止SPI片选 */
// 步骤 5. 以下是用户编写的指定代码, 使能相关中断:#####################################################
GpioDataRegs.GPASET.bit.GPIO4 = 1;//置1---共阴极LED14灭
delay_loop_ms(50);
statecheck = mInitCH376Host( ); /* 初始化CH376 */
mStopIfError( statecheck );
//xWriteCH376Cmd( CMD11_CHECK_EXIST ); /* 测试单片机与CH376之间的通讯接口 */
GpioDataRegs.GPACLEAR.bit.GPIO4 = 1;//清零---共阴极LED14亮
delay_loop_ms(500);
for ( s = 0; s < 10; s ++ ) { /* 最长等待时间,10*50mS */
delay_loop_ms(50);
if ( CH376DiskMount( ) == USB_INT_SUCCESS ) break; /* 初始化磁盘并测试磁盘是否就绪 */
}
/* 如果.TXT文件已经存在则添加数据到尾部,如果不存在则新建文件 */
s = CH376FileOpenPath( "/161211.TXT" ); /* 打开文件,该文件在根目录下 */
if ( s == USB_INT_SUCCESS ) { /* 文件存在并且已经被打开,移动文件指针到尾部以便添加数据 */
s = CH376ByteLocate( 0xFFFFFFFF ); /* 移到文件的尾部 */
mStopIfError( s );
}
else if ( s == ERR_MISS_FILE ) { /* 没有找到文件,必须新建文件 */
s = CH376FileCreatePath( "/161211.TXT" ); /* 新建文件并打开,如果文件已经存在则先删除后再新建,不必再提供文件名,刚才已经提供给CH376FileOpen */
mStopIfError( s );
}
else mStopIfError( s ); /* 打开文件时出错 */
strcpy( buf, "ADC" );
s = CH376ByteWrite( buf, 3, NULL ); /* 以字节为单位向文件写入数据 */
mStopIfError( s );
//delay_loop_ms(50);
s = CH376FileClose( 0x01 ); /* 关闭文件,自动计算文件长度,以字节为单位写文件,建议让程序库关闭文件以便自动更新文件长度 */
mStopIfError( s );
LED14flash();
}
//end of main############################################################################
#definexEndCH376Cmd() GpioDataRegs.GPCSET.bit.GPIO74 = 1; /* SPI片选无效,结束CH376命令,仅用于SPI接口方式 */
//延迟函数
void delay_loop_100ms()//0.1s
{
long i;
for (i = 0; i < 15000000; i++) {} //1ms
}
void delay_loop_ms(int n)//0.001s
{
long i;
for (i = 0; i < 150000*n; i++) {} //1ms
}
void delay_loop_us(int n)//0.000001s
{
long i;
for (i = 0; i < 150*n; i++) {} //1us
}
voidCH376_PORT_INIT( ) /* 由于使用SPI读写时序,所以进行初始化SPI,同时初始化GPIO74,初始化FIFO */
{
/* 如果是硬件SPI接口,那么可使用mode3(CPOL=1&CPHA=1)或mode0(CPOL=0&CPHA=0),CH376在时钟上升沿采样输入,下降沿输出,数据位是高位在前 */
//CH376_SPI_SCS = 1; /* 禁止SPI片选 */
/* 对于双向I/O引脚模拟SPI接口,那么必须在此设置SPI_SCS,SPI_SCK,SPI_SDI为输出方向,SPI_SDO为输入方向 */
//SPCR = 0x5C; /* 设置SPI模式3, DORD=0(MSB first), CPOL=1, CPHA=1, CH376也支持SPI模式0 */
SpiaRegs.SPICCR.all =0x0047;// SPI软件复位, 极性位为1(下降沿发送数据), 每次移 0100 0111
//进和移出8位字长度;禁止SPI内部回送(LOOKBACK)功能;
SpiaRegs.SPICTL.all =0x0006; // 使能主机模式,正常相位(0),使能主机发送,禁止接收 0000 0110
//溢出中断,禁止SPI中断;
SpiaRegs.SPIBRR =0x0011;//SPI波特率=150M/4/18=2MHZ
SpiaRegs.SPICCR.all =0x00C7;//停止SPI软件复位准备接收或发送;禁止SPI内部回送; 1100 0111
SpiaRegs.SPIPRI.bit.FREE = 1; // 自由运行
//GpioCtrlRegs.GPCMUX1.bit.GPIO74 = 0; //GPIO74作为普通IO
//GpioCtrlRegs.GPCDIR.bit.GPIO74 = 1; //GPIO74方向为输出
//GpioCtrlRegs.GPCMUX1.bit.GPIO73 = 0; //GPIO73作为普通IO
//GpioCtrlRegs.GPCDIR.bit.GPIO73 = 0; //GPIO73方向为输入
//GpioCtrlRegs.GPAMUX1.bit.GPIO4 = 0;//GPIO4---->LED作为DEGUG的标志,之后要删掉!!!!**********************************
//GpioCtrlRegs.GPADIR.bit.GPIO4 = 1;
SpiaRegs.SPIFFTX.all=0xE040;//使能FIFO;清除发送中断标志位;禁止FIFO发送中断;
//发送中断级别定义为0;
SpiaRegs.SPIFFRX.all=0x204F;//清除FF溢出标志位;清除溢出接受中断标志位;禁止
//FF接受中断;接受中断级别为16;
SpiaRegs.SPIFFCT.all=0x0;//SPITXBUF到移位寄存器传送不延迟;
}
UINT8Spi376Exchange( UINT8 d ) /* 硬件SPI输出且输入8个位数据 */
{
Uint16 sdata;
Uint16 rdata;
UINT8 tempdata2;
sdata=(d<<8);
SpiaRegs.SPITXBUF=sdata;
while(SpiaRegs.SPIFFRX.bit.RXFFST !=1) { }// wait for the transmission
rdata = SpiaRegs.SPIRXBUF; //每次都保证发送和接收都进行一次,这样FIFO中才不会滞留数据
tempdata2=(UINT8)rdata;
return( tempdata2 );
}
void LED14flash()
{
GpioDataRegs.GPACLEAR.bit.GPIO4 = 1;//清零---共阴极LED14亮
delay_loop_100ms();
GpioDataRegs.GPASET.bit.GPIO4 = 1;//置1---共阴极LED14灭
delay_loop_100ms();
GpioDataRegs.GPACLEAR.bit.GPIO4 = 1;//清零---共阴极LED14亮
delay_loop_100ms();
GpioDataRegs.GPASET.bit.GPIO4 = 1;//置1---共阴极LED14灭
}
voidmStopIfError( UINT8 iError )
{
if ( iError == USB_INT_SUCCESS ) /* 操作成功 */
{
//LED14flash();
}
}
voidxWriteCH376Cmd( UINT8 mCmd ) /* 向CH376写命令 */
{
GpioDataRegs.GPCSET.bit.GPIO74 = 1; /* 防止之前未通过xEndCH376Cmd禁止SPI片选 */
delay_loop_us(2);
/* 对于双向I/O引脚模拟SPI接口,那么必须确保已经设置SPI_SCS,SPI_SCK,SPI_SDI为输出方向,SPI_SDO为输入方向 */
GpioDataRegs.GPCCLEAR.bit.GPIO74 = 1; /* SPI片选有效 */
delay_loop_us(2);
Spi376Exchange( mCmd ); /* 发出命令码 */
delay_loop_us(2);
/* 延时1.5uS确保读写周期大于1.5uS,或者用上面一行的状态查询代替 */
}
voidxWriteCH376Data( UINT8 mData ) /* 向CH376写数据 */
{
Spi376Exchange( mData );
delay_loop_us(2);
}
UINT8xReadCH376Data( void ) /* 从CH376读数据 */
{
delay_loop_us(2);
return( Spi376Exchange( 0xFF ) );
}
UINT8mInitCH376Host( void ) /* 初始化CH376 */
{
UINT8res;
//CH376_PORT_INIT( ); /* 接口硬件初始化 *///接口可以在硬件初始化之前就完成初始化
xWriteCH376Cmd( CMD11_CHECK_EXIST ); /* 测试单片机与CH376之间的通讯接口 */
xWriteCH376Data( 0x56 );
res = xReadCH376Data( );
xEndCH376Cmd( );
if ( res != 0xA9 ) return( ERR_USB_UNKNOWN ); /* 通讯接口不正常,可能原因有:接口连接异常,其它设备影响(片选不唯一),串口波特率,一直在复位,晶振不工作 */
xWriteCH376Cmd( CMD11_SET_USB_MODE ); /* 设备USB工作模式 */
xWriteCH376Data( 0x03 );//USB 05
delay_loop_ms(20);
res = xReadCH376Data( );
xEndCH376Cmd( );
if ( res == CMD_RET_SUCCESS ) return( USB_INT_SUCCESS );
else return( ERR_USB_UNKNOWN ); /* 设置模式错误 */
}
UINT8Query376Interrupt( void )
{
return( GpioDataRegs.GPCDAT.bit.GPIO73 ? FALSE : TRUE ); /* 如果连接了CH376的中断引脚则直接查询中断引脚 */
}
UINT8Wait376Interrupt( void ) /* 等待CH376中断(INT#低电平),返回中断状态码, 超时则返回ERR_USB_UNKNOWN */
{
UINT32i;
for ( i = 0; i < 30000000; i ++ ) { /* 计数防止超时,默认的超时时间,与单片机主频有关 */
if ( Query376Interrupt( ) ) return( CH376GetIntStatus( ) ); /* 检测到中断 */
/* 在等待CH376中断的过程中,可以做些需要及时处理的其它事情 */
}
return( ERR_USB_UNKNOWN ); /* 不应该发生的情况 */
}
UINT8CH376GetIntStatus( void ) /* 获取中断状态并取消中断请求 */
{
UINT8s;
xWriteCH376Cmd( CMD01_GET_STATUS );
s = xReadCH376Data( );
xEndCH376Cmd( );
return( s );
}
UINT8CH376SendCmdWaitInt( UINT8 mCmd ) /* 发出命令码后,等待中断 */
{
xWriteCH376Cmd( mCmd );
xEndCH376Cmd( );
return( Wait376Interrupt( ) );
}
UINT8CH376DiskMount( void ) /* 初始化磁盘并测试磁盘是否就绪 */
{
return( CH376SendCmdWaitInt( CMD0H_DISK_MOUNT ) );
}
UINT8CH376FileOpen( PUINT8 name ) /* 在根目录或者当前目录下打开文件或者目录(文件夹) */
{
CH376SetFileName( name ); /* 设置将要操作的文件的文件名 */
return( CH376SendCmdWaitInt( CMD0H_FILE_OPEN ) );
}
UINT8CH376FileOpenPath( PUINT8 PathName ) /* 打开多级目录下的文件或者目录(文件夹),支持多级目录路径,支持路径分隔符,路径长度不超过255个字符 */
{
return( CH376FileOpenDir( PathName, 0xFF ) );
}
UINT8CH376FileOpenDir( PUINT8 PathName, UINT8 StopName ) /* 打开多级目录下的文件或者目录的上级目录,支持多级目录路径,支持路径分隔符,路径长度不超过255个字符 */
/* StopName 指向最后一级文件名或者目录名 */
{
UINT8i, s;
s = 0;
i = 1; /* 跳过有可能的根目录符 */
while ( 1 ) {
while ( PathName[i] != DEF_SEPAR_CHAR1 && PathName[i] != DEF_SEPAR_CHAR2 && PathName[i] != 0 ) ++ i; /* 搜索下一个路径分隔符或者路径结束符 */
if ( PathName[i] ) i ++; /* 找到了路径分隔符,修改指向目标文件的最后一级文件名 */
else i = 0; /* 路径结束 */
s = CH376FileOpen( &PathName[s] ); /* 打开文件或者目录 */
if ( i && i != StopName ) { /* 路径尚未结束 */
if ( s != ERR_OPEN_DIR ) { /* 因为是逐级打开,尚未到路径结束,所以,如果不是成功打开了目录,那么说明有问题 */
if ( s == USB_INT_SUCCESS ) return( ERR_FOUND_NAME ); /* 中间路径必须是目录名,如果是文件名则出错 */
else if ( s == ERR_MISS_FILE ) return( ERR_MISS_DIR ); /* 中间路径的某个子目录没有找到,可能是目录名称错误 */
else return( s ); /* 操作出错 */
}
s = i; /* 从下一级目录开始继续 */
}
else return( s ); /* 路径结束,USB_INT_SUCCESS为成功打开文件,ERR_OPEN_DIR为成功打开目录(文件夹),其它为操作出错 */
}
}
UINT8CH376FileCreatePath( PUINT8 PathName ) /* 新建多级目录下的文件,支持多级目录路径,支持路径分隔符,路径长度不超过255个字符 */
{
UINT8s;
UINT8Name;
Name = CH376SeparatePath( PathName ); /* 从路径中分离出最后一级文件名,返回最后一级文件名的偏移 */
if ( Name ) { /* 是多级目录 */
s = CH376FileOpenDir( PathName, Name ); /* 打开多级目录下的最后一级目录,即打开新建文件的上级目录 */
if ( s != ERR_OPEN_DIR ) { /* 因为是打开上级目录,所以,如果不是成功打开了目录,那么说明有问题 */
if ( s == USB_INT_SUCCESS ) return( ERR_FOUND_NAME ); /* 中间路径必须是目录名,如果是文件名则出错 */
else if ( s == ERR_MISS_FILE ) return( ERR_MISS_DIR ); /* 中间路径的某个子目录没有找到,可能是目录名称错误 */
else return( s ); /* 操作出错 */
}
}
return( CH376FileCreate( &PathName[Name] ) ); /* 在根目录或者当前目录下新建文件 */
}
UINT8CH376SeparatePath( PUINT8 path ) /* 从路径中分离出最后一级文件名或者目录(文件夹)名,返回最后一级文件名或者目录名的字节偏移 */
{
PUINT8pName;
for ( pName = path; *pName != 0; ++ pName ); /* 到文件名字符串结束位置 */
while ( *pName != DEF_SEPAR_CHAR1 && *pName != DEF_SEPAR_CHAR2 && pName != path ) pName --; /* 搜索倒数第一个路径分隔符 */
if ( pName != path ) pName ++; /* 找到了路径分隔符,则修改指向目标文件的最后一级文件名,跳过前面的多级目录名及路径分隔符 */
return( pName - path );
}
UINT8CH376ByteLocate( UINT32 offset ) /* 以字节为单位移动当前文件指针 */
{
xWriteCH376Cmd( CMD4H_BYTE_LOCATE );
xWriteCH376Data( (UINT8)offset );
xWriteCH376Data( (UINT8)((UINT16)offset>>8) );
xWriteCH376Data( (UINT8)(offset>>16) );
xWriteCH376Data( (UINT8)(offset>>24) );
xEndCH376Cmd( );
return( Wait376Interrupt( ) );
}
UINT8CH376FileCreate( PUINT8 name ) /* 在根目录或者当前目录下新建文件,如果文件已经存在那么先删除 */
{
if ( name ) CH376SetFileName( name ); /* 设置将要操作的文件的文件名 */
return( CH376SendCmdWaitInt( CMD0H_FILE_CREATE ) );
}
UINT8CH376DirCreate( PUINT8 name ) /* 在根目录下新建目录(文件夹)并打开,如果目录已经存在那么直接打开 */
{
CH376SetFileName( name ); /* 设置将要操作的文件的文件名 */
return( CH376SendCmdWaitInt( CMD0H_DIR_CREATE ) );
}
voidCH376SetFileName( PUINT8 name ) /* 设置将要操作的文件的文件名 */
{
/*UINT8i;*/
UINT8c;
xWriteCH376Cmd( CMD10_SET_FILE_NAME );
/*for ( i = MAX_FILE_NAME_LEN; i != 0; -- i ) {
c = *name;
xWriteCH376Data( c );
if ( c == 0 ) break;
name ++;
}*/
c = *name;
xWriteCH376Data( c );
while ( c ) {
name ++;
c = *name;
if ( c == DEF_SEPAR_CHAR1 || c == DEF_SEPAR_CHAR2 ) c = 0; /* 强行将文件名截止 */
xWriteCH376Data( c );
}
xEndCH376Cmd( );
}
UINT8CH376ByteWrite( PUINT8 buf, UINT16 ReqCount, PUINT16 RealCount ) /* 以字节为单位向当前位置写入数据块 */
{
//UINT8s;
xWriteCH376Cmd( CMD2H_BYTE_WRITE );
xWriteCH376Data( (UINT8)ReqCount );
xWriteCH376Data( (UINT8)(ReqCount>>8) );
xEndCH376Cmd( );
if ( RealCount ) *RealCount = 0;
while ( 1 ) {
s = Wait376Interrupt( );
if ( s == USB_INT_DISK_WRITE ) {
s = CH376WriteReqBlock( buf ); /* 向内部指定缓冲区写入请求的数据块,返回长度 */
xWriteCH376Cmd( CMD0H_BYTE_WR_GO );
xEndCH376Cmd( );
buf += s;
if ( RealCount ) *RealCount += s;
}
/*else if ( s == USB_INT_SUCCESS ) return( s );*/ /* 结束 */
else return( s ); /* 错误 */
}
}
UINT8CH376WriteReqBlock( PUINT8 buf ) /* 向内部指定缓冲区写入请求的数据块,返回长度 */
{
UINT8s, l;
xWriteCH376Cmd( CMD01_WR_REQ_DATA );
s = l = xReadCH376Data( ); /* 长度 */
if ( l ) {
do {
xWriteCH376Data( *buf );
buf ++;
} while ( -- l );
}
xEndCH376Cmd( );
return( s );
}
UINT8CH376FileClose( UINT8 UpdateSz ) /* 关闭当前已经打开的文件或者目录(文件夹) */
{
return( CH376SendCmdDatWaitInt( CMD1H_FILE_CLOSE, UpdateSz ) );
}
UINT8CH376SendCmdDatWaitInt( UINT8 mCmd, UINT8 mDat ) /* 发出命令码和一字节数据后,等待中断 */
{
xWriteCH376Cmd( mCmd );
xWriteCH376Data( mDat );
xEndCH376Cmd( );
return( Wait376Interrupt( ) );
}