?? ch372dbg.c
字號:
/* 例子 */
/*
; 單片機(jī)內(nèi)置USB調(diào)試固件程序 V1.0
; 用于連接CH372或者CH375的單片機(jī)進(jìn)行簡單的調(diào)試功能
; 可以用include直接包含到應(yīng)用系統(tǒng)的主程序中,或者添加到工程項(xiàng)目中
;
; Website: http://winchiphead.com
; Email: tech@winchiphead.com
; @2004.08
;****************************************************************************
*/
/* MCS-51單片機(jī)C語言, KC7.0 */
/* 用于其它類型單片機(jī)或者硬件資源不同時(shí), 該程序應(yīng)該根據(jù)需要進(jìn)行局部修改 */
#include <reg52.h>
#include "CH375INC.H"
#include "IIC.h"
#ifdef __CX51__
#ifndef __C51__
#define __C51__ 1
#endif
#endif
typedef unsigned char UINT8;
typedef unsigned short UINT16;
typedef unsigned long UINT32;
#ifdef __C51__
typedef unsigned char idata *PUINT8;
#else
typedef unsigned char *PUINT8;
#endif
#ifdef __C51__
typedef unsigned char xdata *PUINT8X;
#else
typedef unsigned char *PUINT8X;
#endif
#ifdef __C51__
typedef unsigned char code *PUINT8C;
#else
typedef unsigned char *PUINT8C;
#endif
#ifdef __C51__
#pragma NOAREGS
#endif
#ifndef MAX_DATA_SIZE
#define MAX_DATA_SIZE 32 /* 單次命令處理的最大數(shù)據(jù)長度,有效值是1到56 */
#endif
typedef struct _USB_DOWN_PACKET { /* 下傳的數(shù)據(jù)包結(jié)構(gòu),用于命令/寫數(shù)據(jù) */
UINT8 mCommand; /* 命令碼,見下面的定義 */
UINT8 mCommandNot; /* 命令碼的反碼,用于校驗(yàn)下傳數(shù)據(jù)包 */
union {
UINT8 mByte[4]; /* 通用參數(shù) */
UINT16 mWord[2]; /* 通用參數(shù),低字節(jié)在前,Little-Endian */
UINT32 mDword; /* 通用參數(shù),低字節(jié)在前,Little-Endian */
void *mAddress; /* 讀寫操作的起始地址,低字節(jié)在前,Little-Endian */
} u;
UINT8 mLength; /* 下面的緩沖區(qū)的長度,讀寫操作的字節(jié)數(shù) */
UINT8 mBuffer[ MAX_DATA_SIZE ]; /* 數(shù)據(jù)緩沖區(qū) */
} USB_DOWN_PKT;
//輸入數(shù)據(jù)格式如下:
//1-命令 2-命令反碼 3-模式設(shè)定和配置 4-器件地址 5-內(nèi)部單元地址高字節(jié)(當(dāng)?shù)刂纺J綖閱巫止?jié)時(shí)不必理會) 6-低字節(jié) 7-后續(xù)數(shù)據(jù)長度 8------數(shù)據(jù)
//1-VCC 2-GND 3-RXD-P3.0 4-TXD-P3.1 5-T1-P3.5 6-GND
//IIC SCL SDA 須加10K的上拉電阻
/////////////////////////////////////////////////////////////////////////
//IIC: TYPE(8b) DEV_ADD(8b) SUB_ADD_L SUB_ADD_H (16b)
// TYPE( bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 )
// 000 RSV 00/01 00/01
// IIC | |(8b/16bADDR) |(100K/200K)
typedef struct _USB_UP_PACKET { /* 上傳的數(shù)據(jù)包結(jié)構(gòu),用于狀態(tài)/讀數(shù)據(jù) */
UINT8 mStatus; /* 狀態(tài)碼,見下面的定義 */
UINT8 mCommandNot; /* 命令碼的反碼,用于校驗(yàn)上傳數(shù)據(jù)包 */
UINT8 mReserved[4];
UINT8 mLength; /* 下面的緩沖區(qū)的長度,讀操作的字節(jié)數(shù) */
UINT8 mBuffer[ MAX_DATA_SIZE ]; /* 數(shù)據(jù)緩沖區(qū) */
} USB_UP_PKT;
typedef union _USB_DATA_PACKET { /* USB上傳或者下傳數(shù)據(jù)緩沖區(qū) */
USB_DOWN_PKT down;
USB_UP_PKT up;
} USB_DATA_PKT;
/* 命令碼定義,按位說明
位7為命令類型: 0=實(shí)現(xiàn)特定功能, 1=存儲器和SFR讀寫
對于"實(shí)現(xiàn)特定功能"命令類型:
位6-位0為定義的具體命令碼, 命令碼為00H-7FH, 其中: 00H-3FH為通用標(biāo)準(zhǔn)命令, 40H-7FH為與應(yīng)用系統(tǒng)有關(guān)的特定命令
目前版本定義了以下通用標(biāo)準(zhǔn)命令:
00H: 獲取調(diào)試固件程序的版本,并取消未完成的上傳數(shù)據(jù)塊
10H: 獲取當(dāng)前應(yīng)用系統(tǒng)的版本和說明字符串
對于"存儲器和SFR讀寫"命令類型:
位6為數(shù)據(jù)傳輸方向: 0=讀操作/上傳, 1=寫操作/下傳
位5-位4為數(shù)據(jù)讀寫寬度: 00=以字節(jié)為單位/8位, 01=以字為單位/16位, 10=以雙字為單位/32位, 11=以位為單位/1位
位1-位0為存儲器空間: 00=存取SFR, 01=存取內(nèi)部RAM, 10=存取外部RAM, 11=存取程序ROM
例如: 命令碼80H為讀SFR, 命令碼83H為讀程序ROM, 命令碼C1H為寫內(nèi)部RAM, 命令碼C2H為寫外部RAM
狀態(tài)碼定義: 00H為操作成功, 080H為命令不支持, 0FFH為未定義的錯(cuò)誤 */
#define USB_CMD_GET_FW_INFO 0x00
#define USB_CMD_GET_APP_INFO 0x10
#define USB_CMD_CLOSE_S 0x07 //關(guān)閉串口,沒有參數(shù)
#define USB_CMD_SEND_TXD 0x08 //串口發(fā)送數(shù)據(jù)命令,需要加入具體的數(shù)據(jù)長度及數(shù)據(jù)
#define USB_CMD_OPEN_S 0x09 //打開串口,沒有參數(shù)
#define USB_CMD_SET_BO 0X0a //設(shè)置波特率,在此用定時(shí)器2,波特率常數(shù)=晶振頻率/32/波特率
#define USB_CMD_GET_RXD_DATA 0X11 //串口接收數(shù)據(jù)命令,沒有參數(shù)
#define USB_CMD_EXCHANGE_DATA_OUT 0x12 //iic寫數(shù)據(jù)
#define USB_CMD_EXCHANGE_DATA_IN 0x13 //iic讀數(shù)據(jù)
#define USB_CMD_MEM_ACCESS 0x80
#define USB_CMD_MEM_DIR_WR 0x40
#define USB_CMD_MEM_WIDTH 0x0C
#define USB_CMD_MEM_W_BYTE 0x00
#define USB_CMD_MEM_W_WORD 0x04
#define USB_CMD_MEM_W_DWORD 0x08
#define USB_CMD_MEM_W_BIT 0x0C
#define USB_CMD_MEM_SPACE 0x03
#define USB_CMD_MEM_S_SFR 0x00
#define USB_CMD_MEM_S_IRAM 0x01
#define USB_CMD_MEM_S_XRAM 0x02
#define USB_CMD_MEM_S_ROM 0x03
#define ERR_SUCCESS 0x00
#define ERR_PARAMETER 0x10
#define ERR_UNSUPPORT 0x80
#define ERR_UNDEFINED 0xFF
#define ERR_NOPENSER 0X11
#define THIS_FIRMWARE_VER 0x10
#define THIS_APP_SYS_VER 0x09
#define THIS_APP_SYS_STR "Example for USB DEBUG MCS51"
#define DELAY_START_VALUE 1 /* 根據(jù)單片機(jī)的時(shí)鐘選擇初值,20MHz以下為0,30MHz以上為2 */
/*#define TEST_CH375_FIRST 1*/
/*#define MY_USB_VENDOR_ID 0x4348*/
/*#define MY_USB_PRODUCT_ID 0x5537*/
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地址 */
UINT8 mTxdLen;
UINT8 TXDBUF[16];
UINT8 *pTxdbuf;
UINT8 RXDBUF[16];
UINT8 *pRxdbuf;
UINT8 mRxdLen;
bit FLAG_RXD;
unsigned char iic_addr_b;
bit iic_speed;
/* 延時(shí)1微秒,不精確,需要根據(jù)硬件實(shí)際情況調(diào)整 */
void Delay1us( )
{
#if DELAY_START_VALUE != 0
UINT8 i;
for ( i=DELAY_START_VALUE; i!=0; i-- );
#endif
}
/* 延時(shí)2微秒,不精確,需要根據(jù)硬件實(shí)際情況調(diào)整 */
void Delay2us( )
{
UINT8 i;
for ( i=DELAY_START_VALUE*2+1; i!=0; i-- );
}
/* 與CH372/CH375有關(guān)的基本I/O操作 */
void CH375_WR_CMD_PORT( UINT8 cmd ) { /* 向CH375的命令端口寫入命令,周期不小于4uS,如果單片機(jī)較快則延時(shí) */
Delay2us();
CH375_CMD_PORT=cmd;
Delay2us();
}
void CH375_WR_DAT_PORT( UINT8 dat ) { /* 向CH375的數(shù)據(jù)端口寫入數(shù)據(jù),周期不小于1.5uS,如果單片機(jī)較快則延時(shí) */
CH375_DAT_PORT=dat;
Delay1us(); /* 如果是MCS51單片機(jī),因其較慢,所以實(shí)際上無需延時(shí) */
}
UINT8 CH375_RD_DAT_PORT( void ) { /* 從CH375的數(shù)據(jù)端口讀出數(shù)據(jù),周期不小于1.5uS,如果單片機(jī)較快則延時(shí) */
Delay1us(); /* 如果是MCS51單片機(jī),因其較慢,所以實(shí)際上無需延時(shí) */
return( CH375_DAT_PORT );
}
/* CH375初始化子程序 */
void CH375_Init( void ) {
UINT8 i;
#ifdef TEST_CH375_FIRST
/* 測試CH375與單片機(jī)的物理連接是否正常以及是否正常工作,可選操作,通常不需要 */
UINT8 j;
CH375_WR_CMD_PORT( CMD_CHECK_EXIST ); /* 測試CH375是否正常工作 */
CH375_WR_DAT_PORT( 0x55 ); /* 寫入測試數(shù)據(jù),任意數(shù)據(jù) */
i = ~ 0x55; /* 返回?cái)?shù)據(jù)應(yīng)該是測試數(shù)據(jù)取反 */
if ( CH375_RD_DAT_PORT( ) != i ) { /* CH375不正常 */
for ( i=80; i!=0; i-- ) {
CH375_WR_CMD_PORT( CMD_RESET_ALL ); /* 多次重復(fù)發(fā)命令,執(zhí)行硬件復(fù)位 */
CH375_RD_DAT_PORT( );
}
CH375_WR_CMD_PORT( 0 );
for ( i=250; i!=0; i-- ) for( j=100; j!=0; j-- ) Delay2us( ); /* 延時(shí)50mS */
}
#endif
#ifdef MY_USB_VENDOR_ID
#ifdef MY_USB_PRODUCT_ID
/* 設(shè)置外部自定義的USB設(shè)備VID和PID,可選操作,不執(zhí)行該命令則使用默認(rèn)的VID和PID,
如果設(shè)置使用自定義的ID,那么計(jì)算機(jī)端驅(qū)動程序INF安裝文件中的"USB\VID_4348&PID_5537"需要進(jìn)行類似修改 */
CH375_WR_CMD_PORT( CMD_SET_USB_ID ); /* 設(shè)置外部自定義的USB設(shè)備VID和PID,可選操作 */
CH375_WR_DAT_PORT( (UINT8)MY_USB_VENDOR_ID ); /* 寫入廠商ID的低字節(jié) */
CH375_WR_DAT_PORT( (UINT8)(MY_USB_VENDOR_ID>>8) ); /* 寫入廠商ID的高字節(jié) */
CH375_WR_DAT_PORT( (UINT8)MY_USB_PRODUCT_ID ); /* 寫入產(chǎn)品ID的低字節(jié) */
CH375_WR_DAT_PORT( (UINT8)(MY_USB_PRODUCT_ID>>8) ); /* 寫入產(chǎn)品ID的高字節(jié) */
#endif
#endif
/* 設(shè)置USB工作模式, 必要操作 */
CH375_WR_CMD_PORT( CMD_SET_USB_MODE );
CH375_WR_DAT_PORT( 2 ); /* 設(shè)置為使用內(nèi)置固件的USB設(shè)備方式 */
for ( i=100; i!=0; i-- ) if ( CH375_RD_DAT_PORT( ) == CMD_RET_SUCCESS ) break; /* 等待操作成功,通常需要等待10uS-20uS */
/* if ( i == 0 ) { CH372/CH375芯片內(nèi)部或者物理連接存在硬件錯(cuò)誤 }; */
/* 下面啟用USB中斷,CH375的INT#引腳可以連接到單片機(jī)的中斷引腳,中斷為低電平有效或者下降沿有效,
如果不使用中斷,那么也可以用查詢方式,由單片機(jī)程序查詢CH375的INT#引腳為低電平 */
IT0 = 0; /* 置外部信號為低電平觸發(fā) */
IE0 = 0; /* 清中斷標(biāo)志 */
EX0 = 1; /* 允許CH375中斷,假定CH375的INT#引腳連接到單片機(jī)的INT0 */
}
/* CH375中斷服務(wù)程序,假定CH375的INT#引腳連接到單片機(jī)的INT0,使用寄存器組1 */
void mCH375Interrupt( void ) interrupt 0 //using 1
{
UINT8 cnt;
UINT8 dat;
PUINT8 buf;
PUINT8C str;
USB_DATA_PKT udp;
#define IntStatus dat /* 節(jié)約一個(gè)變量存儲單元 */
CH375_WR_CMD_PORT( CMD_GET_STATUS ); /* 獲取中斷狀態(tài)并取消中斷請求 */
IntStatus = CH375_RD_DAT_PORT( ); /* 獲取中斷狀態(tài) */
/* IE0 = 0; 清中斷標(biāo)志,與單片機(jī)硬件有關(guān),對應(yīng)于INT0中斷 */
if ( IntStatus == USB_INT_EP2_OUT ) { /* 批量端點(diǎn)下傳成功,接收到命令包 */
CH375_WR_CMD_PORT( CMD_RD_USB_DATA ); /* 從當(dāng)前USB中斷的端點(diǎn)緩沖區(qū)讀取數(shù)據(jù)塊,并釋放緩沖區(qū) */
cnt = CH375_RD_DAT_PORT( ); /* 首先讀取后續(xù)數(shù)據(jù)長度 */
if ( cnt == 0 ) { /* 長度為0,沒有數(shù)據(jù),在某些應(yīng)用中也可以將長度0定義為一種特殊命令 */
CH375_WR_CMD_PORT( CMD_SET_ENDP7 ); /* 設(shè)置USB端點(diǎn)2的IN,也就是批量上傳端點(diǎn) */
CH375_WR_DAT_PORT( 0x0E ); /* 同步觸發(fā)位不變,設(shè)置USB端點(diǎn)2的IN正忙,返回NAK,實(shí)際是清除上傳緩沖區(qū)的已有內(nèi)容 */
return;
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -