急需DSP操作U盘标准模块的示例
DSP:F2812 32位CPU
IDE:CCS2.0 支持C语言
现在就在U盘模块这里过不去了,急啊.
贵公司有没有为DSP芯片设计的U盘模块的操作示例啊?
主要是并口的时序,我实在是搞不定了,试了很多的方法,很多的组合,但只能在U盘是否插上的辨别上可以百分百正确,其它的如新建,打开文件等,皆以失败告终.
现在项目急啊,如果这个模块搞不成,产品化就要延期了.
望沁恒的工程师帮帮忙啊,论坛上的高手们,请多指教了.
ARM7+DSP
我们暂时没有DSP操作模块的程序,您可以将您的程序发送到我们的技术支持信箱,我们看一下,尽快给您答复!!
此号封存
好的.实际上我已经发了一个,在这里我再贴上来一遍,还恳请你们的帮助.
#include "DSP28_Device.h"
#include "CH375HM.h"
//#include


#define LED1 GpioDataRegs.GPADAT.bit.GPIOA12
#define LED_ON 0
#define LED_OFF 1

#define MAX_PATH_LEN 32
/* 最大路径长度,含所有斜杠分隔符和小数点间隔符以及路径结束符00H,CH375模块支持的最大值是64,最小值是13 */

#define UDisk_WR GpioDataRegs.GPBDAT.bit.GPIOB8 //低电平有效 输出
#define UDisk_RD GpioDataRegs.GPBDAT.bit.GPIOB9 //低电平有效 输出
#define UDisk_CS GpioDataRegs.GPBDAT.bit.GPIOB10 //低电平有效 输出
#define UDisk_A GpioDataRegs.GPBDAT.bit.GPIOB13 //地址信号线,为0时指向索引口,为1时指向数据口 输出
#define UDisk_INT GpioDataRegs.GPBDAT.bit.GPIOB14 //低电平有效 输入

unsigned char DATA_BUF[1024];
/* 外部RAM的文件数据缓冲区,从该单元开始的缓冲区长度不小于一次读写的数据长度,最少为512字节 */
CMD_PARAM mCmdParam;
/* 默认情况下该结构将占用64字节的RAM,可以修改MAX_PATH_LEN常量,当修改为32时,只占用32字节的RAM */
unsigned char mIntStatus;
/* CH375模块的中断状态或者操作完成状态 */

void Nop()
{
int i;
for(i=0;i<3;i++); //PLLCR为A不变的前提下,这个i //这说明了时序是何等的重要。
}

void mDelaymS( unsigned char delay ) //不知道这个延时写得准不准,要适时的调整
{
unsigned char i, j, c;
for ( i = delay; i != 0; i -- ) {
for ( j = 10000; j != 0; j -- ) c += 3;
for ( j = 10000; j != 0; j -- ) c += 3; //j=1000还是对应的PLLCR=2时才看得出是在闪灯
}
}

void CH375HM_INDEX_WR( unsigned char Index ) //char是16位的 问题是:一定要unsigned的吗?
{
unsigned char BDirTemp=GpioMuxRegs.GPBDIR.all;

UDisk_RD=1;
UDisk_A=0;
EALLOW;

GpioMuxRegs.GPBDIR.all=GpioMuxRegs.GPBDIR.all|0x00ff; //输出  
//GpioMuxRegs.GPBDIR.all=0x27FF; //0010 0111 1111 1111
EDIS;
//GpioDataRegs.GPBDAT.all=GpioDataRegs.GPBDAT.all|(Index&0x00FF); //这是新时序里面来的
GpioDataRegs.GPBDAT.all=(Index&0x00FF)|0x5A00; //0101 1010 XXXX XXXX
Nop();

UDisk_CS=0;
UDisk_WR=0;
Nop();
//B15~Horn, B14~INT, B13~A0, B12~SDA, B11~SCL, B10~CS, B9~RD, B8~WR,
//B7~D7, B6~D6, B5~D5, B4~D4, B3~D3, B2~D2, B1~D1, B0~D0
//Nop();
GpioMuxRegs.GPBDIR.all=BDirTemp;
UDisk_WR=1;
UDisk_A=1;
UDisk_CS=1;

}

