[求助]"数据测试返回的长度错误"

"数据测试返回的长度错误" main( ) { Delay50ms(); CH375_Init(); EA=1; updata();/*上传数据*/ } 金针用的是24mhz的 用text测试无问题! 用的是伪中断上传的方法,一直无数据上传,上位机用的是你们vb程序改的! 新手求帮助!

你用TEST测试没有问题的话,那你的硬件应该没什么问题了,数据上传不了的话,应该是程序的问题。要不你把完整的程序发过来看一下。


你可以这样做一下,先通过端点2下传一个数据,可以是空的数据,当下传完之后在上传数据就没有问题了。这个主要问题是上位机不知道你已经将数据准备好了。


#include #include #include

// define P1.0 to check STATUS. sbit STATUS = P1^0;

unsigned char xdata CTRL _at_ 0x2FFF; unsigned char xdata ADSEL _at_ 0x4FFF; unsigned char hByte; unsigned char lByte;

void adc_Convert (void) { // Start a conversion with A0 and A/$C$ low. // The convesion takes place on rising CE edge. CTRL = 0x00; ADSEL = 0x00; // Wait until we have completed a conversion . while(STATUS==1); // Set R/$C$ with A0 low and read the low byte. CTRL = 0x02; hByte = ADSEL; // Set R/$C$ with A0 high and read the high. CTRL = 0x03; lByte = ADSEL; }

void main(void) { unsigned int delay, MSB , LSB, adc_Res; // Initialize serial interface SCON = 0xDA; // SCON: mode 1, 8-bit UART, enable rcvr */ TMOD |= 0x20; // TMOD: timer 1, mode 2, 8-bit reload */ TH1 = 0xFD; // TH1: reload value for 1200 baud @ 12MHz */ TR1 = 1; // TR1: timer 1 run */ TI = 1; // TI: set TI to send first char of UART */ while(1) { adc_Convert(); MSB=(unsigned int)(hByte << 4); LSB=(unsigned int)(lByte >> 4); // adc_Res now has the converted data with 12-bit resolution. adc_Res = MSB + LSB; // Send adc results to the serial interface printf("ADC READINGS: %03Xh\n", adc_Res); // simple delay - it is mcu clock dependent ! for (delay=0; delay<10000; delay++) ; } } 是单片机程序,有高手帮我看一下吗!,现在问题还是"数据测试返回的长度错误 在线等!!


#include "CH375INC.H" #include #include #include #include #include "CH375INC.H" #define uchar unsigned char #define ADC XBYTE[ 0XDFFC] #define ADCHI XBYTE[0XDFFE] #define ADCLO XBYTE[0XDFFF] #define uint unsigned int unsigned char hByte; unsigned char lByte; sbit adbusy=P3^4 ; unsigned char KEY ;

typedef struct _COMMAND_PACKET { /* 自定义的命令包结构 */ unsigned char mCommandCode; /* 命令请求码,见下面的定义 */ unsigned char mCommandCodeNot; /* 命令码的反码,用于校验命令包 */ union { unsigned char mParameter[5]; /* 参数 */ struct { unsigned char mBufferID; /* 缓冲区识别码,本程序针对MCS51单片机定义: 1-专用功能寄存器SFR, 2-内部RAM, 3-外部RAM, 不过本程序实际只演示内部RAM */ unsigned int mBufferAddr; /* 读写操作的起始地址,寻址范围是0000H-0FFFFH,低字节在前 */ unsigned int mLength; /* 数据块总长度,低字节在前 */ } buf; } u; } mCOMMAND_PACKET, *mpCOMMAND_PACKET;

#define CONST_CMD_LEN 0x07 /* 命令块的长度 */ #define DEF_CMD_GET_INFORM 0x90 /* 获取下位机的说明信息,长度不超过64个字符,字符串以00H结束 */ #define DEF_CMD_TEST_DATA 0x91 /* 测试命令,下位机将PC机发来的命令包的所有数据取反后返回 */ #define DEF_CMD_CLEAR_UP 0xA0 /* 在上传数据块之前进行同步,实际是让下位机清除上传缓冲区的已有内容 */ #define DEF_CMD_UP_DATA 0xA1 /* 从下位机的指定地址的缓冲区中读取数据块(上传数据块) */ #define DEF_CMD_DOWN_DATA 0xA2 /* 向下位机的指定地址的缓冲区中写入数据块(下传数据块) */ #define ACCESS_MCS51_SFR 1 /* 读写51单片机的SFR */ #define ACCESS_MCS51_IRAM 2 /* 读写51单片机的内部RAM */ #define ACCESS_MCS51_XRAM 3 /* 读写51单片机的外部RAM */ unsigned char volatile xdata CH375_CMD_PORT _at_ 0xBDF1; /* CH375命令端口的I/O地址 */ unsigned char volatile xdata CH375_DAT_PORT _at_ 0xBCF0; /* CH375数据端口的I/O地址 */ mCOMMAND_PACKET CMD_PKT; /* 命令包结构缓冲区 */ unsigned char data *CurrentRamAddr; /* 进行数据块传输时保存被读写的缓冲区的起始地址 */ unsigned char CurrentRamLen; /* 进行数据块传输时保存剩余长度 */ bit FLAG_INT_WAIT; /* 中断等待标志,1指示有中断数据正在CH375中等待发送 */ unsigned char CH451_CMD_H; /* PC机发给CH451的高4位命令,为0FFH则命令无效 */ unsigned char CH451_CMD_L; /* PC机发给CH451的低8位命令 */ unsigned char code InformString[16] = "CH375/CH451\x0"; /* 信息字符串 */ void Delay2us( ) { unsigned char i; #define DELAY_START_VALUE 1 /* 根据单片机的时钟选择初值,20MHz以下为0,30MHz以上为2 */ for ( i=DELAY_START_VALUE; i!=0; i-- ); }

/* 延时50毫秒,不精确 */ void Delay50ms( ) { unsigned char i, j; for ( i=200; i!=0; i-- ) for ( j=250; j!=0; j-- ); }

/* 将PC机的低字节在前的16位字数据转换为C51的高字节在前的数据 */ unsigned int BIG_ENDIAN( unsigned int value ) { unsigned int in, out; in = value; ((unsigned char *)&out)[1] = ((unsigned char *)&in)[0]; ((unsigned char *)&out)[0] = ((unsigned char *)&in)[1]; return( out ); }

/* CH375初始化子程序 */ void CH375_Init( ) { unsigned char i; FLAG_INT_WAIT = 0; /* 清发送中断等待标志 */ /* 测试CH375是否正常工作,可选操作,通常不需要 */ #ifdef TEST_CH375_FIRST CH375_CMD_PORT = CMD_CHECK_EXIST; /* 测试CH375是否正常工作 */ Delay2us( ); /* 如果时钟频率低于16MHz则无需该指令延时 */ CH375_DAT_PORT = 0x55; /* 写入测试数据 */ Delay2us( ); i = ~ 0x55; /* 返回数据应该是测试数据取反 */ if ( CH375_DAT_PORT != i ) { /* CH375不正常 */ for ( i=80; i!=0; i-- ) { CH375_CMD_PORT = CMD_RESET_ALL; /* 多次重复发命令,执行硬件复位 */ Delay2us( ); } CH375_CMD_PORT = 0; Delay50ms( ); /* 延时50ms */ } #endif #ifdef USE_MY_USB_ID /* 设置外部自定义的USB设备VID和PID,可选操作,不执行该命令则使用默认的VID和PID */ CH375_CMD_PORT = CMD_SET_USB_ID; /* 设置外部自定义的USB设备VID和PID,可选操作 */ Delay2us( ); /* 如果时钟频率低于16MHz则无需该指令延时 */ CH375_DAT_PORT = (unsigned char)MY_USB_VENDOR_ID; /* 写入厂商ID的低字节 */ CH375_DAT_PORT = (unsigned char)(MY_USB_VENDOR_ID>>8); /* 写入厂商ID的高字节 */ CH375_DAT_PORT = (unsigned char)MY_USB_DEVICE_ID; /* 写入设备ID的低字节 */ CH375_DAT_PORT = (unsigned char)(MY_USB_DEVICE_ID>>8); /* 写入设备ID的高字节 */ Delay2us( ); #endif /* 设置USB工作模式, 必要操作 */ CH375_CMD_PORT = CMD_SET_USB_MODE; Delay2us( ); /* 如果时钟频率低于16MHz则无需该指令延时 */ CH375_DAT_PORT = 2; /* 设置为使用内置固件的USB设备方式 */ for ( i=100; i!=0; i-- ) { /* 等待操作成功,通常需要等待10uS-20uS */ if ( CH375_DAT_PORT==CMD_RET_SUCCESS ) break; } /* if ( i==0 ) { CH372/CH375存在硬件错误 }; */ /* 下述启用中断,假定CH375连接在INT0 */ IT0 = 0; /* 置外部信号为低电平触发 */ IE0 = 0; /* 清中断标志 */ EX0 = 1; /* 允许CH375中断 */ }

/* 加载上传数据 */ void LoadUpData( unsigned char data *Buf, unsigned char Len ) { unsigned char i; CH375_CMD_PORT = CMD_WR_USB_DATA7; /* 向USB端点2的发送缓冲区写入数据块 */ Delay2us( ); /* 如果时钟频率低于16MHz则无需该指令延时 */ CH375_DAT_PORT = Len; /* 首先写入后续数据长度 */ for ( i=0; i}

/* CH375中断服务程序INT0,使用寄存器组1 */ void mCH375Interrupt( ) interrupt 0 using 1 { unsigned char InterruptStatus; unsigned char length, c1, len1, len2, i; #define cmd_buf ((unsigned char data *)(&CMD_PKT)) CH375_CMD_PORT = CMD_GET_STATUS; /* 获取中断状态并取消中断请求 */ Delay2us( ); /* 如果时钟频率低于16MHz则无需该指令延时 */ InterruptStatus = CH375_DAT_PORT; /* 获取中断状态 */ IE0 = 0; /* 清中断标志,对应于INT0中断 */ if ( InterruptStatus == USB_INT_EP2_OUT ) { /* 批量端点下传成功 */ CH375_CMD_PORT = CMD_RD_USB_DATA; /* 从当前USB中断的端点缓冲区读取数据块,并释放缓冲区 */ Delay2us( ); /* 如果时钟频率低于16MHz则无需该指令延时 */ length = CH375_DAT_PORT; /* 首先读取后续数据长度 */ if ( length == CONST_CMD_LEN ) { /* 命令块长度总是CONST_CMD_LEN,分析并处理命令 */ /* 分析通过USB接收到的命令块,长度总是CONST_CMD_LEN,首字节为命令,其余为可选的参数,这种命令结构是由单片机和计算机应用层之间自行定义的 */ for ( i=0; i if ( CMD_PKT.mCommandCode != (unsigned char)( ~ CMD_PKT.mCommandCodeNot ) ) return; /* 命令包反码校验错误 */ switch ( CMD_PKT.mCommandCode ) { /* 分析命令码,switch可以用多个if/else代替 */ case DEF_CMD_GET_INFORM: /* 获取下位机的说明信息,长度不超过64个字符,字符串以00H结束 */ CH375_CMD_PORT = CMD_WR_USB_DATA7; /* 向USB端点2的发送缓冲区写入数据块 */ Delay2us( ); /* 如果时钟频率低于16MHz则无需该指令延时 */ CH375_DAT_PORT = 16; /* 首先写入后续数据长度 */ for ( i=0; i<16; i++ ) CH375_DAT_PORT = InformString[i]; /* 加载数据 */ break; case DEF_CMD_TEST_DATA: /* 测试命令,下位机将PC机发来的命令包的所有数据取反后返回 */ CH375_CMD_PORT = CMD_WR_USB_DATA7; /* 向USB端点2的发送缓冲区写入数据块 */ Delay2us( ); /* 如果时钟频率低于16MHz则无需该指令延时 */ CH375_DAT_PORT = CONST_CMD_LEN; /* 首先写入后续数据长度 */ for ( i=0; i break; case DEF_CMD_CLEAR_UP: /* 在上传数据块之前进行同步,实际是让下位机清除上传缓冲区的已有内容 */ /* 连续上传数据块之前进行同步,实际是让单片机清除上传缓冲区的已有内容 ; 如果上一次进行数据上传时,计算机提前结束上传,那么有可能在上传缓冲区中遗留有数据,所以在第二次上传前需要清除上传缓冲区 */ CH375_CMD_PORT = CMD_SET_ENDP7; /* 设置USB端点2的IN,也就是批量上传端点 */ Delay2us( ); /* 如果时钟频率低于16MHz则无需该指令延时 */ CH375_DAT_PORT = 0x0e; /* 同步触发位不变,设置USB端点2的IN正忙,返回NAK */ break; case DEF_CMD_UP_DATA: /* 从下位机的指定地址的缓冲区中读取数据块(上传数据块) */ /* 连续上传数据块, 本程序实际只演示内部RAM */ /* switch ( CMD_PKT.u.buf.mBufferID ) { case ACCESS_MCS51_SFR: 读写51单片机的SFR case ACCESS_MCS51_IRAM: 读写51单片机的内部RAM case ACCESS_MCS51_XRAM: 读写51单片机的外


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