CH375做USB驅(qū)動(dòng)開(kāi)發(fā) PC機(jī)和單片機(jī)通信

求專(zhuān)家指導(dǎo)啊,/* ; CH375/CH372 Bulk Data Test ; U2(AT89C51) Program ; 本程序測(cè)試數(shù)據(jù)傳輸?shù)恼_性, 并通過(guò)收發(fā)大數(shù)據(jù)塊來(lái)測(cè)試傳輸速度, ; 本程序適用于時(shí)鐘頻率不高于24MHz的標(biāo)準(zhǔn)MCS-51單片機(jī), 如果高于24MHz則應(yīng)該適當(dāng)增加延時(shí), 如果低于24MHz則可以適當(dāng)減少延時(shí) ; 只要單片機(jī)允許, 盡量使用較高的時(shí)鐘, 例如將原12MHz晶振換為24MHz, ; 因?yàn)镸CS51單片機(jī)自身速度較慢,讀寫(xiě)外部RAM需要2個(gè)周期以及附加的循環(huán)指令,即使24MHz時(shí)鐘也無(wú)法超過(guò)500KB/S ; 為了減少單片機(jī)自身對(duì)速度測(cè)試的影響,本程序中速度測(cè)試部分在單片機(jī)中斷服務(wù)程序中完成 ; ; Website: http://winchiphead.com ; Email: 個(gè)人信息保護(hù),已隱藏 ; Author: W.ch 2003.09 */

/* MCS-51單片機(jī)C語(yǔ)言的示例程序 */

#include #include #include "..\..\MCU_IF1\MCS51C\CH375INC.H"

/* #define USE_MY_USB_ID YES */ #define MY_USB_VENDOR_ID 0x1234 /* 廠商ID */ #define MY_USB_DEVICE_ID 0x5678 /* 設(shè)備ID */

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地址 */

unsigned char THIS_CMD_CODE; /* 保存當(dāng)前命令碼 */ unsigned char RECV_LEN; /* 剛接收到的數(shù)據(jù)的長(zhǎng)度 */ unsigned char RECV_BUFFER[ CH375_MAX_DATA_LEN ]; /* 數(shù)據(jù)緩沖區(qū),用于保存接收到的下傳數(shù)據(jù),長(zhǎng)度為0到64字節(jié) */ /* 由于MCS-51單片機(jī)存取外部RAM的讀寫(xiě)速度低于內(nèi)部RAM, 并且需要用到DPTR, 所以讀寫(xiě)速度較慢, 其程序可以參考本程序修改 */

/* 定義位標(biāo)志 */ bit bdata FLAG_RECV_OK; /* 接收成功標(biāo)志,1指示成功接收到數(shù)據(jù)塊 */ bit bdata FLAG_SEND_WAIT; /* 發(fā)送等待標(biāo)志,1指示有數(shù)據(jù)塊正在CH375中等待發(fā)送 */

/* 應(yīng)用層定義 */ /* TEST_OTHER EQU 00H ;其它自定義的命令碼 */ #define TEST_START 0x20 /* 測(cè)試過(guò)程開(kāi)始 */ #define TEST_DATA 0x21 /* 測(cè)試數(shù)據(jù)正確性 */ #define TEST_UPLOAD 0x22 /* 測(cè)試上傳數(shù)據(jù)塊 */ #define TEST_DOWNLOAD 0x23 /* 測(cè)試下傳數(shù)據(jù)塊 */

/* 有關(guān)CH451的定義,演示板的連接方式,該程序沒(méi)有用到鍵盤(pán) */ sbit CH451_dclk=P1^7; /* 串行數(shù)據(jù)時(shí)鐘上升延激活 */ sbit CH451_din=P1^6; /* 串行數(shù)據(jù)輸出,接CH451的數(shù)據(jù)輸入 */ sbit CH451_load=P1^5; /* 串行命令加載,上升延激活 */

