请教CH376休眠后不能唤醒,多谢!

弄了一天了,是在是找不到原因了,大家帮忙检查下,多谢!

unsigned char ucTest; void UsbSleepEnable(BOOL bFlag) { if(bFlag) //sleep { xWriteCH376Cmd ( CMD_ENTER_SLEEP ); } else //唤醒 { xWriteCH376Cmd ( CMD_GET_IC_VER ); ucTest=xReadCH376Data(); } }

void TestFunc(void) { UsbSleepEnable(TRUE); DelayMs(250); while(1) { DelayMs(10); UsbSleepEnable(FALSE); if(ucTest == 0x41) break; //正常运行时测试过版本号为0x41 } }

我用的是串口,发送CMD_ENTER_SLEEP(0x03)的命令后CH376进入休眠状态,但是怎么也唤醒不了,无论给CH376发送什么数据,CH376没有任何反应...

1、是怎么判断没唤醒的?版本不对?CH376芯片从低功耗状态退出并恢复到正常工作状态需要几毫秒的唤醒时间,当完全恢复到正常工作状态后,CH376将产生USB_INT_WAKE_UP 事件中断,这时再获取版本看一下 2、执行UsbSleepEnable(FALSE)后,用示波器查看一下晶振是否起振


用示波器测试了一下晶振的引脚,休眠前后晶振启震正常,为12MHz 为检测USB_INT_WAKE_UP事件中断,将Test函数修改如下,但是还是无法退出 void TestFunc(void) { UsbSleepEnable(TRUE); DelayMs(250); while(1) { DelayMs(10); UsbSleepEnable(FALSE); if(ucTest == 0x41) break; //正常运行时测试过版本号为0x41 DelayMs(10); if ( Query376Interrupt( ) ) CH376GetIntStatus( ); // 检测到中断 ,获取中断状态码并取消中断 } } 我设置断点检查过,写入CMD_ENTER_SLEEP(0x03)的命令后CH376进入休眠状态,之后没有检测到任何中断,包括中断引脚和串口


如果设置休眠状态成功,那么CH376的晶振是不起振的, 如果要唤醒发送CMD_GET_IC_VER 即可。恢复正常之后才会产生中断。

UsbSleepEnable(TRUE); DelayMs(250); xWriteCH376Cmd ( CMD_GET_IC_VER ); while(Query376Interrupt( )); //等待唤醒中断 ..........................


回study: 休眠时,CH376的晶振不起振,从电流上看,执行UsbSleepEnable(TRUE)后CH376进入了休眠状态,执行xWriteCH376Cmd(CMD_GET_IC_VER)后CH376被唤醒,但是就在while(Query376Interrupt() == FALSE)那里停住了,跳不出来。 现在我又试了另外一种唤醒方法:U盘唤醒 voit TestFunc(void) { xWriteCH376Cmd ( CMD_ENTER_SLEEP ); DelayMs(250); while(Query376Interrupt() == FALSE); //等待U盘插入 } 当U盘插入时,仍然跳不出while...


程序停在了while() 循环当中,这时候量CH376的中断引脚电平,是不是低电平,另外把Query376Interrupt()贴出来看看。


在Query376Interrupt()函数中采用的是查询串口中断的方法,唤醒后用万用表测中断引脚电平为低。 现将测试过程及现象整理如下: 1、初始化成功,波特率设置为9600,电流为12mA,中断引脚为高电平。 2、当xWriteCH376Cmd ( CMD_ENTER_SLEEP ); 后用示波器测量晶振引脚不起振,电流为4mA(因为是接在仿真器上的,MCU的端口没有处理,所以存在漏电流),中断引脚为高电平。 3、写命令xWriteCH376Cmd ( CMD_GET_IC_VER );或者插入U盘,晶振起振,电流恢复到12mA或加上U盘电流,中断引脚为低电平。 4、虽然从种种现象看,CH376被唤醒,但是串口上检测不到任何操作,并且执行CH376GetIntStatus()也无任何反应。 /* 查询CH376中断(INT#低电平) */ UINT8 Query376Interrupt( void ) { #ifdef CH376_INT_WIRE //没有定义 return( CH376_INT_WIRE ? FALSE : TRUE ); /* 如果连接了CH376的中断引脚则直接查询中断引脚 */ #else if ( _CheckRxEnd() ) { /* 如果未连接CH376的中断引脚则查询串口中断状态码 */ _ClrRxPending(); return( TRUE ); } else return( FALSE ); #endif } void TestFunc(void) { //初始化成功 DelayMs(250); //断点0 -- 测试过,CH376工作正常 xWriteCH376Cmd ( CMD_ENTER_SLEEP ); DelayMs(250); //断点1 -- 能检测到CH376进入休眠状态 xWriteCH376Cmd ( CMD_GET_IC_VER ); //此处可以换作U盘唤醒 DelayMs(250); //断点2 -- 能检测到CH376被唤醒,但是如果是U盘插入指示灯没有点亮 while( 1 ) { if(Query376Interrupt( )) //中断引脚能检测到低电平,但是串口上无任何反应 { if(CH376GetIntStatus();) break; //只要返回非0则退出 } DelayMs(250); } } 另外发现一个现象,如果被唤醒(断点2)之后,再通过RESET引脚复位,并重新配置一下CH376,再读一次中断状态码CH376GetIntStatus(),读出的值是0x06,即USB_INT_WAKE_UP。


苍天啊,大地啊,就差最后一步了啊,好心人,大侠小虾帮帮忙啊...


中断引脚为低电平,说明已经产生唤醒中断,只是你程序没有检测到而已,为什么要在发送CMD_GET_IC_VER 之后设置断点呢? 程序上面看不出来你 有没有使用CH376的中断引脚。 void TestFunc(void) { //初始化成功 DelayMs(250); //断点0 -- 测试过,CH376工作正常 xWriteCH376Cmd ( CMD_ENTER_SLEEP ); DelayMs(250); //断点1 -- 能检测到CH376进入休眠状态 xWriteCH376Cmd ( CMD_GET_IC_VER ); //此处可以换作U盘唤醒 while(Query376Interrupt( ) == FALSE ); DelayMs(250); //设置断点2 }

UINT8 Query376Interrupt( void ) { if ( _CheckRxEnd() ) { /* 如果未连接CH376的中断引脚则查询串口中断状态码 */ _ClrRxPending(); return( TRUE ); } else return( FALSE ); }


回study: “为什么要在发送CMD_GET_IC_VER 之后设置断点呢?” 因为是为了测中断引脚电平,但是撤销断点2,串口也是接收不到数据。 “中断引脚为低电平,说明已经产生唤醒中断,只是你程序没有检测到而已” 对,中断引脚有变化,而串口检测不到数据,所以现在的问题是:我这边的MCU接收不到数据的原因是--CH376没有发送、还是MCU没有接收到(对了,可以用示波器看看)?还是协议部分的原因,比如波特率需要重置... 在唤醒后并且延时一段时间,然后跳过Query376Interrupt()而直接用CH376GetIntStatus()读中断状态码也无法读到数据...给人的感觉好像就是串口罢工了一样...


用示波器测试过,CH376被唤醒后,中断引脚输出低电平,串口无输出


新建文件夹\USB01.bmp 新建文件夹\USB02.bmp 新建文件夹\USB03.bmp


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