[求助] 我无能为力了,求贵公司解答。。。。

小弟我技术有限,开始时我买了两块CH376T...然后就发现CH376T 网上没有提供硬件电路图,然后有看到你们说376T和376S的硬件电路一样,那好我就硬着头皮照376s的电路焊起来,然后用你们的CH376EVT文件SPI软件模拟的方式,改了在SPI_SW.C的IO口,然后我就试了8,9天,无果。。。。 那好我就认倒霉,谁叫我在买芯片时没去看有没有硬件电路图,或许我电路焊错了呢。。。。 那好 ,我就重新又买了两块CH376S的,按照数据手册里的电路图焊了,但是。。。。还是过来8,9天无果。。。。。

虽然我是个新手,但用块芯片怎么就这么难呢?。。。。我就想贵公司解答,我就想用单片机用软件模拟SPI的方式与CH376S连接,让后实现CH376S从U盘中读出TXT文件里面的数据就行了。。。。其他什么功能我都不要了,你们告诉我我该怎么办?

我的单片机,STC12C5410AD ,28引脚封装的。。。CH376与单片机的IO连接关系是

sbit P32 =P3^2; sbit P33 =P3^3; sbit P35 =P3^5; sbit P34 =P3^4; #define CH376_SPI_SCS P34 #define CH376_SPI_SDI P33 #define CH376_SPI_SDO P32 #define CH376_SPI_SCK P35

U盘我是用,金士顿4G优盘。。文件TXT是放在优盘下里,abc.txt 没有任何文件夹。。。 上面单片机用的是24MHZ的晶振,一个机器周期是一个时钟周期,高速型的。。。

CH376S是用12MHZ晶振,两个脚对地接两个15PF的陶瓷电容, 两只脚测得电压在2.23V左右,V3叫对地接一个0.01PF的陶瓷电容,376S 3,4脚接地。。。

你们就告诉我要实现单片机读U盘的TXT文件的内容,第一步要怎么做,第二不要怎么做最后怎么做,一个时钟周期为一个机器周期的单片机与CH376S通信需要注意什么波特率设置需要注意什么。

这样就行了,CH376S的其他功能我也不要了,就读一个TXT文件该怎么办? 有所麻烦的地方,实在不好意思,但我实在没办法了。。。。。 [Emot]1[/Emot]

关于读写你参考CH376EVT下面有个文件,SPI_SW.C 先做测试命令。测试命令通过就说明MCU和CH376通讯成功。先把这一步完成。使用很简单,可能是你的方法不对


请问红桃六,CH375+mega128测试命令在哪可以下载?文件名是什么?


测试命令就是一个命令码,在使用芯片前请仔细看一下文档。CH376DS1。