void CH375HM_DATA_WR( unsigned char Data )
{
unsigned char BDirTemp=GpioMuxRegs.GPBDIR.all;
UDisk_RD=1;
UDisk_A=1;

EALLOW;
GpioMuxRegs.GPBDIR.all=GpioMuxRegs.GPBDIR.all|0x00ff; //输出 
//GpioMuxRegs.GPBDIR.all=0x27FF;
EDIS;
//GpioDataRegs.GPBDAT.all=GpioDataRegs.GPBDAT.all|(Data&0x00FF); //这是新时序里面来的 是个很害人的东西
GpioDataRegs.GPBDAT.all=(Data&0x00FF)|0x7A00; //0111 1010 XXXX XXXX
Nop();

UDisk_CS=0;
UDisk_WR=0;
Nop();
GpioMuxRegs.GPBDIR.all=BDirTemp;

UDisk_WR=1;
UDisk_A=0;
UDisk_CS=1;

}
unsigned char CH375HM_DATA_RD(void)
{
unsigned char Data_rd;
unsigned char BDirTemp=GpioMuxRegs.GPBDIR.all;

UDisk_A=1;

EALLOW;
GpioMuxRegs.GPBDIR.all=GpioMuxRegs.GPBDIR.all&0xff00; //输入
//GpioMuxRegs.GPBDIR.all=0x2700;
EDIS;
UDisk_WR=1;

Nop();
UDisk_CS=0;
UDisk_RD=0;
Nop();
Nop();
Data_rd=GpioDataRegs.GPBDAT.all&0x00FF;

GpioMuxRegs.GPBDIR.all=BDirTemp;
UDisk_RD=1;
UDisk_CS=1;
UDisk_A=0;
return (Data_rd);
}

