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

📄 ch372drv.c

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