我用CH376EVT下的EXAM1为例。。。。根据我的硬件,我把debug.c 里的TH1原本为0xf3,改为0xb2 因为虽然我的单片机晶振是24mhz但这个单片机是一个时钟一个机器的周期的。。。。 /* 为printf和getkey输入输出初始化串口 */ void mInitSTDIO( void ) { SCON = 0x50; //PCON = 0x80; TMOD = 0x21; TH1=0xb2;//TH1 = 0xf3; /* 24MHz晶振, 9600bps */ TR1 = 1; TI = 1; }

还有就是改了spi_sw.c 里面的io连接部分 /* 本例中的硬件连接方式如下(实际应用电路可以参照修改下述定义及子程序) */ /* 单片机的引脚 CH376芯片的引脚 P1.4 SCS P1.5 SDI P1.6 SDO P1.7 SCK */ sbit P32 = P3^2; sbit P33 = P3^3; sbit P35 = P3^5; sbit P34 = P3^4; #define CH376_SPI_SCS P34 /* 假定CH376的SCS引脚 */ #define CH376_SPI_SDI P33 /* 假定CH376的SDI引脚 */ #define CH376_SPI_SDO P32 /* 假定CH376的SDO引脚 */ #define CH376_SPI_SCK P35 /* 假定CH376的SCK引脚 */

还有就是把hal_base.c 里面的毫秒延时时间加长了。。。

/* 延时指定毫秒时间,根据单片机主频调整,不精确 */ void mDelaymS( UINT8 ms ) { while ( ms -- ) { mDelayuS( 250 ); mDelayuS( 250 ); mDelayuS( 250 ); mDelayuS( 250 );

mDelayuS( 250 ); mDelayuS( 250 ); mDelayuS( 250 ); mDelayuS( 250 );mDelayuS( 250 ); mDelayuS( 250 ); mDelayuS( 250 ); mDelayuS( 250 );mDelayuS( 250 ); mDelayuS( 250 ); mDelayuS( 250 ); mDelayuS( 250 );mDelayuS( 250 ); mDelayuS( 250 ); mDelayuS( 250 ); mDelayuS( 250 );mDelayuS( 250 ); mDelayuS( 250 ); mDelayuS( 250 ); mDelayuS( 250 );mDelayuS( 250 ); mDelayuS( 250 ); mDelayuS( 250 ); mDelayuS( 250 );mDelayuS( 250 ); mDelayuS( 250 ); mDelayuS( 250 ); mDelayuS( 250 );mDelayuS( 250 ); mDelayuS( 250 ); mDelayuS( 250 ); mDelayuS( 250 );mDelayuS( 250 ); mDelayuS( 250 ); mDelayuS( 250 ); mDelayuS( 250 );mDelayuS( 250 ); mDelayuS( 250 ); mDelayuS( 250 ); mDelayuS( 250 );mDelayuS( 250 ); mDelayuS( 250 ); mDelayuS( 250 ); mDelayuS( 250 ); } }

我就改了这三个地方,其他地方我都没改动。。。然后打开串口调试助手,他大概每个5秒就发来10几个0x00,。。。


感觉我的波特率的初值也没有算对好像。。


感觉楼主还是先把串口调好再说,把单片机设成1T和12T模式波特率的处置是不一样的


刚才又错了,

已经把串口设置好了,

我查了以下 STC的 1T单片机有特殊功能寄存器AUXR, 当单片机初始化的时候,AUXR默认为0X00,所以1T的定时器,在不设置AUXR 的时候默认就是传统的12分频的定时器。。。是兼容传统8051的,所以

这里按照原来的文件不用改就是正确的

void mInitSTDIO( void ) { SCON = 0x50; PCON = 0x80; TMOD = 0x21; TH1 = 0xf3; /* 24MHz晶振, 9600bps */ TR1 = 1; TI = 1; }

这样设置就是正确的。。。。现在每个7,8秒收到的数据是F8 00 F8 00 F8 F8 00 F8 00 F8 F0 F8 F8 00 00 F8


建议你上电延时50MS之后,做测试命令。如果一上电未做任何处理就出现你上述的现象。估计要么单片机未正常工作,要么编译的时候RAM有问题。


你好。。。。我进入main函数后就加了一个10秒的延时。。。。。然后再试,过了一段时间后就又是5,6秒就收到F8 00 F8 00 F8 F8 00 F8 00 F8 F8 F8 F8 00 00 F8 。。。

还有一点值得关注。。。我把u盘插下去时,优盘上的灯亮不到一秒就灭了,这也是一个问题。。。


这下应该可以跳出来了吧


如果是上述的现象的话,那么程序上面有问题啊,再者你程序都没贴全,看不到你程序怎么跑的


程序就和用CH376EVT下的EXAM1的一模一样啊,

#include #include #include

sfr AUXR = 0x8E; #include "HAL.H" #include "HAL_BASE.C" #include "DEBUG.H" #include "DEBUG.C" #include "SPI_SW.C" #define EN_DISK_QUERY 1 /* 启用磁盘查询 */ #include "FILE_SYS.H" #include "FILE_SYS.C"

UINT8 idata buf[64];

UINT8 CopyAndConvertFile( PUINT8 SrcFileName, PUINT8 TarFileName ) { /* 文件复制,以字节方式复制,缓冲区越大速度越快 */ /* SrcFileName 源文件名,支持路径分隔符和多级目录,字符串必须存放于RAM中 TarFileName 目标文件名,支持路径分隔符和多级目录,字符串必须存放于RAM中 */ UINT8 s; UINT16 ThisLen, cnt; UINT32 FileSize, ByteCount; UINT8 TarName; UINT32 TarUpDirClust; ByteCount = 0; do { printf( "OpenSrc\n" ); /* 注意打印输出会浪费时间,减低平均复制速度 */ s = CH376FileOpenPath( SrcFileName ); /* 打开多级目录下的文件,输入缓冲区必须在RAM中 */ if ( s != USB_INT_SUCCESS ) return( s ); if ( ByteCount == 0 ) { /* 首次 */ FileSize = CH376GetFileSize( ); /* 读取当前文件长度 */ printf( "SrcFileSz=%ld\n", FileSize ); } else { /* 再次进入 */ s = CH376ByteLocate( ByteCount ); /* 以字节为单位移动当前文件指针到上次复制结束位置 */ if ( s != USB_INT_SUCCESS ) return( s ); } printf( "Read\n" ); s = CH376ByteRead( buf, sizeof( buf ), &ThisLen ); /* 以字节为单位从当前位置读取数据块,请求长度同缓冲区大小,返回实际长度在ThisLen中 */ if ( s != USB_INT_SUCCESS ) return( s ); // s = CH376FileClose( FALSE ); /* 关闭文件,对于读操作可以不必关闭文件 */ // if ( s != USB_INT_SUCCESS ) return( s );

for ( cnt=0; cnt < ThisLen; cnt ++ ) { /* 将缓冲区中的小写字符转换为大写 */ s = buf[ cnt ]; if ( s >= 'a' && s <= 'z' ) buf[ cnt ] = s - ( 'a' - 'A' ); }

if ( ByteCount == 0 ) { /* 首次,目标文件尚未存在 */ printf( "CreateTar\n" ); TarName = CH376SeparatePath( TarFileName ); /* 从路径中分离出最后一级文件名或目录名,返回最后一级文件名或目录名的偏移 */ if ( TarName ) { /* 是多级目录 */ s = CH376FileOpenDir( TarFileName, TarName ); /* 打开多级目录下的最后一级目录,即打开新建文件的上级目录 */ 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 ); /* 操作出错 */ } TarUpDirClust = CH376ReadVar32( VAR_START_CLUSTER ); /* 上级目录的起始簇号 */ } else TarUpDirClust = 0; /* 默认是根目录的起始簇号 */ /* 在当前目录下进行文件新建或者打开操作,比全路径多级目录下的文件新建或者打开操作的速度快, 所以目标文件的新建或者打开采用此法处理(本程序源文件是直接打开全路径多级目录下的文件,为提高速度,也可参照此法加快文件打开), 为了实现当前目录下的文件新建或者打开操作,参考上面几行代码, 首先,要获得文件所在的上级目录的起始簇号,相当于打开上级目录,通过CH376FileOpenPath打开上级目录获得, 其次,要获得文件的直接短文件名(去掉上级目录名,不含任何路径分隔符,保留最后一级文件名),通过CH376SeparatePath分析目标文件名获得 */ s = CH376FileCreate( &TarFileName[TarName] ); /* 在根目录或者当前目录下新建文件,如果文件已经存在那么先删除 */ if ( s != USB_INT_SUCCESS ) return( s ); } else { /* 再次进入,目标文件已存在 */ printf( "OpenTar\n" ); CH376WriteVar32( VAR_START_CLUSTER, TarUpDirClust ); /* 将目标文件所在的上级目录的起始簇号设置为当前簇号,相当于打开上级目录 */ s = CH376FileOpen( &TarFileName[TarName] ); /* 打开文件 */ if ( s != USB_INT_SUCCESS ) return( s ); s = CH376ByteLocate( ByteCount ); /* 以字节为单位移动当前文件指针到上次复制结束位置 */ if ( s != USB_INT_SUCCESS ) return( s ); } printf( "Write\n" ); s = CH376ByteWrite( buf, ThisLen, NULL ); /* 以字节为单位向当前位置写入数据块,除非没有磁盘空间,否则返回实际长度总是与ThisLen相等 */ if ( s != USB_INT_SUCCESS ) return( s ); printf( "CloseTar\n" ); s = CH376FileClose( TRUE ); /* 关闭文件,对于字节读写建议自动更新文件长度 */ if ( s != USB_INT_SUCCESS ) return( s ); ByteCount += ThisLen; if ( ThisLen < sizeof( buf ) ) { /* 实际读出字节数小于请求读出字节数,说明原文件结束 */ if ( ByteCount != FileSize ) printf( "Error on SourceFile reading" ); break; } } while( ByteCount < FileSize ); return( USB_INT_SUCCESS ); }