/* 执行命令 */
unsigned char ExecCommandBuf( unsigned char cmd, unsigned char len, unsigned char *bufstart )
/* 输入命令码和输入参数长度,返回操作状态码,输入参数和返回参数都在CMD_PARAM结构中 */
/* 输入参数bufstart仅用于CMD_FileRead或者CMD_FileWrite命令,指定外部RAM缓冲区的起始地址,可以参考中断方式C程序采用全局变量buffer的方式 */
{
unsigned char i, status;
unsigned char *buf;
unsigned char *CurrentBuf;
CH375HM_INDEX_WR( PARA_COMMAND_ADDR );
CH375HM_DATA_WR( cmd ); /* 向索引地址PARA_COMMAND_ADDR写入命令码 */
if ( len ) { /* 有参数 */
i = len;
CH375HM_INDEX_WR( PARA_BUFFER_ADDR ); /* 指向缓冲区 */
buf = (unsigned char *)&mCmdParam; /* 指向输入参数的起始地址 */
do {
CH375HM_DATA_WR( *buf ); /* 从索引地址PARA_BUFFER_ADDR开始,写入参数 */
buf ++;
} while ( -- i );
}
CH375HM_INDEX_WR( PARA_CMD_LEN_ADDR );
CH375HM_DATA_WR( len | PARA_CMD_BIT_ACT ); /* 向索引地址PARA_CMD_LEN_ADDR写入后续参数的长度,最高位通知模块,说明命令包已经写入,请求开始执行命令 */
CurrentBuf = bufstart; /* 外部RAM缓冲区起始地址,仅用于FileRead或者FileWrite命令 */
while ( 1 ) { /* 处理数据传输,直到操作完成才退出 */

#if 1
while ( UDisk_INT ); /* 等待模块完成操作产生低电平中断,最佳检测方式是对模块的INT#信号进行下降沿边沿检测 */
#else
do { /* 如果不需要扇区方式读写,那么可以查询模块的命令码单元代替查询模块INT#引脚 */
CH375HM_INDEX_WR( PARA_COMMAND_ADDR );
} while ( CH375HM_DATA_RD( ) ); /* 模块操作完成时该值会清0,仅适用于非扇区方式读写 */
#endif

CH375HM_INDEX_WR( PARA_STATUS_ADDR ); /* 写入索引地址 */
status = CH375HM_DATA_RD( ); /* 从索引地址PARA_STATUS_ADDR读取中断状态 */
CH375HM_INDEX_WR( PARA_CMD_LEN_ADDR );
CH375HM_DATA_WR( PARA_CMD_BIT_INACT ); /* 中断应答,取消来自模块的中断请求 */
/* 因为模块在收到中断应答后3uS之内才撤消中断请求,所以,如果是查询INT#信号的低电平,那么在发出中断应答后3uS之内不应该再查询INT#信号的状态
但是由于51单片机较慢,下面的处理时间已经超过3uS,所以不必另加延时等待模块撤消中断请求 */
if ( status == ERR_SUCCESS ) { /* 操作成功 */
CH375HM_INDEX_WR( PARA_STS_LEN_ADDR );
i = CH375HM_DATA_RD( ); /* 从索引地址PARA_STS_LEN_ADDR读取返回结果数据的长度,计数 */
if ( i ) { /* 有结果数据 */
CH375HM_INDEX_WR( PARA_BUFFER_ADDR ); /* 指向缓冲区 */
buf = (unsigned char *)&mCmdParam; /* 指向输出参数的起始地址 */
do {
*buf = CH375HM_DATA_RD( ); /* 从索引地址PARA_BUFFER_ADDR开始,读取结果 */
buf ++;
} while ( -- i );
}
// status = ERR_SUCCESS;
break; /* 操作成功返回 */
}
else if ( status == USB_INT_DISK_READ ) { /* 正在从U盘读数据块,请求数据读出 */
CH375HM_INDEX_WR( PARA_BUFFER_ADDR ); /* 指向缓冲区 */
i = 64; /* 计数 */
do { /* 要提高文件数据读写速度,这段程序用汇编程序效率更高,在C51中,do+while比for或者while结构效率高 */
*CurrentBuf = CH375HM_DATA_RD( ); /* 从索引地址0到63依次读出64字节的数据 */
CurrentBuf ++; /* 读取的数据保存到外部缓冲区 */
} while ( -- i ); /* 上面这一小段C程序用汇编程序效率要高近一倍 */
CH375HM_INDEX_WR( PARA_CMD_LEN_ADDR );
CH375HM_DATA_WR( PARA_CMD_BIT_ACT ); /* 通知模块继续,说明64字节数据已经读取完成 */
}
else if ( status == USB_INT_DISK_WRITE ) { /* 正在向U盘写数据块,请求数据写入 */
CH375HM_INDEX_WR( PARA_BUFFER_ADDR ); /* 指向缓冲区 */
i = 64; /* 计数 */
do {
CH375HM_DATA_WR( *CurrentBuf ); /* 向索引地址0到63依次写入64字节的数据 */
CurrentBuf ++; /* 写入的数据来自外部缓冲区 */
} while ( -- i );
CH375HM_INDEX_WR( PARA_CMD_LEN_ADDR );
CH375HM_DATA_WR( PARA_CMD_BIT_ACT ); /* 通知模块继续,说明64字节数据已经写入完成 */
}
else if ( status == USB_INT_DISK_RETRY ) { /* 读写数据块失败重试,应该向回修改缓冲区指针 */
CH375HM_INDEX_WR( PARA_BUFFER_ADDR ); /* 指向缓冲区 */
i = CH375HM_DATA_RD( ); /* 大端模式下为回改指针字节数的高8位,如果是小端模式那么接收到的是回改指针字节数的低8位 */
status = CH375HM_DATA_RD( ); /* 大端模式下为回改指针字节数的低8位,如果是小端模式那么接收到的是回改指针字节数的高8位 */
CurrentBuf -= ( (unsigned short)i << 8 ) + status; /* 这是大端模式下的回改指针,对于小端模式,应该是( (unsigned short)status << 8 ) + i */
CH375HM_INDEX_WR( PARA_CMD_LEN_ADDR );
CH375HM_DATA_WR( PARA_CMD_BIT_ACT ); /* 通知模块继续,说明重试状态码已经处理完成 */
}
else { /* 操作失败 */
if ( status == ERR_DISK_DISCON || status == ERR_USB_CONNECT ) { /* U盘刚刚连接或者断开,应该延时几十毫秒再操作 */
mDelaymS( 100 );
if ( UDisk_INT ) break; /* 没有中断则返回,如果仍然
ARM7+DSP
CH375fileopen()函数是什么??你知不知道啊
这人很懒,什么都没留下
您在哪里看的例子,模块的例子中没有这个函数,您是不是看了CH375的相关例子程序?其实这个函数已经做在库里了,您使用的时候只需要调用就可以了.
此号封存
大哥我是学生,老师交代让做这个,也是2812的DSP,能不能把您的程序发给我一个参考一下啊,十分感谢啊songpeng19880225@yahoo.cn
这人很懒,什么都没留下
有三个方案可以选择:
1.使用我们的U盘文件读写模块,就不需要库,简单,外围单片机压力小,程序简单;
2.使用我们的CH376芯片,内置文件系统,无须库,操作也很简单;
3.使用我们的CH375或者CH374,我们提供2812的库
此号封存
只有登录才能回复,可以选择微信账号登录