?? ch372dbg.c
字號:
/* 例子 */
/*
; 單片機內置USB調試固件程序 V1.0
; 用于連接CH372或者CH375的單片機進行簡單的調試功能
; 可以用include直接包含到應用系統的主程序中,或者添加到工程項目中
;
; Website: http://winchiphead.com
; Email: tech@winchiphead.com
; @2004.08
;****************************************************************************
*/
/* MCS-51單片機C語言, KC7.0 */
/* 用于其它類型單片機或者硬件資源不同時, 該程序應該根據需要進行局部修改 */
#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 /* 單次命令處理的最大數據長度,有效值是1到56 */
#endif
typedef struct _USB_DOWN_PACKET { /* 下傳的數據包結構,用于命令/寫數據 */
UINT8 mCommand; /* 命令碼,見下面的定義 */
UINT8 mCommandNot; /* 命令碼的反碼,用于校驗下傳數據包 */
union {
UINT8 mByte[4]; /* 通用參數 */
UINT16 mWord[2]; /* 通用參數,低字節在前,Little-Endian */
UINT32 mDword; /* 通用參數,低字節在前,Little-Endian */
void *mAddress; /* 讀寫操作的起始地址,低字節在前,Little-Endian */
} u;
UINT8 mLength; /* 下面的緩沖區的長度,讀寫操作的字節數 */
UINT8 mBuffer[ MAX_DATA_SIZE ]; /* 數據緩沖區 */
} USB_DOWN_PKT;
//輸入數據格式如下:
//1-命令 2-命令反碼 3-模式設定和配置 4-器件地址 5-內部單元地址高字節(當地址模式為單字節時不必理會) 6-低字節 7-后續數據長度 8------數據
//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 { /* 上傳的數據包結構,用于狀態/讀數據 */
UINT8 mStatus; /* 狀態碼,見下面的定義 */
UINT8 mCommandNot; /* 命令碼的反碼,用于校驗上傳數據包 */
UINT8 mReserved[4];
UINT8 mLength; /* 下面的緩沖區的長度,讀操作的字節數 */
UINT8 mBuffer[ MAX_DATA_SIZE ]; /* 數據緩沖區 */
} USB_UP_PKT;
typedef union _USB_DATA_PACKET { /* USB上傳或者下傳數據緩沖區 */
USB_DOWN_PKT down;
USB_UP_PKT up;
} USB_DATA_PKT;
/* 命令碼定義,按位說明
位7為命令類型: 0=實現特定功能, 1=存儲器和SFR讀寫
對于"實現特定功能"命令類型:
位6-位0為定義的具體命令碼, 命令碼為00H-7FH, 其中: 00H-3FH為通用標準命令, 40H-7FH為與應用系統有關的特定命令
目前版本定義了以下通用標準命令:
00H: 獲取調試固件程序的版本,并取消未完成的上傳數據塊
10H: 獲取當前應用系統的版本和說明字符串
對于"存儲器和SFR讀寫"命令類型:
位6為數據傳輸方向: 0=讀操作/上傳, 1=寫操作/下傳
位5-位4為數據讀寫寬度: 00=以字節為單位/8位, 01=以字為單位/16位, 10=以雙字為單位/32位, 11=以位為單位/1位
位1-位0為存儲器空間: 00=存取SFR, 01=存取內部RAM, 10=存取外部RAM, 11=存取程序ROM
例如: 命令碼80H為讀SFR, 命令碼83H為讀程序ROM, 命令碼C1H為寫內部RAM, 命令碼C2H為寫外部RAM
狀態碼定義: 00H為操作成功, 080H為命令不支持, 0FFH為未定義的錯誤 */
#define USB_CMD_GET_FW_INFO 0x00
#define USB_CMD_GET_APP_INFO 0x10
#define USB_CMD_CLOSE_S 0x07 //關閉串口,沒有參數
#define USB_CMD_SEND_TXD 0x08 //串口發送數據命令,需要加入具體的數據長度及數據
#define USB_CMD_OPEN_S 0x09 //打開串口,沒有參數
#define USB_CMD_SET_BO 0X0a //設置波特率,在此用定時器2,波特率常數=晶振頻率/32/波特率
#define USB_CMD_GET_RXD_DATA 0X11 //串口接收數據命令,沒有參數
#define USB_CMD_EXCHANGE_DATA_OUT 0x12 //iic寫數據
#define USB_CMD_EXCHANGE_DATA_IN 0x13 //iic讀數據
#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 /* 根據單片機的時鐘選擇初值,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數據端口的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;
/* 延時1微秒,不精確,需要根據硬件實際情況調整 */
void Delay1us( )
{
#if DELAY_START_VALUE != 0
UINT8 i;
for ( i=DELAY_START_VALUE; i!=0; i-- );
#endif
}
/* 延時2微秒,不精確,需要根據硬件實際情況調整 */
void Delay2us( )
{
UINT8 i;
for ( i=DELAY_START_VALUE*2+1; i!=0; i-- );
}
/* 與CH372/CH375有關的基本I/O操作 */
void CH375_WR_CMD_PORT( UINT8 cmd ) { /* 向CH375的命令端口寫入命令,周期不小于4uS,如果單片機較快則延時 */
Delay2us();
CH375_CMD_PORT=cmd;
Delay2us();
}
void CH375_WR_DAT_PORT( UINT8 dat ) { /* 向CH375的數據端口寫入數據,周期不小于1.5uS,如果單片機較快則延時 */
CH375_DAT_PORT=dat;
Delay1us(); /* 如果是MCS51單片機,因其較慢,所以實際上無需延時 */
}
UINT8 CH375_RD_DAT_PORT( void ) { /* 從CH375的數據端口讀出數據,周期不小于1.5uS,如果單片機較快則延時 */
Delay1us(); /* 如果是MCS51單片機,因其較慢,所以實際上無需延時 */
return( CH375_DAT_PORT );
}
/* CH375初始化子程序 */
void CH375_Init( void ) {
UINT8 i;
#ifdef TEST_CH375_FIRST
/* 測試CH375與單片機的物理連接是否正常以及是否正常工作,可選操作,通常不需要 */
UINT8 j;
CH375_WR_CMD_PORT( CMD_CHECK_EXIST ); /* 測試CH375是否正常工作 */
CH375_WR_DAT_PORT( 0x55 ); /* 寫入測試數據,任意數據 */
i = ~ 0x55; /* 返回數據應該是測試數據取反 */
if ( CH375_RD_DAT_PORT( ) != i ) { /* CH375不正常 */
for ( i=80; i!=0; i-- ) {
CH375_WR_CMD_PORT( CMD_RESET_ALL ); /* 多次重復發命令,執行硬件復位 */
CH375_RD_DAT_PORT( );
}
CH375_WR_CMD_PORT( 0 );
for ( i=250; i!=0; i-- ) for( j=100; j!=0; j-- ) Delay2us( ); /* 延時50mS */
}
#endif
#ifdef MY_USB_VENDOR_ID
#ifdef MY_USB_PRODUCT_ID
/* 設置外部自定義的USB設備VID和PID,可選操作,不執行該命令則使用默認的VID和PID,
如果設置使用自定義的ID,那么計算機端驅動程序INF安裝文件中的"USB\VID_4348&PID_5537"需要進行類似修改 */
CH375_WR_CMD_PORT( CMD_SET_USB_ID ); /* 設置外部自定義的USB設備VID和PID,可選操作 */
CH375_WR_DAT_PORT( (UINT8)MY_USB_VENDOR_ID ); /* 寫入廠商ID的低字節 */
CH375_WR_DAT_PORT( (UINT8)(MY_USB_VENDOR_ID>>8) ); /* 寫入廠商ID的高字節 */
CH375_WR_DAT_PORT( (UINT8)MY_USB_PRODUCT_ID ); /* 寫入產品ID的低字節 */
CH375_WR_DAT_PORT( (UINT8)(MY_USB_PRODUCT_ID>>8) ); /* 寫入產品ID的高字節 */
#endif
#endif
/* 設置USB工作模式, 必要操作 */
CH375_WR_CMD_PORT( CMD_SET_USB_MODE );
CH375_WR_DAT_PORT( 2 ); /* 設置為使用內置固件的USB設備方式 */
for ( i=100; i!=0; i-- ) if ( CH375_RD_DAT_PORT( ) == CMD_RET_SUCCESS ) break; /* 等待操作成功,通常需要等待10uS-20uS */
/* if ( i == 0 ) { CH372/CH375芯片內部或者物理連接存在硬件錯誤 }; */
/* 下面啟用USB中斷,CH375的INT#引腳可以連接到單片機的中斷引腳,中斷為低電平有效或者下降沿有效,
如果不使用中斷,那么也可以用查詢方式,由單片機程序查詢CH375的INT#引腳為低電平 */
IT0 = 0; /* 置外部信號為低電平觸發 */
IE0 = 0; /* 清中斷標志 */
EX0 = 1; /* 允許CH375中斷,假定CH375的INT#引腳連接到單片機的INT0 */
}
/* CH375中斷服務程序,假定CH375的INT#引腳連接到單片機的INT0,使用寄存器組1 */
void mCH375Interrupt( void ) interrupt 0 //using 1
{
UINT8 cnt;
UINT8 dat;
PUINT8 buf;
PUINT8C str;
USB_DATA_PKT udp;
#define IntStatus dat /* 節約一個變量存儲單元 */
CH375_WR_CMD_PORT( CMD_GET_STATUS ); /* 獲取中斷狀態并取消中斷請求 */
IntStatus = CH375_RD_DAT_PORT( ); /* 獲取中斷狀態 */
/* IE0 = 0; 清中斷標志,與單片機硬件有關,對應于INT0中斷 */
if ( IntStatus == USB_INT_EP2_OUT ) { /* 批量端點下傳成功,接收到命令包 */
CH375_WR_CMD_PORT( CMD_RD_USB_DATA ); /* 從當前USB中斷的端點緩沖區讀取數據塊,并釋放緩沖區 */
cnt = CH375_RD_DAT_PORT( ); /* 首先讀取后續數據長度 */
if ( cnt == 0 ) { /* 長度為0,沒有數據,在某些應用中也可以將長度0定義為一種特殊命令 */
CH375_WR_CMD_PORT( CMD_SET_ENDP7 ); /* 設置USB端點2的IN,也就是批量上傳端點 */
CH375_WR_DAT_PORT( 0x0E ); /* 同步觸發位不變,設置USB端點2的IN正忙,返回NAK,實際是清除上傳緩沖區的已有內容 */
return;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -