"數(shù)據(jù)測試返回的長度錯誤" main( ) { Delay50ms(); CH375_Init(); EA=1; updata();/*上傳數(shù)據(jù)*/ } 金針用的是24mhz的 用text測試無問題! 用的是偽中斷上傳的方法,一直無數(shù)據(jù)上傳,上位機(jī)用的是你們vb程序改的! 新手求幫助!
你用TEST測試沒有問題的話,那你的硬件應(yīng)該沒什么問題了,數(shù)據(jù)上傳不了的話,應(yīng)該是程序的問題。要不你把完整的程序發(fā)過來看一下。
你可以這樣做一下,先通過端點(diǎn)2下傳一個數(shù)據(jù),可以是空的數(shù)據(jù),當(dāng)下傳完之后在上傳數(shù)據(jù)就沒有問題了。這個主要問題是上位機(jī)不知道你已經(jīng)將數(shù)據(jù)準(zhǔn)備好了。
#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++) ; } } 是單片機(jī)程序,有高手幫我看一下嗎!,現(xiàn)在問題還是"數(shù)據(jù)測試返回的長度錯誤 在線等??!
#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 { /* 自定義的命令包結(jié)構(gòu) */ unsigned char mCommandCode; /* 命令請求碼,見下面的定義 */ unsigned char mCommandCodeNot; /* 命令碼的反碼,用于校驗(yàn)命令包 */ union { unsigned char mParameter[5]; /* 參數(shù) */ struct { unsigned char mBufferID; /* 緩沖區(qū)識別碼,本程序針對MCS51單片機(jī)定義: 1-專用功能寄存器SFR, 2-內(nèi)部RAM, 3-外部RAM, 不過本程序?qū)嶋H只演示內(nèi)部RAM */ unsigned int mBufferAddr; /* 讀寫操作的起始地址,尋址范圍是0000H-0FFFFH,低字節(jié)在前 */ unsigned int mLength; /* 數(shù)據(jù)塊總長度,低字節(jié)在前 */ } buf; } u; } mCOMMAND_PACKET, *mpCOMMAND_PACKET;
#define CONST_CMD_LEN 0x07 /* 命令塊的長度 */ #define DEF_CMD_GET_INFORM 0x90 /* 獲取下位機(jī)的說明信息,長度不超過64個字符,字符串以00H結(jié)束 */ #define DEF_CMD_TEST_DATA 0x91 /* 測試命令,下位機(jī)將PC機(jī)發(fā)來的命令包的所有數(shù)據(jù)取反后返回 */ #define DEF_CMD_CLEAR_UP 0xA0 /* 在上傳數(shù)據(jù)塊之前進(jìn)行同步,實(shí)際是讓下位機(jī)清除上傳緩沖區(qū)的已有內(nèi)容 */ #define DEF_CMD_UP_DATA 0xA1 /* 從下位機(jī)的指定地址的緩沖區(qū)中讀取數(shù)據(jù)塊(上傳數(shù)據(jù)塊) */ #define DEF_CMD_DOWN_DATA 0xA2 /* 向下位機(jī)的指定地址的緩沖區(qū)中寫入數(shù)據(jù)塊(下傳數(shù)據(jù)塊) */ #define ACCESS_MCS51_SFR 1 /* 讀寫51單片機(jī)的SFR */ #define ACCESS_MCS51_IRAM 2 /* 讀寫51單片機(jī)的內(nèi)部RAM */ #define ACCESS_MCS51_XRAM 3 /* 讀寫51單片機(jī)的外部RAM */ unsigned char volatile xdata CH375_CMD_PORT _at_ 0xBDF1; /* CH375命令端口的I/O地址 */ unsigned char volatile xdata CH375_DAT_PORT _at_ 0xBCF0; /* CH375數(shù)據(jù)端口的I/O地址 */ mCOMMAND_PACKET CMD_PKT; /* 命令包結(jié)構(gòu)緩沖區(qū) */ unsigned char data *CurrentRamAddr; /* 進(jìn)行數(shù)據(jù)塊傳輸時保存被讀寫的緩沖區(qū)的起始地址 */ unsigned char CurrentRamLen; /* 進(jìn)行數(shù)據(jù)塊傳輸時保存剩余長度 */ bit FLAG_INT_WAIT; /* 中斷等待標(biāo)志,1指示有中斷數(shù)據(jù)正在CH375中等待發(fā)送 */ unsigned char CH451_CMD_H; /* PC機(jī)發(fā)給CH451的高4位命令,為0FFH則命令無效 */ unsigned char CH451_CMD_L; /* PC機(jī)發(fā)給CH451的低8位命令 */ unsigned char code InformString[16] = "CH375/CH451\x0"; /* 信息字符串 */ void Delay2us( ) { unsigned char i; #define DELAY_START_VALUE 1 /* 根據(jù)單片機(jī)的時鐘選擇初值,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機(jī)的低字節(jié)在前的16位字?jǐn)?shù)據(jù)轉(zhuǎn)換為C51的高字節(jié)在前的數(shù)據(jù) */ 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; /* 清發(fā)送中斷等待標(biāo)志 */ /* 測試CH375是否正常工作,可選操作,通常不需要 */ #ifdef TEST_CH375_FIRST CH375_CMD_PORT = CMD_CHECK_EXIST; /* 測試CH375是否正常工作 */ Delay2us( ); /* 如果時鐘頻率低于16MHz則無需該指令延時 */ CH375_DAT_PORT = 0x55; /* 寫入測試數(shù)據(jù) */ Delay2us( ); i = ~ 0x55; /* 返回?cái)?shù)據(jù)應(yīng)該是測試數(shù)據(jù)取反 */ if ( CH375_DAT_PORT != i ) { /* CH375不正常 */ for ( i=80; i!=0; i-- ) { CH375_CMD_PORT = CMD_RESET_ALL; /* 多次重復(fù)發(fā)命令,執(zhí)行硬件復(fù)位 */ Delay2us( ); } CH375_CMD_PORT = 0; Delay50ms( ); /* 延時50ms */ } #endif #ifdef USE_MY_USB_ID /* 設(shè)置外部自定義的USB設(shè)備VID和PID,可選操作,不執(zhí)行該命令則使用默認(rèn)的VID和PID */ CH375_CMD_PORT = CMD_SET_USB_ID; /* 設(shè)置外部自定義的USB設(shè)備VID和PID,可選操作 */ Delay2us( ); /* 如果時鐘頻率低于16MHz則無需該指令延時 */ CH375_DAT_PORT = (unsigned char)MY_USB_VENDOR_ID; /* 寫入廠商ID的低字節(jié) */ CH375_DAT_PORT = (unsigned char)(MY_USB_VENDOR_ID>>8); /* 寫入廠商ID的高字節(jié) */ CH375_DAT_PORT = (unsigned char)MY_USB_DEVICE_ID; /* 寫入設(shè)備ID的低字節(jié) */ CH375_DAT_PORT = (unsigned char)(MY_USB_DEVICE_ID>>8); /* 寫入設(shè)備ID的高字節(jié) */ Delay2us( ); #endif /* 設(shè)置USB工作模式, 必要操作 */ CH375_CMD_PORT = CMD_SET_USB_MODE; Delay2us( ); /* 如果時鐘頻率低于16MHz則無需該指令延時 */ CH375_DAT_PORT = 2; /* 設(shè)置為使用內(nèi)置固件的USB設(shè)備方式 */ 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; /* 置外部信號為低電平觸發(fā) */ IE0 = 0; /* 清中斷標(biāo)志 */ EX0 = 1; /* 允許CH375中斷 */ }
/* 加載上傳數(shù)據(jù) */ void LoadUpData( unsigned char data *Buf, unsigned char Len ) { unsigned char i; CH375_CMD_PORT = CMD_WR_USB_DATA7; /* 向USB端點(diǎn)2的發(fā)送緩沖區(qū)寫入數(shù)據(jù)塊 */ Delay2us( ); /* 如果時鐘頻率低于16MHz則無需該指令延時 */ CH375_DAT_PORT = Len; /* 首先寫入后續(xù)數(shù)據(jù)長度 */ for ( i=0; i}
/* CH375中斷服務(wù)程序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; /* 獲取中斷狀態(tài)并取消中斷請求 */ Delay2us( ); /* 如果時鐘頻率低于16MHz則無需該指令延時 */ InterruptStatus = CH375_DAT_PORT; /* 獲取中斷狀態(tài) */ IE0 = 0; /* 清中斷標(biāo)志,對應(yīng)于INT0中斷 */ if ( InterruptStatus == USB_INT_EP2_OUT ) { /* 批量端點(diǎn)下傳成功 */ CH375_CMD_PORT = CMD_RD_USB_DATA; /* 從當(dāng)前USB中斷的端點(diǎn)緩沖區(qū)讀取數(shù)據(jù)塊,并釋放緩沖區(qū) */ Delay2us( ); /* 如果時鐘頻率低于16MHz則無需該指令延時 */ length = CH375_DAT_PORT; /* 首先讀取后續(xù)數(shù)據(jù)長度 */ if ( length == CONST_CMD_LEN ) { /* 命令塊長度總是CONST_CMD_LEN,分析并處理命令 */ /* 分析通過USB接收到的命令塊,長度總是CONST_CMD_LEN,首字節(jié)為命令,其余為可選的參數(shù),這種命令結(jié)構(gòu)是由單片機(jī)和計(jì)算機(jī)應(yīng)用層之間自行定義的 */ for ( i=0; i if ( CMD_PKT.mCommandCode != (unsigned char)( ~ CMD_PKT.mCommandCodeNot ) ) return; /* 命令包反碼校驗(yàn)錯誤 */ switch ( CMD_PKT.mCommandCode ) { /* 分析命令碼,switch可以用多個if/else代替 */ case DEF_CMD_GET_INFORM: /* 獲取下位機(jī)的說明信息,長度不超過64個字符,字符串以00H結(jié)束 */ CH375_CMD_PORT = CMD_WR_USB_DATA7; /* 向USB端點(diǎn)2的發(fā)送緩沖區(qū)寫入數(shù)據(jù)塊 */ Delay2us( ); /* 如果時鐘頻率低于16MHz則無需該指令延時 */ CH375_DAT_PORT = 16; /* 首先寫入后續(xù)數(shù)據(jù)長度 */ for ( i=0; i<16; i++ ) CH375_DAT_PORT = InformString[i]; /* 加載數(shù)據(jù) */ break; case DEF_CMD_TEST_DATA: /* 測試命令,下位機(jī)將PC機(jī)發(fā)來的命令包的所有數(shù)據(jù)取反后返回 */ CH375_CMD_PORT = CMD_WR_USB_DATA7; /* 向USB端點(diǎn)2的發(fā)送緩沖區(qū)寫入數(shù)據(jù)塊 */ Delay2us( ); /* 如果時鐘頻率低于16MHz則無需該指令延時 */ CH375_DAT_PORT = CONST_CMD_LEN; /* 首先寫入后續(xù)數(shù)據(jù)長度 */ for ( i=0; i break; case DEF_CMD_CLEAR_UP: /* 在上傳數(shù)據(jù)塊之前進(jìn)行同步,實(shí)際是讓下位機(jī)清除上傳緩沖區(qū)的已有內(nèi)容 */ /* 連續(xù)上傳數(shù)據(jù)塊之前進(jìn)行同步,實(shí)際是讓單片機(jī)清除上傳緩沖區(qū)的已有內(nèi)容 ; 如果上一次進(jìn)行數(shù)據(jù)上傳時,計(jì)算機(jī)提前結(jié)束上傳,那么有可能在上傳緩沖區(qū)中遺留有數(shù)據(jù),所以在第二次上傳前需要清除上傳緩沖區(qū) */ CH375_CMD_PORT = CMD_SET_ENDP7; /* 設(shè)置USB端點(diǎn)2的IN,也就是批量上傳端點(diǎn) */ Delay2us( ); /* 如果時鐘頻率低于16MHz則無需該指令延時 */ CH375_DAT_PORT = 0x0e; /* 同步觸發(fā)位不變,設(shè)置USB端點(diǎn)2的IN正忙,返回NAK */ break; case DEF_CMD_UP_DATA: /* 從下位機(jī)的指定地址的緩沖區(qū)中讀取數(shù)據(jù)塊(上傳數(shù)據(jù)塊) */ /* 連續(xù)上傳數(shù)據(jù)塊, 本程序?qū)嶋H只演示內(nèi)部RAM */ /* switch ( CMD_PKT.u.buf.mBufferID ) { case ACCESS_MCS51_SFR: 讀寫51單片機(jī)的SFR case ACCESS_MCS51_IRAM: 讀寫51單片機(jī)的內(nèi)部RAM case ACCESS_MCS51_XRAM: 讀寫51單片機(jī)的外