SCM老师:你好! 实在不好意思,我按你的指导折腾了很常时间,就是编译通过不了,有很多错误报告,可能是环境没有设置好,但我又搞不好,这里我再一次冒昧向你提出求助:你能将CH375HST.ZIP中的CH375PRT.C文件帮我编译一下,生成一个汇编文件吗?本人万分感谢! 我的信箱:个人信息保护,已隐藏 谢谢!
已处理,请查收邮件
邮件已收到,谢谢!!!
本人在编译的时候也出现有4个Warning.请问是什么原因呢?编译结果如下 MedWin v2.39 Translating F:\WEbook\ZPUSB\ch375_host_int_para.c......pass ! MedWin V2.39 Linking...... BL51 BANKED LINKER/LOCATER V4.13 - SN: Eval Version COPYRIGHT KEIL ELEKTRONIK GmbH 1987 - 2001 ch375_host_int_para.obj TO CH375JP.Omf RAMSIZE(256) *** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS SEGMENT: ?PR?_SET_RETRY?CH375_HOST_INT_PARA *** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS SEGMENT: ?PR?SET_CONFIG_EX?CH375_HOST_INT_PARA *** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS SEGMENT: ?PR?_GET_DESCR?CH375_HOST_INT_PARA *** WARNING L15: MULTIPLE CALL TO SEGMENT SEGMENT: ?PR?_RD_USB_DATA?CH375_HOST_INT_PARA CALLER1: ?PR?INTT0?CH375_HOST_INT_PARA CALLER2: ?C_C51STARTUP LINK/LOCATE RUN COMPLETE. 4 WARNING(S), 0 ERROR(S) Write Intel HEX format file "F:\WEbook\CH375JP.hex" successfully. Initial Emulator...seccessfully. Loading program "CH375JP.Omf"... ............................................................ .......... Set address breakpoint at 037Bh ************* T o t a l ************* Code number: 3358 bytes. Minimal address: 0000H. Maximal address: 0D1DH. ************************************* Loading program Completed. 引用--蓝仙的话ch375_host_int_para.c "文件帮我编译一下,生成一个汇编文件吗?本人万分感谢!"
我的邮箱个人信息保护,已隐藏
这个是没问题的,这些是你没调用的函数。
还有一个问题要请教,在仿真器上程序运行到" #ifdef TEST_LOW_SPEED set_freq( ); //使375B进入低速模式 #endif while(1) { while ( wait_interrupt()!=USB_INT_CONNECT ); /* 等待设备端连接上来 */
"时,调用下面的程序,运行到"while (CH375_INT_WIRE);" 时INT#中断引脚一直为高电平这是什么原因呢? 我的电路是按CH375中文手册(1)中的电路图来做的,在TEST的程序上跑过,没问题的.
unsigned char wait_interrupt() { /* 主机端等待操作完成, 返回操作状态 */ while( CH375_INT_WIRE ); /* 查询等待CH375操作完成中断(INT#低电平) */ CH375_WR_CMD_PORT( CMD_GET_STATUS ); /* 产生操作完成中断, 获取中断状态 */ return( CH375_RD_DAT_PORT() ); }
set_freq( )之前已经检测到设备连接,如果设备没有断开过,那么在wait_interrupt中不会再检测到设备连接中断,while ( wait_interrupt()!=USB_INT_CONNECT )就是一个死循环 。 你把程序贴出来看看
/**************************************** ** Copyright (C) W.ch 1999-2004 ** ** Web: http://www.winchiphead.com ** **************************************** ** USB 1.1 Host Examples for CH375 ** ** KC7.0@MCS-51 ** **************************************** */ /* 用CH375操作HID设备,比如键盘,鼠标*/
#include #include #include "CH375INC.H" #define TEST_LOW_SPEED 1 unsigned char volatile xdata CH375_CMD_PORT _at_ 0xBDF1; /* CH375命令端口的I/O地址 */ unsigned char volatile xdata CH375_DAT_PORT _at_ 0xBCF0; /* CH375数据端口的I/O地址 */ sbit CH375_INT_WIRE = 0xB0^2; /* P3.2, INT0, 连接CH375的INT#引脚,用于查询中断状态 */ sbit P1_0=P1^0; sbit P1_2=P1^2; #define TRUE 1 #define FALSE 0 unsigned char endp_int; //中断端点号 unsigned char num_interfaces; //接口数 unsigned char config_value; //配置值 unsigned char report_descr_len=0; //REPORT描述符长度 bit flag_config_2=0; //第二次获取描述符标志位 bit flag_interface_2=0; //多个接口标志位 unsigned char endp6_mode=0x80, endp7_mode=0x80; //同步标志位初值 unsigned char status=0xff; //全局状态 unsigned char idata data_buf[96]; //描述符缓冲区可以适当减小 union _REQUEST //请求包结构 { struct { unsigned char bmRequestType; unsigned char bRequest; unsigned int wValue; unsigned int wIndex; unsigned int wLength; } Req; unsigned char Req_buf[8]; } Request; unsigned char report_cou=0; //REPORT描述符长度计数 bit flag_output=0; //串口输出标志位 unsigned char xdata data_in[1000]; //串口输出缓冲区 void delay2us( ) { unsigned char i; #ifdef TEST_LOW_SPEED for ( i = 20; i != 0; i -- ); #else for ( i = 2; i != 0; i -- ); #endif } void delay1us( ) { unsigned char i; #ifdef TEST_LOW_SPEED for ( i = 10; i != 0; i -- ); #else for ( i = 1; i != 0; i -- ); #endif } void delayms(unsigned char delay) { unsigned char i; do{ for(i=0;i!=250;i++){;} for(i=0;i!=250;i++){;} for(i=0;i!=150;i++){;} } while(--delay); } void mInitSTDIO( ) { SCON = 0x50; PCON = 0x80; TMOD = 0x21; TH1 = 0xf3; /* 22.1184MHz晶振, 115200bps */ TR1 = 1; TI = 1; EX0=1; EA=0; }
void CH375_WR_CMD_PORT( unsigned char cmd ) { /* 向CH375的命令端口写入命令,周期不小于4uS,如果单片机较快则延时 */ delay2us(); CH375_CMD_PORT=cmd; delay2us(); }
void CH375_WR_DAT_PORT( unsigned char dat ) { /* 向CH375的数据端口写入数据,周期不小于1.5uS,如果单片机较快则延时 */ CH375_DAT_PORT=dat; delay1us(); /* 因为MCS51单片机较慢所以实际上无需延时 */ }
unsigned char CH375_RD_DAT_PORT() { /* 从CH375的数据端口读出数据,周期不小于1.5uS,如果单片机较快则延时 */ delay1us(); /* 因为MCS51单片机较慢所以实际上无需延时 */ return( CH375_DAT_PORT ); }
unsigned char set_usb_mode( unsigned char mode ) { /* 设置CH37X的工作模式 */ unsigned char i; CH375_WR_CMD_PORT( CMD_SET_USB_MODE ); CH375_WR_DAT_PORT( mode ); endp6_mode=endp7_mode=0x80; /* 主机端复位USB数据同步标志 */ for( i=0; i!=100; i++ ) { /* 等待设置模式操作完成,不超过30uS */ if ( CH375_RD_DAT_PORT()==CMD_RET_SUCCESS ) return( TRUE ); /* 成功 */ } return( FALSE ); /* CH375出错,例如芯片型号错或者处于串口方式或者不支持 */ }
void set_freq(void) { CH375_WR_CMD_PORT(0x0b); /* 切换使375B进入低速模式 */ CH375_WR_DAT_PORT(0x17); CH375_WR_DAT_PORT(0xd8); }
/* 数据同步 */ /* USB的数据同步通过切换DATA0和DATA1实现: 在设备端, CH372/CH375可以自动切换; 在主机端, 必须由SET_ENDP6和SET_ENDP7命令控制CH375切换DATA0与DATA1. 主机端的程序处理方法是为SET_ENDP6和SET_ENDP7分别提供一个全局变量, 初始值均为80H, 每执行一次成功事务后将位6取反, 每执行一次失败事务后将其复位为80H. */
void toggle_recv() { /* 主机接收成功后,切换DATA0和DATA1实现数据同步 */ CH375_WR_CMD_PORT( CMD_SET_ENDP6 ); CH375_WR_DAT_PORT( endp6_mode ); endp6_mode^=0x40; delay2us(); }
void toggle_send() { /* 主机发送成功后,切换DATA0和DATA1实现数据同步 */ CH375_WR_CMD_PORT( CMD_SET_ENDP7 ); CH375_WR_DAT_PORT( endp7_mode ); endp7_mode^=0x40; delay2us(); }
//void clr_stall6() { /* 主机接收失败后,复位设备端的数据同步到DATA0 */ // CH375_WR_CMD_PORT( CMD_CLR_STALL ); // CH375_WR_DAT_PORT( 2 | 0x80 ); /* 如果设备端不是CH37X芯片,那么需要修改端点号 */ // endp6_mode=0x80; // status=0xff; //}
//void clr_stall7() { /* 主机发送失败后,复位设备端的数据同步到DATA0 */ // CH375_WR_CMD_PORT( CMD_CLR_STALL ); // CH375_WR_DAT_PORT( 2 ); /* 如果设备端不是CH37X芯片,那么需要修改端点号 */ // endp7_mode=0x80; // status=0xff; //}
unsigned char rd_usb_data( unsigned char *buf ) { /* 从CH37X读出数据块 */ unsigned char i, len; CH375_WR_CMD_PORT( CMD_RD_USB_DATA ); /* 从CH375的端点缓冲区读取接收到的数据 */ len=CH375_RD_DAT_PORT(); /* 后续数据长度 */ for ( i=0; i!=len; i++ ) *buf++=CH375_RD_DAT_PORT(); return( len ); }
void wr_usb_data( unsigned char len, unsigned char *buf ) { /* 向CH37X写入数据块 */ CH375_WR_CMD_PORT( CMD_WR_USB_DATA7 ); /* 向CH375的端点缓冲区写入准备发送的数据 */ CH375_WR_DAT_PORT( len ); /* 后续数据长度, len不能大于64 */ while( len-- ) CH375_WR_DAT_PORT( *buf++ ); }
void issue_token( unsigned char endp_and_pid ) { /* 执行USB事务 */ CH375_WR_CMD_PORT( CMD_ISSUE_TOKEN ); CH375_WR_DAT_PORT( endp_and_pid ); /* 高4位目的端点号, 低4位令牌PID */ status=0xff; }
void intt0() interrupt 0 { unsigned char len_temp,i; CH375_WR_CMD_PORT( CMD_GET_STATUS ); /* 产生操作完成中断, 获取中断状态 */ status=CH375_RD_DAT_PORT(); if(status!=USB_INT_SUCCESS) //&&((status&0xf0)==0x20)) { CH375_WR_CMD_PORT( CMD_CLR_STALL ); CH375_WR_DAT_PORT(1); /* 如果设备端不是CH37X芯片,那么需要修改端点号 */ endp6_mode=0x80; endp7_mode=0x80; toggle_recv(); issue_token(( endp_int << 4 ) | DEF_USB_PID_IN); //发送从中断端点读数据的令牌 } else { len_temp=rd_usb_data(data_buf); //键盘中断端点数据长度一般为8字节,鼠标为4字节 for(i=0;i!=len_temp;i++)data_in[i]=data_buf[i]; flag_output=1; toggle_recv(); issue_token(( endp_int << 4 ) | DEF_USB_PID_IN); //发送从中断端点读数据的令牌 } } unsigned char wait_interrupt() { /* 主机端等待操作完成, 返回操作状态 */ while( CH375_INT_WIRE ); /* 查询等待CH375操作完成中断(INT#低电平) */ CH375_WR_CMD_PORT( CMD_GET_STATUS ); /* 产生操作完成中断, 获取中断状态 */ return( CH375_RD_DAT_PORT() ); }
void set_retry(unsigned char num) { CH375_WR_CMD_PORT( CMD_SET_RETRY); CH375_WR_DAT_PORT( 0x25); CH375_WR_DAT_PORT( num); delay2us(); }
unsigned char set_config_ex() { Request.Req.bmRequestType=0x00; Request.Req.bRequest=0x09; config_value=config_value; Request.Req.wValue=0x0000|((unsigned int)config_value<<8); Request.Req.wIndex=0x0000; Request.Req.wLength=0x0000; endp7_mode=0x80; toggle_send(); wr_usb_data(8,Request.Req_buf); /* SETUP数据总是8字节 */ issue_token(( 0 << 4 ) | DEF_USB_PID_SETUP); status=wait_interrupt(); if(status==USB_INT_SUCCESS) /* SETUP阶段操作成功 */ { endp6_mode=0xc0; toggle_recv(); issue_token(( 0 << 4 ) | DEF_USB_PID_IN); status=wait_interrupt(); if(status==USB_INT_SUCCESS) /* 状态阶段操作成功 */ { if(rd_usb_data(data_buf)!=0) return(0); } else return(0); } else return(0); return(1) ; } unsigned char set_idle() { Request.Req.bmRequestType=0x21; Request.Req.bRequest=0x0a; Request.Req.wValue=0x0000; Request.Req.wIndex=0x0000; if(flag_interface_2==1) Request.Req.wIndex=0x0100; Request.Req.wLength=0x0000; endp7_mode=0x80; toggle_send(); wr_usb_data(8,Request.Req_buf); /* SETUP数据总是8字节 */ issue_token(( 0 << 4 ) | DEF_USB_PID_SETUP); status=wait_interrupt(); if(status==USB_INT_SUCCESS) /* SETUP阶段操作成功 */ { endp6_mode=0xc0; toggle_recv(); issue_token(( 0 << 4 ) | DEF_USB_PID_IN );status=wait_interrupt(); if(status==USB
网站上的程序都是测试过的,应该不会有什么问题。 你检查一下375的硬件接口与程序中的定义是否一致:命令口,数据口,中断线
我是用CH372芯片的,命令口,数据口,中断线,没有接错. 现在发现CH372-CS引脚只有在写命令、写数据、或读数据的时候才有低电平。读写过了之后就为高电平了,那说明CH372没有片选信号,为什么程序要"while( CH375_INT_WIRE );/* 查询等待CH375操作完成中断(INT#低电平) */"呢?