/* 延時(shí)2微秒,不精確 */ void Delay2us( ) { unsigned char i; #define DELAY_START_VALUE 1 /* 根據(jù)單片機(jī)的時(shí)鐘選擇初值,20MHz以下為0,30MHz以上為2 */ for ( i=DELAY_START_VALUE; i!=0; i-- ); }

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

/* CH451初始化子程序 */ void CH451_Init( ) { CH451_din=0; /* 先低后高,選擇4線輸入 */ CH451_din=1; }

/* CH451輸出命令子程序 */ /* 定義一無(wú)符號(hào)整型變量存儲(chǔ)12字節(jié)的命令字 */ void CH451_Write( unsigned int command ) { unsigned char i; CH451_load=0; /* 命令開(kāi)始 */ for( i=0; i<12; i++ ) { /* 送入12位數(shù)據(jù),低位在前 */ CH451_din = command & 1; CH451_dclk = 0; command >>= 1; CH451_dclk = 1; /* 上升沿有效 */ } CH451_load = 1; /* 加載數(shù)據(jù) */ }

/* CH375初始化子程序 */ void CH375_Init( ) { unsigned char i; FLAG_RECV_OK=0; /* 清接收成功標(biāo)志,1指示成功接收到數(shù)據(jù)塊 */ FLAG_SEND_WAIT=0; /* 清發(fā)送等待標(biāo)志,1指示有數(shù)據(jù)塊正在CH375中等待發(fā)送 */ /* 測(cè)試CH375是否正常工作,可選操作,通常不需要 */ #ifdef TEST_CH375_FIRST CH375_CMD_PORT = CMD_CHECK_EXIST; /* 測(cè)試CH375是否正常工作 */ Delay2us( ); /* 如果時(shí)鐘頻率低于16MHz則無(wú)需該指令延時(shí) */ CH375_DAT_PORT = 0x55; /* 寫(xiě)入測(cè)試數(shù)據(jù) */ Delay2us( ); i = ~ 0x55; /* 返回?cái)?shù)據(jù)應(yīng)該是測(cè)試數(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( ); /* 延時(shí)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( ); /* 如果時(shí)鐘頻率低于16MHz則無(wú)需該指令延時(shí) */ CH375_DAT_PORT = (unsigned char)MY_USB_VENDOR_ID; /* 寫(xiě)入廠商ID的低字節(jié) */ CH375_DAT_PORT = (unsigned char)(MY_USB_VENDOR_ID>>8); /* 寫(xiě)入廠商ID的高字節(jié) */ CH375_DAT_PORT = (unsigned char)MY_USB_DEVICE_ID; /* 寫(xiě)入設(shè)備ID的低字節(jié) */ CH375_DAT_PORT = (unsigned char)(MY_USB_DEVICE_ID>>8); /* 寫(xiě)入設(shè)備ID的高字節(jié) */ Delay2us( ); #endif /* 設(shè)置USB工作模式, 必要操作 */ CH375_CMD_PORT = CMD_SET_USB_MODE; Delay2us( ); /* 如果時(shí)鐘頻率低于16MHz則無(wú)需該指令延時(shí) */ 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存在硬件錯(cuò)誤 }; */ /* 下述啟用中斷,假定CH375連接在INT0 */ IT0 = 0; /* 置外部信號(hào)為低電平觸發(fā) */ IE0 = 0; /* 清中斷標(biāo)志 */ EX0 = 1; /* 允許CH375中斷 */ }

/* CH375中斷服務(wù)程序,使用寄存器組1 */ void mCh375Interrupt( ) interrupt 0 using 1 { unsigned char InterruptStatus; unsigned char length, c1; unsigned char data *cmd_buf; unsigned char data *ret_buf; CH375_CMD_PORT = CMD_GET_STATUS; /* 獲取中斷狀態(tài)并取消中斷請(qǐng)求 */ Delay2us( ); /* 如果時(shí)鐘頻率低于16MHz則無(wú)需該指令延時(shí) */ InterruptStatus = CH375_DAT_PORT; /* 獲取中斷狀態(tài) */ IE0 = 0; /* 清中斷標(biāo)志,對(duì)應(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( ); /* 如果時(shí)鐘頻率低于16MHz則無(wú)需該指令延時(shí) */ length = CH375_DAT_PORT; /* 首先讀取后續(xù)數(shù)據(jù)長(zhǎng)度 */ if ( length != 0 ) { /* 如果長(zhǎng)度為0則不處理 */ THIS_CMD_CODE = CH375_DAT_PORT; /* 保存當(dāng)前命令碼,因?yàn)槲覀儨y(cè)試程序與PC機(jī)應(yīng)用程序約定首字節(jié)為命令碼 */ if ( THIS_CMD_CODE == TEST_DOWNLOAD ) { /* 測(cè)試下傳速度 */ while ( --length != 0 ) /* 先減1以去掉首字節(jié)后 */ c1 = CH375_DAT_PORT; /* 接收數(shù)據(jù),為了測(cè)試速度,數(shù)據(jù)舍棄,24MHz的MCS51每讀取一個(gè)字節(jié)需要2uS */ } else { /* 不是測(cè)試下傳速度的命令,先接收完命令包再分析 */ RECV_LEN = length; /* 命令包的數(shù)據(jù)長(zhǎng)度 */ cmd_buf = RECV_BUFFER; /* 接收緩沖區(qū) */ *cmd_buf = THIS_CMD_CODE; while ( --length != 0 ) { /* 先減1以去掉首字節(jié)后 */ cmd_buf++; *cmd_buf = CH375_DAT_PORT; } /* 以上程序C語(yǔ)言要每讀一個(gè)字節(jié)可能要十多個(gè)機(jī)器周期,如果用匯編語(yǔ)言只要4個(gè)機(jī)器周期 mov a,length jz skip_get mov r7,a mov dptr,#CH375_DAT_PORT get_next_byte: movx a,@dptr 數(shù)據(jù)直接放棄 djnz r7,get_next_byte skip_get: nop */ if ( THIS_CMD_CODE == TEST_UPLOAD ) { /* 測(cè)試上傳速度 */ CH375_CMD_PORT = CMD_WR_USB_DATA7; /* 向USB端點(diǎn)2的發(fā)送緩沖區(qū)寫(xiě)入數(shù)據(jù)塊 */ Delay2us( ); /* 如果時(shí)鐘頻率低于16MHz則無(wú)需該指令延時(shí) */ length = CH375_MAX_DATA_LEN; CH375_DAT_PORT = length; /* 首先寫(xiě)入后續(xù)數(shù)據(jù)長(zhǎng)度 */ do { CH375_DAT_PORT = TL0; /* 發(fā)送偽隨機(jī)數(shù)數(shù)據(jù),為了測(cè)試速度,數(shù)據(jù)無(wú)效,24MHz的MCS51每寫(xiě)出一個(gè)字節(jié)需要2uS */ } while ( --length != 0 ); } else if ( THIS_CMD_CODE == TEST_START ) { /* 測(cè)試過(guò)程開(kāi)始 */ /* 由于上一次測(cè)試數(shù)據(jù)上傳速度時(shí)可能在上傳緩沖區(qū)中遺留有數(shù)據(jù), 所以在第二次測(cè)試前需要清除上傳緩沖區(qū) */ CH375_CMD_PORT = CMD_SET_ENDP7; /* 設(shè)置USB端點(diǎn)2的IN */ Delay2us( ); /* 如果時(shí)鐘頻率低于16MHz則無(wú)需該指令延時(shí) */ CH375_DAT_PORT = 0x0e; /* 同步觸發(fā)位不變,設(shè)置USB端點(diǎn)2的IN正忙,返回NAK */ FLAG_SEND_WAIT = 0; /* 清除發(fā)送等待標(biāo)志,通知應(yīng)用程序可以繼續(xù)發(fā)送數(shù)據(jù) */ } else if ( THIS_CMD_CODE == TEST_DATA ) { /* 測(cè)試數(shù)據(jù)正確性,將接收到的命令包數(shù)據(jù)取反后返回給PC機(jī) */ CH375_CMD_PORT = CMD_WR_USB_DATA7; /* 向USB端點(diǎn)2的發(fā)送緩沖區(qū)寫(xiě)入數(shù)據(jù)塊 */ Delay2us( ); /* 如果時(shí)鐘頻率低于16MHz則無(wú)需該指令延時(shí) */ ret_buf = RECV_BUFFER; /* 接收緩沖區(qū) */ length = RECV_LEN; /* 剛接收到的數(shù)據(jù)長(zhǎng)度 */ CH375_DAT_PORT = length; /* 首先寫(xiě)入后續(xù)數(shù)據(jù)長(zhǎng)度 */ if ( length ) { do { CH375_DAT_PORT = ~ *ret_buf; /* 數(shù)據(jù)取反后返回,由計(jì)算機(jī)應(yīng)用程序測(cè)試數(shù)據(jù)是否正確 */ ret_buf++; } while ( --length != 0 ); } } else { /* 其它命令,尚未定義 */ FLAG_RECV_OK =


什么時(shí)候上傳取決你程序的約定,你可以發(fā)特定數(shù)據(jù)來(lái)啟動(dòng)傳輸,這也是一次正常數(shù)據(jù)傳輸,是你流程決定有沒(méi)有這一次傳輸。 上傳成功后會(huì)產(chǎn)生一個(gè)上傳成功的中斷,通知MCU已傳輸完成。


謝謝,可能我沒(méi)理解你的意思。


只有登錄才能回復(fù),可以選擇微信賬號(hào)登錄

国产91精品新入口,国产成人综合网在线播放,九热这里只有精品,本道在线观看,美女视频a美女视频,韩国美女激情视频,日本美女pvp视频