main( ) {

UINT8 i, s; P_FAT_DIR_INFO pDir; UINT8 xdata SrcName[64]; UINT8 xdata TarName[64]; mDelaymS( 100 ); /* 延时100毫秒 */ mDelaymS( 100 ); mDelaymS( 100 ); mDelaymS( 100 ); mDelaymS( 100 ); mDelaymS( 100 ); mDelaymS( 100 ); mDelaymS( 100 ); mDelaymS( 100 ); mDelaymS( 100 );

mInitSTDIO( ); /* 为了让计算机通过串口监控演示过程 */ printf( "Start\n" );

s = mInitCH376Host( ); /* 初始化CH376 */ //SBUF=0xaa; mStopIfError( s ); /* 其它电路初始化 */

while ( 1 ) { printf( "Wait Udisk/SD\n" ); while ( CH376DiskConnect( ) != USB_INT_SUCCESS ) { /* 检查U盘是否连接,等待U盘插入,对于SD卡,可以由单片机直接查询SD卡座的插拔状态引脚 */ mDelaymS( 100 ); } mDelaymS( 200 ); /* 延时,可选操作,有的USB存储器需要几十毫秒的延时 */

/* 对于检测到USB设备的,最多等待100*50mS,主要针对有些MP3太慢,对于检测到USB设备并且连接DISK_MOUNTED的,最多等待5*50mS,主要针对DiskReady不过的 */ for ( i = 0; i < 100; i ++ ) { /* 最长等待时间,100*50mS */ mDelaymS( 50 ); printf( "Ready ?\n" ); s = CH376DiskMount( ); /* 初始化磁盘并测试磁盘是否就绪 */ if ( s == USB_INT_SUCCESS ) break; /* 准备好 */ else if ( s == ERR_DISK_DISCON ) break; /* 检测到断开,重新检测并计时 */ if ( CH376GetDiskStatus( ) >= DEF_DISK_MOUNTED && i >= 5 ) break; /* 有的U盘总是返回未准备好,不过可以忽略,只要其建立连接MOUNTED且尝试5*50mS */ } if ( s == ERR_DISK_DISCON ) { /* 检测到断开,重新检测并计时 */ printf( "Device gone\n" ); continue; } if ( CH376GetDiskStatus( ) < DEF_DISK_MOUNTED ) { /* 未知USB设备,例如USB键盘、打印机等 */ printf( "Unknown device\n" ); goto UnknownUsbDevice; } i = CH376ReadBlock( buf ); /* 如果需要,可以读取数据块CH376_CMD_DATA.DiskMountInq,返回长度 */ if ( i == sizeof( INQUIRY_DATA ) ) { /* U盘的厂商和产品信息 */ buf[ i ] = 0; printf( "UdiskInfo: %s\n", ((P_INQUIRY_DATA)buf) -> VendorIdStr ); }

/* 读取原文件 */ strcpy( SrcName, "\\C51\\CH376HFT.C" ); /* 源文件名,多级目录下的文件名和路径名必须复制到RAM中再处理,而根目录或者当前目录下的文件名可以在RAM或者ROM中 */ strcpy( TarName, "\\NEWFILE.TXT" ); /* 目标文件名 */ printf( "Open\n" ); s = CH376FileOpenPath( SrcName ); /* 打开文件,该文件在C51子目录下 */ if ( s == ERR_MISS_DIR || s == ERR_MISS_FILE ) { /* 没有找到目录或者没有找到文件 */ /* 列出文件,完整枚举可以参考EXAM13全盘枚举 */ if ( s == ERR_MISS_DIR ) strcpy( buf, "\\*" ); /* C51子目录不存在则列出根目录下的文件 */ else strcpy( buf, "\\C51\\CH376*" ); /* CH376HFT.C文件不存在则列出\C51子目录下的以CH376开头的文件 */ printf( "List file %s\n", buf ); s = CH376FileOpenPath( buf ); /* 枚举多级目录下的文件或者目录,输入缓冲区必须在RAM中 */ while ( s == USB_INT_DISK_READ ) { /* 枚举到匹配的文件 */ CH376ReadBlock( buf ); /* 读取枚举到的文件的FAT_DIR_INFO结构,返回长度总是sizeof( FAT_DIR_INFO ) */ pDir = (P_FAT_DIR_INFO)buf; /* 当前文件目录信息 */ if ( pDir -> DIR_Name[0] != '.' ) { /* 不是本级或者上级目录名则继续,否则必须丢弃不处理 */ if ( pDir -> DIR_Name[0] == 0x05 ) pDir -> DIR_Name[0] = 0xE5; /* 特殊字符替换 */ pDir -> DIR_Attr = 0; /* 强制文件名字符串结束以便打印输出 */ printf( "*** EnumName: %s\n", pDir -> DIR_Name ); /* 打印名称,原始8+3格式,未整理成含小数点分隔符 */ } xWriteCH376Cmd( CMD0H_FILE_ENUM_GO ); /* 继续枚举文件和目录 */ xEndCH376Cmd( ); s = Wait376Interrupt( ); } if ( s != ERR_MISS_FILE ) mStopIfError( s ); /* 操作出错 */ printf( "Create\n" ); s = CH376FileCrea


我感觉像是CH376连初始化的程序也没有通过,

整个程序就停在了开头初始化的部分,串口调试助手返回的应该是初始化时的printf的东西,不过为什么我就真的搞不清楚了


你按照这个说明文档来调试CH376芯片: UploadImages/20115181741359.rar


恩,我今晚仔细去研究一下。。。。你提供的手册。。。。

在这里我先发我的,硬件电路图,因为是做实验。。。所以用的是单面覆铜板 麻烦你帮我看一下有没有错误。。。

20115181810433.jpg


只有登录才能回复,可以选择微信账号登录