?? ch372drv.c
字號:
{
if (CH375_RD_DAT_PORT() == CMD_RET_SUCCESS)
break;
}
/* 下面啟用USB中斷,CH372的INT#引腳可以連接到單片機的中斷引腳,中斷為低電平有效或者下降沿有效,
如果不使用中斷,那么也可以用查詢方式,由單片機程序查詢CH372的INT#引腳為低電平 */
IT0 = 0; // 置外部信號為低電平觸發
IE0 = 0; // 清中斷標志
EX0 = 1; // 允許CH372中斷,假定CH372的INT#引腳連接到單片機的INT0
}
/* CH375中斷服務程序,假定CH375的INT#引腳連接到單片機的INT0,使用寄存器組1 */
void mCH375Interrupt(void) interrupt INT_INT0 using 1
{
INT8U id;
INT8U cnt;
INT8U dat;
PUINT8C str;
USB_DOWN_BUFFER down;
USB_UP_BUFFER up;
#define IntStatus dat // 節約一個變量存儲單元
CH375_WR_CMD_PORT((INT8U)CMD_GET_STATUS); // 獲取中斷狀態并取消中斷請求
IntStatus = CH375_RD_DAT_PORT(); // 獲取中斷狀態
USB_INT = 1;
IE0 = 0; // 清中斷標志,與單片機硬件有關,對應于INT0中斷
/* 批量端點下傳成功,接收到命令包 */
if (IntStatus == USB_INT_EP2_OUT)
{
CH375_WR_CMD_PORT((INT8U)CMD_RD_USB_DATA); // 從當前USB中斷的端點緩沖區讀取數據塊,并釋放緩沖區
cnt = CH375_RD_DAT_PORT(); // 首先讀取后續數據長度
if (cnt == 0) // 長度為0,沒有數據,在某些應用中也可以將長度0定義為一種特殊命令
{
CH375_WR_CMD_PORT((INT8U)CMD_SET_ENDP7); // 設置USB端點2的IN,也就是批量上傳端點
CH375_WR_DAT_PORT((INT8U)0x0E); // 同步觸發位不變,設置USB端點2的IN正忙,返回NAK,實際是清除上傳緩沖區的已有內容
return;
}
id = 0;
do
{
down[id] = CH375_RD_DAT_PORT(); // 接收命令包的數據
id++;
} while (--cnt); // 接收完所有的下傳數據
/* 命令包反碼校驗錯誤,放棄該下傳包 */
if (down[COMMAND_ID] != (INT8U)(~down[COMMAND_NOT_ID]))
return;
/* 根據命令碼實現不同的功能 */
if (down[COMMAND_ID] < USB_CMD_SET_ALL_PARAMS) // 讀操作命令,需要返回數據
{
up[STATUS_ID] = ERR_SUCCESS; // 準備狀態碼
up[COMMAND_NOT_ID] = down[COMMAND_NOT_ID]; // 準備命令反碼
switch (down[COMMAND_ID])
{
case USB_CMD_GET_FW_INFO: /* 返回固件程序版本,并取消未完成的上傳數據塊 */
up[DATA_START_ID] = THIS_FIRMWARE_VER; // 準備固件程序版本
up[LENGTH_ID] = 1; // 發送一個字節(不包含幀頭部分的三個字節)
CH375_WR_CMD_PORT((INT8U)CMD_SET_ENDP7); // 設置USB端點2的IN,也就是批量上傳端點
CH375_WR_DAT_PORT((INT8U)0x0E); // 同步觸發位不變,設置USB端點2的IN正忙,返回NAK,實際是清除上傳緩沖區的已有內容
break;
case USB_CMD_GET_APP_INFO: /* 返回當前應用系統的版本和說明字符串 */
up[DATA_START_ID] = THIS_APP_SYS_VER; // 準備應用系統的版本
cnt = 1;
str = THIS_APP_SYS_STR; // 準備說明字符串
while (up[DATA_START_ID + cnt] = *str)
{
cnt++;
str++;
}
up[LENGTH_ID] = 1 + sizeof(THIS_APP_SYS_STR); // 設置緩沖區長度(不包含幀頭部分的三個字節)
break;
case USB_CMD_GET_TEST_DATA: /* 返回當前測試數據 */
up[DATA_START_ID + 0] = gnPressGet % 256; // 準備測試壓力值的低8位
up[DATA_START_ID + 1] = gnPressGet / 256; // 準備測試壓力值的高8位
up[DATA_START_ID + 2] = gnLeakGet % 256; // 準備氣體流量的低8位
up[DATA_START_ID + 3] = gnLeakGet / 256; // 準備氣體流量的高8位
up[LENGTH_ID] = 4; // 準備緩沖區長度(不包含幀頭部分的三個字節)
break;
case USB_CMD_GET_ALL_PARAMS: /* 返回所有參數的值(不包含流量修正系數) */
up[DATA_START_ID + 0] = gnPressGet % 256; // 準備測試壓力值的低8位
up[DATA_START_ID + 1] = gnPressGet / 256; // 準備測試壓力值的高8位
up[DATA_START_ID + 2] = gnPressMax % 256; // 準備壓力上限值的低8位
up[DATA_START_ID + 3] = gnPressMax / 256; // 準備壓力上限值的高8位
up[DATA_START_ID + 4] = gnPressMin % 256; // 準備壓力下限值的低8位
up[DATA_START_ID + 5] = gnPressMin / 256; // 準備壓力下限值的高8位
up[DATA_START_ID + 6] = gnLeakMax % 256; // 準備流量上限值的低8位
up[DATA_START_ID + 7] = gnLeakMax / 256; // 準備流量上限值的高8位
up[DATA_START_ID + 8] = gnFillTime % 256; // 準備充氣時間的低8位
up[DATA_START_ID + 9] = gnFillTime / 256; // 準備充氣時間的高8位
up[DATA_START_ID + 10]= gnTestTime % 256; // 準備測試時間的低8位
up[DATA_START_ID + 11]= gnTestTime / 256; // 準備測試時間的高8位
up[LENGTH_ID] = 12; // 準備緩沖區長度(不包含幀頭部分的三個字節)
break;
case USB_CMD_GET_PRESS_SET: /* 返回參數設定壓力 */
up[DATA_START_ID + 0] = gnPressGet % 256; // 準備測試壓力值的低8位
up[DATA_START_ID + 1] = gnPressGet / 256; // 準備測試壓力值的高8位
up[LENGTH_ID] = 2; // 準備緩沖區長度
break;
case USB_CMD_GET_PRESS_MAX: /* 返回參數壓力上限 */
up[DATA_START_ID + 0] = gnPressMax % 256; // 準備壓力上限值的低8位
up[DATA_START_ID + 1] = gnPressMax / 256; // 準備壓力上限值的高8位
up[LENGTH_ID] = 2; // 準備緩沖區長度
break;
case USB_CMD_GET_PRESS_MIN: /* 返回參數壓力下限 */
up[DATA_START_ID + 0] = gnPressMin % 256; // 準備壓力下限值的低8位
up[DATA_START_ID + 1] = gnPressMin / 256; // 準備壓力下限值的高8位
up[LENGTH_ID] = 2; // 準備緩沖區長度
break;
case USB_CMD_GET_LEAK_MAX: /* 返回參數流量上限 */
up[DATA_START_ID + 0] = gnLeakMax % 256; // 準備流量上限值的低8位
up[DATA_START_ID + 1] = gnLeakMax / 256; // 準備流量上限值的高8位
up[LENGTH_ID] = 2; // 準備緩沖區長度
break;
case USB_CMD_GET_FILL_TIME: /* 返回參數充氣時間 */
up[DATA_START_ID + 0] = gnFillTime % 256; // 準備充氣時間的低8位
up[DATA_START_ID + 1] = gnFillTime / 256; // 準備充氣時間的高8位
up[LENGTH_ID] = 2; // 準備緩沖區長度
break;
case USB_CMD_GET_TEST_TIME: /* 返回參數測試時間 */
up[DATA_START_ID + 0] = gnTestTime % 256; // 準備測試時間的低8位
up[DATA_START_ID + 1] = gnTestTime / 256; // 準備測試時間的高8位
up[LENGTH_ID] = 2; // 準備緩沖區長度
break;
case USB_CMD_GET_ALL_COEFS: /* 返回所有流量修正值及其系數 */
up[DATA_START_ID + 0] = gnLeakAreaMax[0] % 256; // 準備第一段流量修正值的低8位
up[DATA_START_ID + 1] = gnLeakAreaMax[0] / 256; // 準備第一段流量修正值的高8位
up[DATA_START_ID + 2] = gnLeakAreaCoef[0] % 256; // 準備第一段流量修正系數的低8位
up[DATA_START_ID + 3] = gnLeakAreaCoef[0] / 256; // 準備第一段流量修正系數的高8位
up[DATA_START_ID + 4] = gnLeakAreaMax[1] % 256; // 準備第二段流量修正值的低8位
up[DATA_START_ID + 5] = gnLeakAreaMax[1] / 256; // 準備第二段流量修正值的高8位
up[DATA_START_ID + 6] = gnLeakAreaCoef[1] % 256; // 準備第二段流量修正系數的低8位
up[DATA_START_ID + 7] = gnLeakAreaCoef[1] / 256; // 準備第二段流量修正系數的高8位
up[DATA_START_ID + 8] = gnLeakAreaMax[2] % 256; // 準備第三段流量修正值的低8位
up[DATA_START_ID + 9] = gnLeakAreaMax[2] / 256; // 準備第三段流量修正值的高8位
up[DATA_START_ID + 10]= gnLeakAreaCoef[2] % 256; // 準備第三段流量修正系數的低8位
up[DATA_START_ID + 11]= gnLeakAreaCoef[2] / 256; // 準備第三段流量修正系數的高8位
up[DATA_START_ID + 12]= gnLeakAreaMax[3] % 256; // 準備第四段流量修正值的低8位
up[DATA_START_ID + 13]= gnLeakAreaMax[3] / 256; // 準備第四段流量修正值的高8位
up[DATA_START_ID + 14]= gnLeakAreaCoef[3] % 256; // 準備第四段流量修正系數的低8位
up[DATA_START_ID + 15]= gnLeakAreaCoef[3] / 256; // 準備第四段流量修正系數的高8位
up[LENGTH_ID] = 16; // 準備緩沖區長度
break;
case USB_CMD_GET_COEF_1: /* 返回第一段流量修正值及其系數 */
up[DATA_START_ID + 0] = gnLeakAreaMax[0] % 256; // 準備第一段流量修正值的低8位
up[DATA_START_ID + 1] = gnLeakAreaMax[0] / 256; // 準備第一段流量修正值的高8位
up[DATA_START_ID + 2] = gnLeakAreaCoef[0] % 256; // 準備第一段流量修正系數的低8位
up[DATA_START_ID + 3] = gnLeakAreaCoef[0] / 256; // 準備第一段流量修正系數的高8位
up[LENGTH_ID] = 4; // 準備緩沖區長度
break;
case USB_CMD_GET_COEF_2: /* 返回第二段流量修正值及其系數 */
up[DATA_START_ID + 0] = gnLeakAreaMax[1] % 256; // 準備第二段流量修正值的低8位
up[DATA_START_ID + 1] = gnLeakAreaMax[1] / 256; // 準備第二段流量修正值的高8位
up[DATA_START_ID + 2] = gnLeakAreaCoef[1] % 256; // 準備第二段流量修正系數的低8位
up[DATA_START_ID + 3] = gnLeakAreaCoef[1] / 256; // 準備第二段流量修正系數的高8位
up[LENGTH_ID] = 4; // 準備緩沖區長度
break;
case USB_CMD_GET_COEF_3: /* 返回第三段流量修正值及其系數 */
up[DATA_START_ID + 0] = gnLeakAreaMax[2] % 256; // 準備第三段流量修正值的低8位
up[DATA_START_ID + 1] = gnLeakAreaMax[2] / 256; // 準備第三段流量修正值的高8位
up[DATA_START_ID + 2] = gnLeakAreaCoef[2] % 256; // 準備第三段流量修正系數的低8位
up[DATA_START_ID + 3] = gnLeakAreaCoef[2] / 256; // 準備第三段流量修正系數的高8位
up[LENGTH_ID] = 4; // 準備緩沖區長度
break;
case USB_CMD_GET_COEF_4: /* 返回第四段流量修正值及其系數 */
up[DATA_START_ID + 0] = gnLeakAreaMax[3] % 256; // 準備第四段流量修正值的低8位
up[DATA_START_ID + 1] = gnLeakAreaMax[3] / 256; // 準備第四段流量修正值的高8位
up[DATA_START_ID + 2] = gnLeakAreaCoef[3] % 256; // 準備第四段流量修正系數的低8位
up[DATA_START_ID + 3] = gnLeakAreaCoef[3] / 256; // 準備第四段流量修正系數的高8位
up[LENGTH_ID] = 4; // 準備緩沖區長度
break;
default: /* 命令不支持 */
up[LENGTH_ID] = 0;
up[STATUS_ID] = ERR_UNSUPPORT;
break;
}
/* 向USB端點2的發送緩沖區寫入數據塊 */
CH375_WR_CMD_PORT((INT8U)CMD_WR_USB_DATA7);
cnt = 3 + up[LENGTH_ID];
CH375_WR_DAT_PORT(cnt); // 首先寫入后續數據長度
id = 0;
do
{
CH375_WR_DAT_PORT(up[id]); // 寫入數據到CH375
id++;
} while (--cnt);
}
else /* 寫操作命令,不返回數據 */
{
switch (down[COMMAND_ID])
{
case USB_CMD_SET_ALL_PARAMS: // 修改所有參數的值(不包含流量修正系數)
break;
case USB_CMD_SET_PRESS_SET: // 修改參數設定壓力
break;
case USB_CMD_SET_PRESS_MAX: // 修改參數壓力上限
break;
case USB_CMD_SET_PRESS_MIN: // 修改參數壓力下限
break;
case USB_CMD_SET_LEAK_MAX: // 修改參數流量上限
break;
case USB_CMD_SET_FILL_TIME: // 修改參數充氣時間
break;
case USB_CMD_SET_TEST_TIME: // 修改參數測試時間
break;
case USB_CMD_SET_ALL_COEFS: // 修改所有流量修正值及其系數
break;
case USB_CMD_SET_COEF_1: /* 修改第一段流量修正值及其系數 */
break;
case USB_CMD_SET_COEF_2: /* 修改第二段流量修正值及其系數 */
break;
case USB_CMD_SET_COEF_3: /* 修改第三段流量修正值及其系數 */
break;
case USB_CMD_SET_COEF_4: /* 修改第四段流量修正值及其系數 */
break;
default: /* 命令不支持 */
up[LENGTH_ID] = 0;
up[STATUS_ID] = ERR_UNSUPPORT;
break;
}
}
}
else if (IntStatus == USB_INT_EP2_IN) /* 批量數據發送成功,狀態包已發送 */
CH375_WR_CMD_PORT((INT8U)CMD_UNLOCK_USB); // 釋放當前USB緩沖區,收到上傳成功中斷后,必須解鎖USB緩沖區,以便繼續收發
else if (IntStatus == USB_INT_EP1_IN) /* 中斷數據發送成功,本程序未用到 */
CH375_WR_CMD_PORT((INT8U)CMD_UNLOCK_USB); // 釋放當前USB緩沖區
/* 內置固件的USB方式下不應該出現其它中斷狀態 */
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -