关于中断的问题,请教hcn!

又来麻烦hcn了:

take_pin();//先发送令牌 do{ if(CH375_INT_WIRE==0) intt0(); //接收数据 } while(1);

请问为什么我接上扫描枪后,执行程序,即使令上面程序段(main函数中一部分)中CH375_INT_WIRE==1,程序仍会运行到intt0()中呢? 这个中断好象不管用啊?

你是怎么知道在中断脚为高的时候还会执行下面的函数呢?


hcn: 是这样的,我在下面的一个子函数里设置了断点,发现最后程序运行到那个地方停止。这不能说明么?


实际上是这样的,上面的发送令牌的函数发送完成之后,在下面的循环就一直等待设备给主机来中断,如果没中断的话就一直在那循环,你在 CH375_WR_CMD_PORT( CMD_GET_STATUS ); /* 产生操作完成中断, 获取中断状态 */ 命令之前设置一个断点,在程序运行到这个之前的时候,你测下375的INT脚为低电平吗? 在这个命令之后,375就将INT#脚由低电平变为高电平了,所以在后面的操作的时候,INT#脚的电压都是高电平


hcn: 这个我是知道的,现在有这么一个问题: USB键盘程序里好像看不到键盘数据在何时被接收? void intt0() { unsigned char len_temp,status,i; unsigned char *BUF=buffer_r; CH375_WR_CMD_PORT( CMD_GET_STATUS ); /* 产生操作完成中断, 获取中断状态 */ status=CH375_RD_DAT_PORT();//printf("%02x ",(unsigned int)status);printf("\n"); if(status!=USB_INT_SUCCESS)//&&((status&0xf0)==0x20)) { CH375_WR_CMD_PORT( CMD_CLR_STALL );//printf("13\n"); CH375_WR_DAT_PORT(1); /* 如果设备端不是CH37X芯片,那么需要修改端点号 */ toggle_recv(1); issue_token_s(( endp_int << 4 ) | DEF_USB_PID_IN);//发送从中断端点读数据的令牌 } else len_temp=rd_usb_data(buffer_r); //键盘中断端点数据长度一般为8字节,鼠标为4字节 for(i=0;i!=8;i++)printf("%02x ",(unsigned int)buffer_r[i]); printf("\n"); // flag_output=0; tank=((~tank)&0x01); toggle_recv(tank); issue_token_s(( endp_int << 4 ) | DEF_USB_PID_IN);//发送从中断端点读数据的令牌 }

这个数据接收子函数里,好像只能看到接收数据,但似乎看不到判别用键盘键入数据这个动作。


else len_temp=rd_usb_data(buffer_r); //键盘中断端点数据长度一般为8字节,鼠标为4字节 就是接收数据,因为键盘一次上传的数据就8个字节,所以直接就可以一次读出来就可以了。


hcn: 我的意思是说按一下键是否能产生中断,以便于让系统知道有数据了,然后开始接收。 如果按您的意思,那系统怎么才能知道有数据可以接收呢? 可能我表达的不尽完整,叙述不到位。


产生了中断就说明有数据了,这时候就可以通过单片机来读取数据了。


hcn: 哪个地方的中断表示有数据了? 应该不是主函数 take_pin(); //先发送令牌 do{ if(CH375_INT_WIRE==0) intt0(); //接收数据 }while(1); 中这个if(CH375_INT_WIRE==0)语句啊; 或者是issue_token_s( ( endp_int << 4 ) | DEF_USB_PID_IN );这个命令吗? 而在接收数据的子函数intt0()里也没看到有这样的中断啊; 所以我觉得应该是少了一个等待扫描枪的中断语句。 不知我的想法对不对。


hcn: 是不是这样,您看对不对? take_pin();//先发送令牌 do{ if(CH375_INT_WIRE==0) intt0(); //接收数据 }while(1); take_pin();语句发IN事务命令,而后if(CH375_INT_WIRE==0)语句判断是否有数据来中断对吗?

但是有个问题,紧接着在intt0();子函数里 CH375_WR_CMD_PORT( CMD_GET_STATUS ); /* 产生操作完成中断, 获取中断状态 */ status=CH375_RD_DAT_PORT(); if(status!=USB_INT_SUCCESS) 这几个语句是否重复判断了?


你仔细看下芯片资料说明,来了中断之后,在中断里面要先读取中断状态,当发送读取中断状态的命令的时候,当读取完中断状态之后,375就将中断引脚拉高,不存在冲突的问题,仔细看芯片资料说明,里面有详细的读取中断的流程


hcn: 那您能指出哪个中断是判别来数据的吗? 麻烦了。 我就是太笨,呵呵。


intt0(); 函数就是判断是数据,前面的中断都不是


hcn:

void intt0() { unsigned char len_temp,status,i; unsigned char *BUF=buffer_r; CH375_WR_CMD_PORT( CMD_GET_STATUS ); /* 产生操作完成中断, 获取中断状态 */ status=CH375_RD_DAT_PORT();//printf("%02x ",(unsigned int)status);printf("\n"); if(status!=USB_INT_SUCCESS)//&&((status&0xf0)==0x20)) { CH375_WR_CMD_PORT( CMD_CLR_STALL );//printf("13\n"); CH375_WR_DAT_PORT(1); /* 如果设备端不是CH37X芯片,那么需要修改端点号 */ toggle_recv(1); issue_token_s(( endp_int << 4 ) | DEF_USB_PID_IN);//发送从中断端点读数据的令牌 } else len_temp=rd_usb_data(buffer_r); //键盘中断端点数据长度一般为8字节,鼠标为4字节 for(i=0;i!=8;i++)printf("%02x ",(unsigned int)buffer_r[i]); printf("\n"); // flag_output=0; tank=((~tank)&0x01); toggle_recv(tank); issue_token_s(( endp_int << 4 ) | DEF_USB_PID_IN);//发送从中断端点读数据的令牌 }

这里头的status是不是就是判断数据到了没到呢?如果数据到了,status就为USB_INT_SUCCESS吗?然后就开始接收数据,对吗?


如果status==USB_INT_SUCCESS就说明有数据了


hcn: unsigned char len_temp=4; void intt1() { unsigned char status,i,tank=1; unsigned char *BUF=buffer; CH375_WR_CMD_PORT( CMD_GET_STATUS ); /* 产生操作完成中断, 获取中断状态 */ status=CH375_RD_DAT_PORT(); while(status!=USB_INT_SUCCESS) { CH375_WR_CMD_PORT( CMD_CLR_STALL ); // CMD_CLR_STALL 主机方式:控制传输-清除端点错误 CH375_WR_DAT_PORT(1); /* 如果设备端不是CH37X芯片,那么需要修改端点号 */ toggle_recv(1); issue_token_s(( 1 << 4 ) | DEF_USB_PID_IN);//发送从中断端点读数据的令牌 status=CH375_RD_DAT_PORT(); } while(1); len_temp=rd_usb_data(buffer); // USB扫描枪的数据包长度为8个字节 while(buffer[0]) { tank=((~tank)&0x01); // ~:按位取反;&:按位与 BUF+=0x08; // 意为指针指向buffer数组8个字节后的数据 toggle_recv( tank ); /* DATA阶段 */ _nop_(); _nop_(); while(issue_token( ( 1 << 4 ) | DEF_USB_PID_IN )!=USB_INT_SUCCESS ); { /* SETUP阶段操作成功 */ len_temp=rd_usb_data(BUF); buffer[0]=buffer[0]-len_temp; } } // 该循环是将描述符逐数据逐一读出,存放在buffer数组中 tank=((~tank)&0x01); toggle_recv(tank); issue_token_s(( 1 << 4 ) | DEF_USB_PID_IN);//发送从中断端点读数据的令牌 }

以上是我关于接收数据的子函数,与您给的键盘程序略有区别,麻烦帮我看下有什么问题。 通过有关软件得到的配置描述符中的endp_int值为0x81,所以我直接将子函数中的endp_int值用其代替了。发现一个问题,就是我的扫描枪不作任何操作的情况下,程序都会通过 while(status!=USB_INT_SUCCESS) { CH375_WR_CMD_PORT( CMD_CLR_STALL ); // CMD_CLR_STALL 主机方式:控制传输-清除端点错误 CH375_WR_DAT_PORT(1); /* 如果设备端不是CH37X芯片,那么需要修改端点号 */ toggle_recv(1); issue_token_s(( 1 << 4 ) | DEF_USB_PID_IN);//发送从中断端点读数据的令牌 status=CH375_RD_DAT_PORT(); } 这是为什么呢?

现在接收不到数据,即使将该部分代码换成您给的程序里的那段代码,也仍然接收不到数据。

附注:我的扫描枪数据包长度为8个字节,全速。


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