求助CH372芯片的程序设计

首先,对于一个不会上位机程序的来说,如何调试单片机的上传数据程序, 目前我要实现的方案是: 单片机接收到一段数据后,将此数据上传给PC机,请问如何实现? 我下载并查阅了贵公司提供的相关例程,还是没有解决这个问题,主要问题有 1、采用CH372DBG里面的DEBUG372调试时,点击上传时只有一组最多64字节数据上传,而我需要完成的是1000甚至更多的数据上传,不知该如何实现? 2、运行CH372EVT里的TEST程序,里面的内容不太明了,没有达到TEST的功能,能否配合图片解释一下具体的应用说明,谢谢。

不会上位机,你只能简单调试。我们提供的程序不可能完全符合客户的需求。只做参考。 仔细看看说明书,和程序,有什么不明白的地方可以提问,但是要做图片解释,这个工作量也太大。为提高效率,你可以先参考程序不明白的地方发帖或电话询问


根据提供的程序 调试后 DEBUG372 能够实现上传和下传。 我自己修改了下程序 /* CH375中断服务程序,使用寄存器组1 */ void __attribute__((interrupt, auto_psv)) _INT1Interrupt(void) { unsigned char InterruptStatus; unsigned char i, length; unsigned char buffer[ 64 ]={0}; xWriteCH376Cmd( CMD_GET_STATUS ); /* 获取中断状态并取消中断请求 */ InterruptStatus = xReadCH376Data( ); /* 获取中断状态 */ switch ( InterruptStatus ) { /* 分析中断状态处理 */ case USB_INT_EP2_OUT: { /* 批量端点下传成功 */ xWriteCH376Cmd( CMD_RD_USB_DATA ); /* 从当前USB中断的端点缓冲区读取数据块,并释放缓冲区 */ length = xReadCH376Data( ); /* 首先读取后续数据长度 */ for ( i = 0; i < length; i ++ ) buffer[ i ] = xReadCH376Data( ); /* 接收数据包 */ /* 测试数据正确性,将接收到的命令包数据取反后返回给PC机 */ xWriteCH376Cmd( CMD_WR_USB_DATA7 ); /* 向USB端点2的发送缓冲区写入数据块 */ xWriteCH376Data( length ); /* 首先写入后续数据长度,回传刚接收到的数据长度 */ for ( i = 0; i < length; i ++ ) xWriteCH376Data( ~ buffer[ i ] ); /* 数据取反后返回,由计算机应用程序测试数据是否正确 */ break; } case USB_INT_EP2_IN: { /* 批量数据发送成功 */ xWriteCH376Cmd( CMD_UNLOCK_USB ); /* 释放当前USB缓冲区 */ FLAG_SEND_WAIT = 1; xWriteCH376Cmd( CMD_WR_USB_DATA7 ); /* 向USB端点2的发送缓冲区写入数据块 */ xWriteCH376Data( 60 ); /* 首先写入后续数据长度,回传刚接收到的数据长度 */ for ( i = 0; i < 60; i ++ ) xWriteCH376Data( i ); /* 数据取反后返回,由计算机应用程序测试数据是否正确 */ break; } default: { /* 其它中断,未用到,解锁后退出即可 */ xWriteCH376Cmd( CMD_UNLOCK_USB ); /* 释放当前USB缓冲区 */ break; } } }

void main() { unsigned char i; CH376DeviceInit( ); /* 初始化USB设备模式 */

mDelaymS(100); while(1);

} 这个程序能够 点上传能够收到数据,每次都可以收到60个数据。 而我进行修改后,将发送数据程序放到主程序后上传不能收到数据 这是为什么? /* CH375中断服务程序,使用寄存器组1 */ void __attribute__((interrupt, auto_psv)) _INT1Interrupt(void) { unsigned char InterruptStatus; unsigned char i, length; unsigned char buffer[ 64 ]={0}; xWriteCH376Cmd( CMD_GET_STATUS ); /* 获取中断状态并取消中断请求 */ InterruptStatus = xReadCH376Data( ); /* 获取中断状态 */ switch ( InterruptStatus ) { /* 分析中断状态处理 */ case USB_INT_EP2_OUT: { /* 批量端点下传成功 */ xWriteCH376Cmd( CMD_RD_USB_DATA ); /* 从当前USB中断的端点缓冲区读取数据块,并释放缓冲区 */ length = xReadCH376Data( ); /* 首先读取后续数据长度 */ for ( i = 0; i < length; i ++ ) buffer[ i ] = xReadCH376Data( ); /* 接收数据包 */ /* 测试数据正确性,将接收到的命令包数据取反后返回给PC机 */ xWriteCH376Cmd( CMD_WR_USB_DATA7 ); /* 向USB端点2的发送缓冲区写入数据块 */ xWriteCH376Data( length ); /* 首先写入后续数据长度,回传刚接收到的数据长度 */ for ( i = 0; i < length; i ++ ) xWriteCH376Data( ~ buffer[ i ] ); /* 数据取反后返回,由计算机应用程序测试数据是否正确 */ break; } case USB_INT_EP2_IN: { /* 批量数据发送成功 */ xWriteCH376Cmd( CMD_UNLOCK_USB ); /* 释放当前USB缓冲区 */ FLAG_SEND_WAIT = 1; break; } default: { /* 其它中断,未用到,解锁后退出即可 */ xWriteCH376Cmd( CMD_UNLOCK_USB ); /* 释放当前USB缓冲区 */ break; } } }

void main() { unsigned char i; CH376DeviceInit( ); /* 初始化USB设备模式 */

mDelaymS(100); // while(1); while(1) { // mDelaymS(10); while(!FLAG_SEND_WAIT); FLAG_SEND_WAIT = 0; xWriteCH376Cmd( CMD_WR_USB_DATA7 ); /* 向USB端点2的发送缓冲区写入数据块 */ xWriteCH376Data( 60 ); /* 首先写入后续数据长度,回传刚接收到的数据长度 */ for ( i = 0; i < 60; i ++ ) xWriteCH376Data( i ); /* 数据取反后返回,由计算机应用程序测试数据是否正确 */

}

}


FLAG_SEND_WAIT变量默认的值是多少?第一次需要你先写数据给CH376之后才会产生批量端点上传的中断,否则第一次是不会产生批量端点上传的中断的。


你对CH372产生中断的原因还不了解 当PC下发数据完毕后,CH372会产生中断,通知MCU读取数据 当一包数据成功上传给PC后,CH372会产生中断。 你的程序要先下传数据,然后点击上传才会产生上传中断。


下位机流程这样设计是否有问题? 1、CH372设备模式初始化完成; 2、xWriteCH376Cmd( CMD_WR_USB_DATA7 ),发送数据; 3、等待CH372产生的上传中断后,再发送下一组数据。

FLAG_SEND_WAIT 默认值为1;


这个流程忽略了一个问题:CH372在被枚举成功之前,写入的上传数据是无效的,你的程序就存在这个问题 可以先下传一包数据,通知下位机已经枚举完成,这时才能上传


“CH372在被枚举成功之前,写入的上传数据是无效的,你的程序就存在这个问题 可以先下传一包数据,通知下位机已经枚举完成”

下位机如何知道已经枚举成功;很困惑,上面两程序唯一的区别就在于发送程序一放于中断内,和采用查询方式在发送程序写在主程序中。 以下是我根据SCM提的意见 重新修改的程序。

/* CH375中断服务程序,使用寄存器组1 */ void __attribute__((interrupt, auto_psv)) _INT1Interrupt(void) { unsigned char InterruptStatus; unsigned char i, length; unsigned char buffer[ 64 ]={0}; xWriteCH376Cmd( CMD_GET_STATUS ); /* 获取中断状态并取消中断请求 */ InterruptStatus = xReadCH376Data( ); /* 获取中断状态 */ switch ( InterruptStatus ) { /* 分析中断状态处理 */ case USB_INT_EP2_OUT: { /* 批量端点下传成功 */ xWriteCH376Cmd( CMD_RD_USB_DATA ); /* 从当前USB中断的端点缓冲区读取数据块,并释放缓冲区 */ length = xReadCH376Data( ); /* 首先读取后续数据长度 */ for ( i = 0; i < length; i ++ ) buffer[ i ] = xReadCH376Data( ); /* 接收数据包 */ FLAG_SEND_WAIT = 1; /* 测试数据正确性,将接收到的命令包数据取反后返回给PC机 */ // xWriteCH376Cmd( CMD_WR_USB_DATA7 ); /* 向USB端点2的发送缓冲区写入数据块 */ // xWriteCH376Data( length ); /* 首先写入后续数据长度,回传刚接收到的数据长度 */ // for ( i = 0; i < length; i ++ ) xWriteCH376Data( ~ buffer[ i ] ); /* 数据取反后返回,由计算机应用程序测试数据是否正确 */ break; } case USB_INT_EP2_IN: { /* 批量数据发送成功 */ xWriteCH376Cmd( CMD_UNLOCK_USB ); /* 释放当前USB缓冲区 */ FLAG_SEND_WAIT = 1; // xWriteCH376Cmd( CMD_WR_USB_DATA7 ); /* 向USB端点2的发送缓冲区写入数据块 */ // xWriteCH376Data( 60 ); /* 首先写入后续数据长度,回传刚接收到的数据长度 */ // for ( i = 0; i < 60; i ++ ) xWriteCH376Data( i ); /* 数据取反后返回,由计算机应用程序测试数据是否正确 */

break; } default: { /* 其它中断,未用到,解锁后退出即可 */ xWriteCH376Cmd( CMD_UNLOCK_USB ); /* 释放当前USB缓冲区 */ break; } } }

