ch375调试问题

各位前辈: 我在调试CH375时遇到以下问题: 设置好内置固件模式后,安装驱动程序正常,USB设备枚举成功,用调试工具传数据时,程序也能进入中断,准备中断程序中看一下时否能正确接收数据,以为很顺利,可是发现问题了,用CH375_RD_DAT_PORT()读数据时,发现总是返回0xff,程序的都检查了好多次,还是这样,非常郁闷,为什么写命令和数据都能成功,可是读的时候不行了呢? 请那位好心我帮帮我啊,拜谢!

/******************************************* CH375B驱动程序V0.1 MCU:ATmega128L OSC:8MHz *******************************************/ #include "CH375INC.H" #include /******************************************* INT:pin26(PD1) CH375_CS:pin39(PC4),对于USB设备可以将此引脚接地 CH375_A0:pin40(PC5) CH375_WR:pin12(PB2) CH375_RD:pin13(PB3) ********************************************/

#define CH375_WR PORTB.2 #define CH375_RD PORTB.3 #define CH375_CS PORTC.4 #define CH375_A0 PORTC.5 #define CH375_DQ PORTA #define CH375_DQ1 PINA

void CH375_WR_CMD_PORT( unsigned char cmd ) { /* 向CH375的命令端口写入命令,周期不小于4uS,如果单片机较快则延时 */ DDRA = 0xff; DDRB |= 0x06; DDRC |= 0x30; delay_us(2); CH375_DQ = cmd; CH375_A0 = 1; //选择CH375的命令口 CH375_RD = 1; CH375_CS = 0; //使能ch375 CH375_WR = 0; #asm("NOP"); //CH375_WR产生宽度至少为80nS的低电平脉冲 CH375_WR = 1; CH375_CS = 1; CH375_A0 = 0; // DDRA = 0x00; //将数据端口置为输入 // PORTA = 0xff; //使能内部上拉电阻 delay_us(2); }

void CH375_WR_DAT_PORT( unsigned char dat ) { /* 向CH375的数据端口写入数据,周期不小于1.5uS,如果单片机较快则延时 */ DDRA = 0xff; DDRB |= 0x06; DDRC |= 0x30; delay_us(1); CH375_DQ = dat; CH375_A0 = 0; CH375_RD = 1; CH375_CS = 0; CH375_WR = 0; #asm("NOP"); //CH375_WR产生宽度至少为80nS的低电平脉冲 CH375_WR = 1; CH375_CS = 1; // DDRA = 0x00; // PORTA = 0xFF; //使能内部上拉电阻 delay_us(1); }

unsigned char CH375_RD_DAT_PORT(void) { /* 从CH375的数据端口读出数据,周期不小于1.5uS,如果单片机较快则延时 */ unsigned char dat = 0; DDRA = 0x00; //将数据端口设置为输入 DDRB |= 0x06; DDRC |= 0x30; CH375_A0 = 0; CH375_WR = 1; CH375_CS = 0; CH375_RD = 0; dat = PINA; CH375_RD = 1; CH375_CS = 1; return dat; }

void CH375_INIT() { unsigned char i; unsigned char str[10]; lcd_init(); /* 测试CH375是否正常工作,可选操作,通常不需要 */ CH375_WR_CMD_PORT(CMD_CHECK_EXIST); //测试CH375是否正常工作 CH375_WR_DAT_PORT(0x55); //写入测试数据 i = CH375_RD_DAT_PORT(); //返回数据应该是测试数据取反 sprintf(str,"#######%x",i); print_str(1,0,str); if(i != ~0x55) { /* CH375不正常 */ for ( i=80; i!=0; i-- ) { CH375_WR_CMD_PORT(CMD_RESET_ALL); //多次重复发命令,执行硬件复位 */ CH375_RD_DAT_PORT(); } CH375_WR_CMD_PORT(0); delay_ms(50); //延时50ms } CH375_WR_CMD_PORT(CMD_SET_USB_MODE); CH375_WR_DAT_PORT(0x02); //设置为使用内置固件的USB设备方式 */ delay_us(20); if(CH375_RD_DAT_PORT() == CMD_RET_SUCCESS) { sprintf(str,"枚举成功!"); print_str(1,0,str); } /*******************外部中断1初始化*************************/ EIMSK = 0x02; //使用外部中断1 EICRA &= 0xf3; //低电平触发 #asm("sei"); //开全局中断使能 }

[b]文字[/b][size=6]文字[/size][b]文字[/b]

是在什么中断状态下,调用CH375_RD_DAT_PORT()读数据的?从程序中没看出来,一般是下传中断,才可以去读数据


USB从机问题已经解决,问题出在控制信号上引脚上,程序中引脚没有和硬件对应好! /////////////////////////////////////////////////////////////////////////////////

现在开始调试USB主机,用的U盘是爱国者,64M的,调试过程遇到下面的问题: 1.初始化U盘后,插上U盘,ch375的ACK引脚成低电平指示灯亮,U盘指示灯亮,请问是不是说明U盘已经连接成功? 2.再识别U盘,就是读U盘扇区ReadSector(0,1,diskbuff);diskbuff[0]读到的数据是0x1d,请问WCH的工程师 if(diskbuff[0]==0xeb||diskbuff[0]==0xe9) 这句话是什么意思?望指教!! 3.DeviceInfo.StartSector = LSwapINT32(diskbuff[454],diskbuff[455],diskbuff[456],diskbuff[457]); 执行完这句话后,StartSector 变成0x0000,也就是说从diskbuff[454]到diskbuff[457]这四个字节数据都是0 了,这又是什么意思呢?不吝啬 //********************************************************************* //读取U盘扇区: //addr_start 为起始扇区地址 //sector_cntcnt 为要读取的扇区数 //read_buf 为读取数据的缓冲区 //********************************************************************* uchar ReadSector(uint32 addr_start,uchar sector_cnt,uchar *read_buf) { uchar status; uint16 blockcnt; CH375_WR_CMD_PORT(CMD_DISK_READ); //从USB存储器读数块 CH375_WR_DAT_PORT((uchar)addr_start); //写入起始扇区地址 CH375_WR_DAT_PORT((uchar)(addr_start>>8)); CH375_WR_DAT_PORT((uchar)(addr_start>>16)); CH375_WR_DAT_PORT((uchar)(addr_start>>24)); CH375_WR_DAT_PORT(sector_cnt); //写入扇区数 for(blockcnt=(uint16)sector_cnt*8;blockcnt!=0;blockcnt--) { status = WaitInterrupt(); //等待中断并获取状态 if(status == USB_INT_DISK_READ) { CH375_WR_DAT_PORT(CMD_RD_USB_DATA); //从CH375缓冲区读取数据块 status = CH375_RD_DAT_PORT(); //读取数据块的长度 while(status--) //读取U盘数据到单片机缓冲区 { *(read_buf++) = CH375_RD_DAT_PORT(); } CH375_WR_CMD_PORT(CMD_DISK_RD_GO);//继续执行USB存储器的读操作 } else break; } if(blockcnt==0) { status = WaitInterrupt(); if(status == USB_INT_SUCCESS) { return 0; //操作成功,返回0 } } return status; //返回错误状态 } /************************************************************************** 初始化U盘 **************************************************************************/ uchar InitDisk() { uchar status; CH375_WR_CMD_PORT(CMD_GET_STATUS); //获取设备状态 status = CH375_RD_DAT_PORT(); if(status == USB_INT_DISCONNECT) //若U盘拔出,程序退出 { return status; } CH375_WR_CMD_PORT(CMD_DISK_INIT); //初始化USB存储器 status = WaitInterrupt(); //等待中断并获取状态 if(status != USB_INT_SUCCESS) { return status; } CH375_WR_CMD_PORT(CMD_DISK_SIZE); //获取USB存储器容量 status = WaitInterrupt(); //等待中断并获取状态 if(status != USB_INT_SUCCESS) { delay_ms(250); CH375_WR_CMD_PORT(CMD_DISK_SIZE); //出错重试 status = WaitInterrupt(); } if(status != USB_INT_SUCCESS) { return status; } return 0; //初始化成功 } /************************************************************************** 识别U盘 **************************************************************************/ uchar IdentifyDisk() { uchar status; unsigned int ReservedSectorsNum; DeviceInfo.BPB_BytesPerSec=512; //每扇区字节数据暂假设为512 //DeviceInfo.BPB_BytesPerSec status = ReadSector(0,1,diskbuff); if(status!=0) { return status; } if(diskbuff[0]==0xeb||diskbuff[0]==0xe9) { DeviceInfo.StartSector = 0; } else { sprintf(str,"%04x",diskbuff[0]); print_str(2,0,str); DeviceInfo.StartSector = LSwapINT32(diskbuff[454],diskbuff[455],diskbuff[456],diskbuff[457]); status = ReadSector(DeviceInfo.StartSector,1,diskbuff); if(status != 0) { return status; } sprintf(str,"%04x",DeviceInfo.StartSector); print_str(2,2,str); } sprintf(str,"%x",diskbuff[82]); print_str(2,4,str); DeviceInfo.BPB_BytesPerSec=LSwapINT16(diskbuff[11],diskbuff[12]); //每扇区字节数 DeviceInfo.BPB_SecPerClus=diskbuff[13]; //每簇扇区数 ReservedSectorsNum=LSwapINT16(diskbuff[14],diskbuff[15]); //保留区扇区个数 DeviceInfo.BPB_NumFATs=diskbuff[16]; //FAT表占用扇区数 if(diskbuff[82]=='F'&&diskbuff[83]=='A'&&diskbuff[84]=='T'&&diskbuff[85]=='3'&&diskbuff[86]=='2') { DeviceInfo.BPB_TotSec32=LSwapINT32(diskbuff[32],diskbuff[33],diskbuff[34],diskbuff[35]); DeviceInfo.BPB_FATSz32=LSwapINT32(diskbuff[36],diskbuff[37],diskbuff[38],diskbuff[39]); DeviceInfo.RootStartCluster=LSwapINT32(diskbuff[44],diskbuff[45],diskbuff[46],diskbuff[47]); DeviceInfo.FatStartSector=DeviceInfo.StartSector+ReservedSectorsNum; DeviceInfo.FirstDataSector=DeviceInfo.FatStartSector+DeviceInfo.BPB_NumFATs*DeviceInfo.BPB_FATSz32; DeviceInfo.TotCluster=(DeviceInfo.BPB_TotSec32-DeviceInfo.FirstDataSector+1)/DeviceInfo.BPB_SecPerClus+1; // DirStartCluster32=DeviceInfo.RootStartCluster; DeviceInfo.FAT=1; //FAT16=0,FAT32=1; sprintf(str,"Disk Enum success!"); print_str(2,0,str); } else { DeviceInfo.BPB_RootEntCnt=LSwapINT16(diskbuff[17],diskbuff[18]); DeviceInfo.BPB_RootEntCnt=(DeviceInfo.BPB_RootEntCnt)*32/DeviceInfo.BPB_BytesPerSec; DeviceInfo.BPB_TotSec16=LSwapINT16(diskbuff[19],diskbuff[20]); DeviceInfo.BPB_FATSz16=LSwapINT16(diskbuff[22],diskbuff[23]); DeviceInfo.FatStartSector=DeviceInfo.StartSector+ReservedSectorsNum; DeviceInfo.RootStartSector=DeviceInfo.StartSector+DeviceInfo.BPB_NumFATs*DeviceInfo.BPB_FATSz16+ReservedSectorsNum; DeviceInfo.FirstDataSector=DeviceInfo.FatStartSector+DeviceInfo.BPB_NumFATs*DeviceInfo.BPB_FATSz16+DeviceInfo.BPB_RootEntCnt; DeviceInfo.FAT=0; } return 0; }


if(diskbuff[0]==0xeb||diskbuff[0]==0xe9) 一般来说DBR的数据也就是逻辑盘的第0号扇区的数据开始就是0XEB,0XE9,您可以下载WINHEX这个软件去看看就知道了.网上很容易下载到. 第2个问题: 对有MBR的U盘来说,这是来计算从磁盘开始到本分区的扇区数,相对扇区数( 从该磁盘的开始到该分区的开始的位移量,以扇区来计算


谢谢,读写扇区问题已经解决了,

请问如果我想支持读写FAT32格式的文件该如果操作,看了一下,似乎非学复杂!

对了,我没有用沁恒提供的库,底层的驱动都是通过实例文档自己写的,不知道你没有好的方法来读写U盘文件


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