?? ch372drv.c
字號:
/*
; 單片機內置USB調試固件程序 V1.0
; 用于連接CH372或者CH375的單片機進行簡單的調試功能
; 可以用include直接包含到應用系統的主程序中,或者添加到工程項目中
;
; Website: http://winchiphead.com
; Email: tech@winchiphead.com
; @2004.08
;****************************************************************************
*/
// ------------------------------------------------------------------------------------------------------
/********************************************************************************************************
** CH372芯片說明
** CH372芯片占用兩個地址位,當A0引腳為高電平時選擇命令端口,可以寫入命令;當A0引腳為低電平時選擇數據端
** 口,可以讀寫數據。單片機通過8位并口對CH372芯片進行讀寫,所有操作都是由一個命令碼、若干個輸入數據和若干
** 個輸出數據組成,部分命令不需要輸入數據,部分命令沒有輸出數據。命令操作步驟如下:
** 1)在A0=1時向命令端口寫入命令代碼;
** 2)如果該命令具有輸入數據,則在A0=0時依次寫入輸入數據,每次一個字節;
** 3)如果該命令具有輸出數據,則在A0=0時依次讀取輸出數據,每次一個字節;
** 4)命令完成,可以暫停或者轉到1)繼續執行下一個命令。
** CH372芯片專門用于處理USB通訊,在接收到數據后或者發送完數據后,CH372以中斷方式通知單片機進行處理。
** 單片機通過CH372接收數據的處理步驟如下:
** 1)當CH372接收到USB主機發來的數據后,首先鎖定當前USB緩沖區,防止被后續數據覆蓋,然后將INT#引腳設置為低
** 電平,向單片機請求中斷;
** 2)單片機進入中斷服務程序,首先執行GET_STATUS命令獲取中斷狀態;
** 3)CH372在GET_STATUS命令完成后將INT#引腳恢復為高電平,取消中斷請求;
** 4)由于通過上述GET_STATUS命令獲取的中斷狀態是“下傳成功”,所以單片機執行RD_USB_DATA命令從CH372讀取接收到的數據;
** 5)
**
**
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
/* MCS-51單片機C語言, KC7.0 */
/* 用于其它類型單片機或者硬件資源不同時, 該程序應該根據需要進行局部修改 */
#include <c8051f020.h> // SFR declarations
#include "GlobeDef.h"
#include "CH372Drv.H"
#ifdef __CX51__
#ifndef __C51__
#define __C51__ 1
#endif
#endif
#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 56 // 單次命令處理的最大數據長度,有效值是1到56
#endif
#ifndef MAX_BUFFER_SIZE
#define MAX_BUFFER_SIZE MAX_DATA_SIZE+3 // 上傳或下傳緩沖區的最大長度(3代表命令碼/狀態碼、命令反碼和數據長度)
#endif
/* 上傳或下傳緩沖區索引定義 */
#define COMMAND_ID 0
#define COMMAND_NOT_ID 1
#define LENGTH_ID 2
#define DATA_START_ID 3
#define STATUS_ID 0
typedef USB_DOWN_BUFFER[MAX_BUFFER_SIZE]; // 計算機發給CH372的下傳緩沖區定義
typedef USB_UP_BUFFER[MAX_BUFFER_SIZE]; // CH372發給計算機的上傳緩沖區定義
/* 命令碼定義 */
#define USB_CMD_GET_FW_INFO 0x00 // 返回固件程序版本,并取消未完成的上傳數據塊
#define USB_CMD_GET_APP_INFO 0x01 // 返回當前應用系統的版本和說明字符串
#define USB_CMD_GET_TEST_DATA 0x02 // 返回當前測試數據
#define USB_CMD_GET_ALL_PARAMS 0x10 // 返回所有參數的值(不包含流量修正系數)
#define USB_CMD_GET_PRESS_SET 0x11 // 返回參數設定壓力
#define USB_CMD_GET_PRESS_MAX 0x12 // 返回參數壓力上限
#define USB_CMD_GET_PRESS_MIN 0x13 // 返回參數壓力下限
#define USB_CMD_GET_LEAK_MAX 0x14 // 返回參數流量上限
#define USB_CMD_GET_FILL_TIME 0x15 // 返回參數充氣時間
#define USB_CMD_GET_TEST_TIME 0x16 // 返回參數測試時間
#define USB_CMD_GET_ALL_COEFS 0x20 // 返回所有流量修正值及其系數
#define USB_CMD_GET_COEF_1 0x21 // 返回第一段流量修正值及其系數
#define USB_CMD_GET_COEF_2 0x22 // 返回第二段流量修正值及其系數
#define USB_CMD_GET_COEF_3 0x23 // 返回第三段流量修正值及其系數
#define USB_CMD_GET_COEF_4 0x24 // 返回第四段流量修正值及其系數
#define USB_CMD_SET_ALL_PARAMS 0x80 // 修改所有參數的值(不包含流量修正系數)
#define USB_CMD_SET_PRESS_SET 0x81 // 修改參數設定壓力
#define USB_CMD_SET_PRESS_MAX 0x82 // 修改參數壓力上限
#define USB_CMD_SET_PRESS_MIN 0x83 // 修改參數壓力下限
#define USB_CMD_SET_LEAK_MAX 0x84 // 修改參數流量上限
#define USB_CMD_SET_FILL_TIME 0x85 // 修改參數充氣時間
#define USB_CMD_SET_TEST_TIME 0x86 // 修改參數測試時間
#define USB_CMD_SET_ALL_COEFS 0x90 // 修改所有流量修正值及其系數
#define USB_CMD_SET_COEF_1 0x91 // 修改第一段流量修正值及其系數
#define USB_CMD_SET_COEF_2 0x92 // 修改第二段流量修正值及其系數
#define USB_CMD_SET_COEF_3 0x93 // 修改第三段流量修正值及其系數
#define USB_CMD_SET_COEF_4 0x94 // 修改第四段流量修正值及其系數
/* 狀態碼定義 */
#define ERR_SUCCESS 0x00 // 操作成功
#define ERR_PARAMETER 0x10 // 參數錯誤
#define ERR_UNSUPPORT 0x80 // 命令不支持
#define ERR_UNDEFINED 0xFF // 未定義的錯誤
/* 固件版本信息定義 */
#define THIS_FIRMWARE_VER 0x10 // 固件版本號
#define THIS_APP_SYS_VER 0x10 // 應用系統版本號
#define THIS_APP_SYS_STR "RA50" // 應用系統描述字符串
/* 一般常量定義 */
#define OP_CMD 1 // 命令操作碼
#define OP_DATA 0 // 數據操作碼
#define DELAY_TIMES 2 // 延時2微秒
#define DELAY_CNT_NUMS DELAY_TIMES*25 // 延時2微秒所需的時鐘周期數(對于22.1184MHz晶振,每個微秒包含22.1184個時鐘周期)
#define MY_USB_VENDOR_ID 0x4348 // USB設備制造商標識
#define MY_USB_PRODUCT_ID 0x5537 // USB設備產品標識
/* CH372芯片控制引腳定義 */
sbit USB_INT = P0^6; // XBR1.2 = 1(INT0EN = 1), P0MDOUT.6 = 0, INT0作為漏極開路方式輸入
sbit USB_A0 = P0^7; // P0MDOUT.7 = 1, 推挽方式, 數字輸出
sbit USB_WR = P3^0; // P3MDOUT.0 = 1,推挽方式,作為數字輸出
sbit USB_RD = P3^1; // P3MDOUT.1 = 1,推挽方式,作為數字輸出
sfr USB_DATA = 0x84; // P74OUT = 0x00,P4口被配置為漏極開路方式,使USB_DATA = 0xFF將其配置為數字輸入
/* 引入外部全局變量 */
extern INT16U data gnPressGet; // 測得的氣體壓力(單位為0.1KPa)
extern INT16U data gnLeakGet; // 測得的氣體流量(單位為0.01L/min)
extern INT16U data gnPressSet; // 用戶通過觸摸屏設定的氣體壓力(單位為0.1KPa)
extern INT16U data gnPressMax; // 用戶通過觸摸屏設定的允許最大氣體壓力(單位為0.1KPa)
extern INT16U data gnPressMin; // 用戶通過觸摸屏設定的允許最小氣體壓力(單位為0.1KPa)
extern INT16U data gnLeakMax; // 用戶通過觸摸屏設定的允許最大氣體流量(單位為0.01L/min)
extern INT16U data gnCurrTime; // 代表當前操作正在進行的時間
extern INT16U data gnFillTime; // 用戶通過觸摸屏設定的充氣時間
extern INT16U data gnTestTime; // 用戶通過觸摸屏設定的測試時間
extern INT16U idata gnLeakAreaMax[6]; // 用戶通過觸摸屏設定的分段修正流量最大值(單位為0.01L/min)
extern INT16U idata gnLeakAreaCoef[6]; // 用戶通過觸摸屏設定的分段修正流量系數
/* 延時2微秒,不精確,需要根據硬件實際情況調整 */
void Delay2us( )
{
INT8U i;
i = (INT8U)DELAY_CNT_NUMS;
while (--i);
}
/* 與CH372/CH375有關的基本I/O操作 */
/* 向CH375的命令端口寫入命令,周期不小于4uS,如果單片機較快則延時 */
void CH375_WR_CMD_PORT(INT8U cmd)
{
USB_WR = 1;
USB_RD = 1;
Delay2us();
USB_A0 = OP_CMD; // 準備寫命令
USB_DATA = cmd; // 準備命令數據
USB_WR = 0; // 開始寫命令
Delay2us();
USB_WR = 1; // 結束寫命令(USB_WR信號的有效時間不能超過10us)
}
/* 向CH375的數據端口寫入數據,周期不小于1.5uS,如果單片機較快則延時 */
void CH375_WR_DAT_PORT(INT8U dat)
{
USB_WR = 1;
USB_RD = 1;
Delay2us();
USB_A0 = OP_DATA; // 準備寫數據
USB_DATA = dat; // 準備數據
USB_WR = 0; // 開始寫數據
Delay2us();
USB_WR = 1; // 結束寫命令(USB_WR信號的有效時間不能超過10us)
}
/* 從CH375的數據端口讀出數據,周期不小于1.5uS,如果單片機較快則延時 */
INT8U CH375_RD_DAT_PORT(void)
{
INT8U nData;
USB_WR = 1;
USB_RD = 1;
Delay2us();
USB_DATA = 0xFF; // 將USB_DATA(P4口)配置為數字輸入
USB_A0 = OP_DATA; // 準備讀數據
USB_RD = 0; // 開始讀數據
Delay2us();
nData = USB_DATA; // 讀取數據
USB_RD = 1; // 結束讀命令(USB_RD信號的有效時間不能超過10us)
return nData; // 返回讀取的數據
}
/* CH375初始化子程序 */
void CH375_Init(void)
{
INT8U i;
/* 如果設置使用自定義的ID,那么計算機端驅動程序INF安裝文件中的"USB\VID_4348&PID_5537"需要進行類似修改 */
CH375_WR_CMD_PORT(CMD_SET_USB_ID); // 設置外部自定義的USB設備VID和PID,可選操作
CH375_WR_DAT_PORT((INT8U)MY_USB_VENDOR_ID); // 寫入廠商ID的低字節
CH375_WR_DAT_PORT((INT8U)(MY_USB_VENDOR_ID>>8)); // 寫入廠商ID的高字節
CH375_WR_DAT_PORT((INT8U)MY_USB_PRODUCT_ID); // 寫入產品ID的低字節
CH375_WR_DAT_PORT((INT8U)(MY_USB_PRODUCT_ID>>8)); // 寫入產品ID的高字節
/* 設置USB工作模式(內置固件的USB設備方式), 必要操作 */
CH375_WR_CMD_PORT(CMD_SET_USB_MODE);
CH375_WR_DAT_PORT(2);
/* 等待操作成功,通常需要等待10uS-20uS */
for (i=100; i!=0; i--)
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -