📄 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 + -