方法很多,你可以通过仿真器,可以通过串口输出。等等。根据你自己的硬件选择。
//#pragma NOAREGS //禁止编译器使用绝对寄存器寻址,一定要加上 #include #include #include #include "CH375INC.H" #define uchar unsigned char #define uint unsigned int
typedef struct _COMMAND_PACKET { /* 自定义的命令包结构 */ uchar mCommandCode; /* 命令请求码,见下面的定义 */ uchar mCommandCodeNot; /* 命令码的反码,用于校验命令包 */ union { uchar mParameter[5]; /* 参数 */ struct { uchar mBufferID; /* 缓冲区识别码,本程序针对MCS51单片机定义: 1-专用功能寄存器SFR, 2-内部RAM, 3-外部RAM, */ uint mBufferAddr; /* 读写操作的起始地址,寻址范围是0000H-0FFFFH,低字节在前 */ uint mLength; /* 数据块总长度,低字节在前 */ } buf; } u; } mCOMMAND_PACKET, *mpCOMMAND_PACKET;
#define CONST_CMD_LEN 0x07 /* 命令块的长度 */ /* 由于命令与数据都是通过数据下传管道(USB端点2的OUT)下传, 为了防止两者混淆, 我们可以在计算机应用程序与单片机程序之间约定, 命令块的长度总是7, 而数据块的长度肯定不是7, 例如64,32等 另外, 可以约定, 命令块的首字节是命令码, 等等 本程序约定命令码: 80H-0FFH是通用命令,适用于各种应用 00H-7FH是专用命令,针对各种应用特别定义 */ /* 通用命令 */ #define DEF_CMD_GET_INFORM 0x90 /* 获取下位机的说明信息,长度不超过64个字符,字符串以00H结束 */ #define DEF_CMD_TEST_DATA 0x91 /* 测试命令,下位机将PC机发来的命令包的所有数据取反后返回 */ #define DEF_CMD_CLEAR_UP 0xA0 /* 在上传数据块之前进行同步,实际是让下位机清除上传缓冲区的已有内容 */ #define DEF_CMD_UP_DATA 0xA1 /* 从下位机的指定地址的缓冲区中读取数据块(上传数据块) */ #define DEF_CMD_DOWN_DATA 0xA2 /* 向下位机的指定地址的缓冲区中写入数据块(下传数据块) */ /* 对于MCS51单片机在使用通用命令时,还需要指定缓冲区识别码 */ #define ACCESS_MCS51_SFR 1 /* 读写51单片机的SFR */ #define ACCESS_MCS51_IRAM 2 /* 读写51单片机的内部RAM */ #define ACCESS_MCS51_XRAM 3 /* 读写51单片机的外部RAM */
uchar volatile xdata CH375_CMD_PORT _at_ 0x0001; /* CH375命令端口的I/O地址 */ uchar volatile xdata CH375_DAT_PORT _at_ 0x0000; /* CH375数据端口的I/O地址 */
#define DELAY_START_VALUE 1 /* 根据单片机的时钟选择初值,20MHz以下为0,30MHz以上为2 */ #define TEST_CH375_FIRST #define MY_USB_VENDOR_ID 0x4348 #define MY_USB_DEVICE_ID 0x5537
//sbit LCD_SCLK = P2^5; //sbit LCD_SID = P1^1; //sbit LCD_CS = P2^6;
sbit IO_SUO = P3^5; sbit Switch_MOVX = P2^0; sfr Add17 = 0xA5; //P4.3地址线17位 0:& 0xf7 1: | 0x08 sfr Add16 = 0xA5; //P4.2地址线16位 0:& 0xfb 1: | 0x04
sfr DaDog = 0xa5;
#define IO_LOCK() { IO_SUO = 0;} #define IO_UNLOCK() { IO_SUO = 1;} #define Switch_MOVX_H() { Switch_MOVX = 1; } #define Switch_MOVX_L() { Switch_MOVX = 0; }
//sbit p1_0=P1^0; //硬件错误指示 //sbit p1_1=P1^1; //接收数据正确指示 //sbit p1_2=P1^2; //发送完成指示
/*+++++++++++++*延时2us*++++++++++++++*/ void delay2us() { uint i; _nop_(); //for (i=DELAY_START_VALUE; i!=0; i--); /* 根据单片机的时钟选择初值 */ _nop_(); } /*写命令函数*/ void CH375_WR_CMD_PORT(uchar cmd) { delay2us(); CH375_CMD_PORT=cmd; delay2us(); }
/*写数据函数*/ void CH375_WR_DAT_PORT(uchar dat) { CH375_DAT_PORT=dat; }
/*读数据函数*/ uchar CH375_RD_DAT_PORT(void) { return(CH375_DAT_PORT); } /*+++++++++++++++++++延时50ms+++++++++++++++*/ void Delay50ms() { uint i, j; for (i=200; i!=0; i--) for (j=250; j!=0; j--); }
/*ch375初始化*/ void CH375_Init(void) { uchar i;
#ifdef TEST_CH375_FIRST /*测试CH375是否正常工作 */ CH375_WR_CMD_PORT(CMD_CHECK_EXIST); CH375_WR_DAT_PORT(0x55); /* 写入测试数据 */ if (CH375_RD_DAT_PORT() != 0xaa) /* CH375不正常 */ {for (i=80; i!=0; i--) {CH375_WR_CMD_PORT(CMD_RESET_ALL); /* 多次重复发命令,执行硬件复位 */ CH375_RD_DAT_PORT(); } CH375_WR_CMD_PORT(0); Delay50ms(); /* 延时50ms */ } #endif
#ifdif MY_USB_VENDOR_ID #ifdif MY_USB_DEVICE_ID /* 设置外部自定义的USB设备VID和PID,可选操作,不执行该命令则使用默认的VID和PID */ /*CH375_CMD_PORT = CMD_SET_USB_ID; /* 设置外部自定义的USB设备VID和PID,可选操作 */ //Delay2us( ); /* 如果时钟频率低于16MHz则无需该指令延时 */ CH375_CMD_PORT=(CMD_SET_USB_ID); CH375_DAT_PORT =(uchar)MY_USB_VENDOR_ID; /* 写入厂商ID的低字节 */ CH375_DAT_PORT =(uchar)(MY_USB_VENDOR_ID>>8); /* 写入厂商ID的高字节 */ CH375_DAT_PORT =(uchar)MY_USB_DEVICE_ID; /* 写入设备ID的低字节 */ CH375_DAT_PORT =(uchar)(MY_USB_DEVICE_ID>>8); /* 写入设备ID的高字节 */ Delay2us( ); #endif #endif /* 设置USB工作模式 */ CH375_WR_CMD_PORT(CMD_SET_USB_MODE); //设置USB模式命令 CH375_WR_DAT_PORT(2); /* 方式2即设置为使用内置固件的USB设备方式 */ for (i=20; i!=0; i--) { /* 等待操作成功,通常需要等待10uS-20uS */ if (CH375_RD_DAT_PORT() == CMD_RET_SUCCESS) break; } /*if (i==0) //{ p1_0=0; } // CH375存在硬件错误(调试指示)*/ /* 下述启用中断,假定CH375连接在INT0 */ //IT0 = 0; /* 置外部信号为低电平触发 */ //IE0 = 0; /* 清中断标志 */ EX0 = 1; /* 允许CH375中断 */ } /*加载上传数据*/ void LoadUpData(uchar data *Buf, uchar Len) { uchar i; CH375_CMD_PORT = CMD_WR_USB_DATA7; /* 向USB端点2的发送缓冲区写入数据块 */ CH375_DAT_PORT = Len; /* 首先写入后续数据长度 */ for (i=0; i}
/*ch375的中断服务函数*/ void mCh375Interrupt() interrupt 9 using 1 { uchar InterruptStatus;//中断状态 uchar i, length; uchar data buffer[64]; CH375_WR_CMD_PORT(CMD_GET_STATUS); /* 获取中断状态并取消中断请求 */ InterruptStatus = CH375_RD_DAT_PORT(); /* 获取中断状态 */ switch (InterruptStatus) /* 分析中断状态处理 */ { case USB_INT_EP2_OUT: /* 批量端点下传成功 */ { CH375_WR_CMD_PORT(CMD_RD_USB_DATA); //从当前USB中断的端点缓冲区读取数据块,并释放缓冲区 length = CH375_RD_DAT_PORT(); //首先读取后续数据长度 for (i=0; i { buffer[i] = CH375_RD_DAT_PORT(); //接收数据包 /*if(buffer[i]==TESTDAT) p1_1=0;*/ //数据正确(调试指示) } //测试数据正确性,将接收到的命令包数据取反后返回给PC机 CH375_WR_CMD_PORT(CMD_WR_USB_DATA7); //向USB端点2的发送缓冲区写入数据块 CH375_WR_DAT_PORT(length); //首先写入后续数据长度 for(i=0;i CH375_WR_DAT_PORT(~buffer[i]); //将数据取反后返回 break; } case USB_INT_EP2_IN: //批量数据发送成功 { // p1_2=0;//进入中断,发送数据成功(调试指示) CH375_WR_CMD_PORT(CMD_UNLOCK_USB); /* 释放当前USB缓冲区 */ break; } default: /* 其它中断,未用到,解锁后退出即可 */ { CH375_WR_CMD_PORT(CMD_UNLOCK_USB); /* 释放当前USB缓冲区 */ break; } } }
/*主函数*/ void main() { Delay50ms(); /* 延时等待CH375初始化完成,如果单片机由CH375提供复位信号则不必延时 */ CH375_Init(); /* 初始化CH375 */ EA = 1; /* 允许中断 */ while (1); /* 以下指令开始工作循环,等待PC机命令进行操作 */ } 麻烦帮我看下哪里有错吧
uchar volatile xdata CH375_CMD_PORT _at_ 0x0001; /* CH375命令端口的I/O地址 */ uchar volatile xdata CH375_DAT_PORT _at_ 0x0000; /* CH375数据端口的I/O地址 */
你用的什么MCU是否和MCU自带的XRAM有冲突?这个地址太小了,很有可能是外部RAM的地址,你不能使用
这个我等下问下我师傅吧。这是他程序上的地址,除了这个的话这个程序应该是能用的吗?
纯粹做实验的话,这个程序略复杂了点,下载CH372EVT.ZIP,建议用PUT/TEST下的程序