void main() { unsigned char i; CH376DeviceInit( ); /* 初始化USB设备模式 */ FLAG_SEND_WAIT = 0; mDelaymS(100); // while(1); while(1) { // mDelaymS(10); while(!FLAG_SEND_WAIT); FLAG_SEND_WAIT = 0; xWriteCH376Cmd( CMD_WR_USB_DATA7 ); /* 向USB端点2的发送缓冲区写入数据块 */ xWriteCH376Data( 60 ); /* 首先写入后续数据长度,回传刚接收到的数据长度 */ for ( i = 0; i < 60; i ++ ) xWriteCH376Data( i ); /* 数据取反后返回,由计算机应用程序测试数据是否正确 */

}

} 程序修改成这样,流程应该是对了吧?? 怎么还是收不到上传数据


你首先需要下传数据之后才能计算机才能接收到你发送的数据。按照程序来讲的话应该没什么问题了。


收不到上传数据, 现象是单片机没有收到 批量数据发送成功 的中断;


先前说修改我们的例程是能够下传数据的,现在对比一下程序上作了哪些改动,这个解决了就能上传数据了


void main() { unsigned char i; mDelaymS(100); CH376DeviceInit( ); /* 初始化USB设备模式 */ FLAG_SEND_WAIT = 0; mDelaymS(100); mDelaymS(100); mDelaymS(100); mDelaymS(100); mDelaymS(100); mDelaymS(100); mDelaymS(100); mDelaymS(100); mDelaymS(100); // while(1); while(1) { //while(!FLAG_SEND_WAIT);//程序不就死在这里了吗???,没机会写数据了!!!!! //FLAG_SEND_WAIT = 0;

xWriteCH376Cmd( CMD_WR_USB_DATA7 ); /* 向USB端点2的发送缓冲区写入数据块 */ xWriteCH376Data( 60 ); /* 首先写入后续数据长度,回传刚接收到的数据长度 */ for ( i = 0; i < 60; i ++ ) xWriteCH376Data( i ); /* 数据取反后返回,由计算机应用程序测试数据是否正确 */ while(FLAG_SEND_WAIT == 0); FLAG_SEND_WAIT = 0; }

}


是这样的 当我使用下面的程序时是能够收到上传数据的。 case USB_INT_EP2_OUT: { /* 批量端点下传成功 */ xWriteCH376Cmd( CMD_RD_USB_DATA ); /* 从当前USB中断的端点缓冲区读取数据块,并释放缓冲区 */ length = xReadCH376Data( ); /* 首先读取后续数据长度 */ for ( i = 0; i < length; i ++ ) buffer[ i ] = xReadCH376Data( ); /* 接收数据包 */ FLAG_SEND_WAIT = 1; /* 测试数据正确性,将接收到的命令包数据取反后返回给PC机 */ xWriteCH376Cmd( CMD_WR_USB_DATA7 ); /* 向USB端点2的发送缓冲区写入数据块 */ xWriteCH376Data( length ); /* 首先写入后续数据长度,回传刚接收到的数据长度 */ for ( i = 0; i < length; i ++ ) xWriteCH376Data( ~ buffer[ i ] ); /* 数据取反后返回,由计算机应用程序测试数据是否正确 */ break; }

而将上面程序中下面几句屏蔽后就收不到上传数据了 // xWriteCH376Cmd( CMD_WR_USB_DATA7 ); /* 向USB端点2的发送缓冲区写入数据块 */ // xWriteCH376Data( length ); /* 首先写入后续数据长度,回传刚接收到的数据长度 */ // for ( i = 0; i < length; i ++ ) xWriteCH376Data( ~ buffer[ i ] ); /* 数据取反后返回,由计算机应用程序测试数据是否正确 */

实际上两个程序唯一的区别就在于一个在中断内,一个在主程序内运行, 我一直没找到到底是什么原因啊


那到底有没有收到下传的数据?


在CH372设置成模式2之后,加上这部分数据之后在进行数据上传你看下还有没有问题: CH375_WR_CMD_PORT(0x15);//设置设备模式 CH375_WR_DAT_PORT(0x02);//设置内置固件模式 while(1){ //下面的判断可能很花时间,在计算机主动通信的时候可以不需要这个步骤,建议加上 mDelaymS(50); CH375_WR_CMD_PORT(0x0a); CH375_WR_DAT_PORT(0x20);//这边判断计算机是否准备好,时间在500MS,所以应该在500MS以上 _nop_( ); c=CH375_DAT_PORT; if((c&0x20)==0x20)break; }


可能我没表述清楚, 根据你们提供的例程 修改过后,用DEBUG372进行测试时, 上传和下传数据都没有问题; 而我将中断里面的 // xWriteCH376Cmd( CMD_WR_USB_DATA7 ); /* 向USB端点2的发送缓冲区写入数据块 */ // xWriteCH376Data( length ); /* 首先写入后续数据长度,回传刚接收到的数据长度 */ // for ( i = 0; i < length; i ++ ) xWriteCH376Data( ~ buffer[ i ] ); /* 数据取反后返回,由计算机应用 此段程序屏蔽后,放到主程序中运行后,结果是单片机能够收到DEBUG372的下传数据,但DEBUG372收不到单片机发送的上传数据。

并且如果上传或者下传不成功的话,DEBUG372的按钮也会处于灰色状态。


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