⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch372drv.c

📁 一个采用C8051F020+CH372实现的带USB功能的流量测控系统
💻 C
📖 第 1 页 / 共 2 页
字号:
  {
    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 + -