📄 ch375451.lst
字号:
C51 COMPILER V7.06 CH375451 02/21/2008 17:32:43 PAGE 1
C51 COMPILER V7.06, COMPILATION OF MODULE CH375451
OBJECT MODULE PLACED IN CH375451.OBJ
COMPILER INVOKED BY: C:\Keil\C51\BIN\C51.EXE CH375451.C BROWSE DEBUG OBJECTEXTEND
stmt level source
1 /*; CH375/CH372/CH451 EVT
2 ; U2(AT89C51) Program
3 ;
4 ; Website: http://winchiphead.com
5 ; Email: tech@winchiphead.com
6 ; Author: W.ch 2003.12
7 ;
8 ;****************************************************************************
9 */
10
11 /* MCS-51单片机C语言的示例程序 */
12
13 #include <reg52.h>
14 #include <string.h>
15 #include "CH375INC.H"
16
17 typedef struct _COMMAND_PACKET { /* 自定义的命令包结构 */
18 unsigned char mCommandCode; /* 命令请求码,见下面的定义 */
19 unsigned char mCommandCodeNot; /* 命令码的反码,用于校验命令包 */
20 union {
21 unsigned char mParameter[5]; /* 参数 */
22 struct {
23 unsigned char mBufferID; /* 缓冲区识别码,本程序针对MCS51单片机定义: 1-专用功能寄存器SFR, 2-内部RAM, 3-
-外部RAM, 不过本程序实际只演示内部RAM */
24 unsigned int mBufferAddr; /* 读写操作的起始地址,寻址范围是0000H-0FFFFH,低字节在前 */
25 unsigned int mLength; /* 数据块总长度,低字节在前 */
26 } buf;
27 } u;
28 } mCOMMAND_PACKET, *mpCOMMAND_PACKET;
29
30 #define CONST_CMD_LEN 0x07 /* 命令块的长度 */
31 /* 由于命令与数据都是通过数据下传管道(USB端点2的OUT)下传, 为了防止两者混淆,
32 我们可以在计算机应用程序与单片机程序之间约定, 命令块的长度总是7, 而数据块的长度肯定不是7, 例如64,32等
33 另外, 可以约定, 命令块的首字节是命令码, 等等
34 本程序约定命令码: 80H-0FFH是通用命令,适用于各种应用
35 00H-7FH是专用命令,针对各种应用特别定义 */
36 /* 通用命令 */
37 #define DEF_CMD_GET_INFORM 0x90 /* 获取下位机的说明信息,长度不超过64个字符,字符串以00H结束 */
38 #define DEF_CMD_TEST_DATA 0x91 /* 测试命令,下位机将PC机发来的命令包的所有数据取反后返回 */
39 #define DEF_CMD_CLEAR_UP 0xA0 /* 在上传数据块之前进行同步,实际是让下位机清除上传缓冲区的已有内容 */
40 #define DEF_CMD_UP_DATA 0xA1 /* 从下位机的指定地址的缓冲区中读取数据块(上传数据块) */
41 #define DEF_CMD_DOWN_DATA 0xA2 /* 向下位机的指定地址的缓冲区中写入数据块(下传数据块) */
42 /* 专用命令 */
43 #define DEMO_CH451_CMD 0x56 /* PC发送命令给CH451,用于演示CH451的功能 */
44 /* 对于MCS51单片机在使用通用命令时,还需要指定缓冲区识别码 */
45 #define ACCESS_MCS51_SFR 1 /* 读写51单片机的SFR */
46 #define ACCESS_MCS51_IRAM 2 /* 读写51单片机的内部RAM */
47 #define ACCESS_MCS51_XRAM 3 /* 读写51单片机的外部RAM */
48
49 unsigned char volatile xdata CH375_CMD_PORT _at_ 0xBDF1; /* CH375命令端口的I/O地址 */
50 unsigned char volatile xdata CH375_DAT_PORT _at_ 0xBCF0; /* CH375数据端口的I/O地址 */
51
52 /* 有关CH451的定义,演示板的连接方式 */
53 sbit CH451_dclk=P1^7; /* 串行数据时钟上升延激活 */
54 sbit CH451_din=P1^6; /* 串行数据输出,接CH451的数据输入 */
C51 COMPILER V7.06 CH375451 02/21/2008 17:32:43 PAGE 2
55 sbit CH451_load=P1^5; /* 串行命令加载,上升延激活 */
56 sbit CH451_dout=P3^3; /* INT1,键盘中断和键值数据输入,接CH451的数据输出 */
57 unsigned char CH451_KEY; /* 存放键盘中断中读取的键值 */
58 unsigned char LAST_KEY; /* 保存上次的键值 */
59
60 mCOMMAND_PACKET CMD_PKT; /* 命令包结构缓冲区 */
61 unsigned char data *CurrentRamAddr; /* 进行数据块传输时保存被读写的缓冲区的起始地址 */
62 unsigned char CurrentRamLen; /* 进行数据块传输时保存剩余长度 */
63 bit FLAG_INT_WAIT; /* 中断等待标志,1指示有中断数据正在CH375中等待发送 */
64 unsigned char CH451_CMD_H; /* PC机发给CH451的高4位命令,为0FFH则命令无效 */
65 unsigned char CH451_CMD_L; /* PC机发给CH451的低8位命令 */
66 unsigned char code InformString[16] = "CH375/CH451\x0"; /* 信息字符串 */
67
68 /* 延时2微秒,不精确 */
69 void Delay2us( )
70 {
71 1 unsigned char i;
72 1 #define DELAY_START_VALUE 1 /* 根据单片机的时钟选择初值,20MHz以下为0,30MHz以上为2 */
73 1 for ( i=DELAY_START_VALUE; i!=0; i-- );
74 1 }
75
76 /* 延时50毫秒,不精确 */
77 void Delay50ms( )
78 {
79 1 unsigned char i, j;
80 1 for ( i=200; i!=0; i-- ) for ( j=250; j!=0; j-- );
81 1 }
82
83 /* 将PC机的低字节在前的16位字数据转换为C51的高字节在前的数据 */
84 unsigned int BIG_ENDIAN( unsigned int value )
85 {
86 1 unsigned int in, out;
87 1 in = value;
88 1 ((unsigned char *)&out)[1] = ((unsigned char *)&in)[0];
89 1 ((unsigned char *)&out)[0] = ((unsigned char *)&in)[1];
90 1 return( out );
91 1 }
92
93 /* CH375初始化子程序 */
94 void CH375_Init( )
95 {
96 1 unsigned char i;
97 1 FLAG_INT_WAIT = 0; /* 清发送中断等待标志 */
98 1 /* 测试CH375是否正常工作,可选操作,通常不需要 */
99 1 #ifdef TEST_CH375_FIRST
CH375_CMD_PORT = CMD_CHECK_EXIST; /* 测试CH375是否正常工作 */
Delay2us( ); /* 如果时钟频率低于16MHz则无需该指令延时 */
CH375_DAT_PORT = 0x55; /* 写入测试数据 */
Delay2us( );
i = ~ 0x55; /* 返回数据应该是测试数据取反 */
if ( CH375_DAT_PORT != i ) { /* CH375不正常 */
for ( i=80; i!=0; i-- ) {
CH375_CMD_PORT = CMD_RESET_ALL; /* 多次重复发命令,执行硬件复位 */
Delay2us( );
}
CH375_CMD_PORT = 0;
Delay50ms( ); /* 延时50ms */
}
#endif
114 1 #ifdef USE_MY_USB_ID
/* 设置外部自定义的USB设备VID和PID,可选操作,不执行该命令则使用默认的VID和PID */
CH375_CMD_PORT = CMD_SET_USB_ID; /* 设置外部自定义的USB设备VID和PID,可选操作 */
C51 COMPILER V7.06 CH375451 02/21/2008 17:32:43 PAGE 3
Delay2us( ); /* 如果时钟频率低于16MHz则无需该指令延时 */
CH375_DAT_PORT = (unsigned char)MY_USB_VENDOR_ID; /* 写入厂商ID的低字节 */
CH375_DAT_PORT = (unsigned char)(MY_USB_VENDOR_ID>>8); /* 写入厂商ID的高字节 */
CH375_DAT_PORT = (unsigned char)MY_USB_DEVICE_ID; /* 写入设备ID的低字节 */
CH375_DAT_PORT = (unsigned char)(MY_USB_DEVICE_ID>>8); /* 写入设备ID的高字节 */
Delay2us( );
#endif
124 1 /* 设置USB工作模式, 必要操作 */
125 1 CH375_CMD_PORT = CMD_SET_USB_MODE;
126 1 Delay2us( ); /* 如果时钟频率低于16MHz则无需该指令延时 */
127 1 CH375_DAT_PORT = 2; /* 设置为使用内置固件的USB设备方式 */
128 1 for ( i=100; i!=0; i-- ) { /* 等待操作成功,通常需要等待10uS-20uS */
129 2 if ( CH375_DAT_PORT==CMD_RET_SUCCESS ) break;
130 2 }
131 1 /* if ( i==0 ) { CH372/CH375存在硬件错误 }; */
132 1 /* 下述启用中断,假定CH375连接在INT0 */
133 1 IT0 = 0; /* 置外部信号为低电平触发 */
134 1 IE0 = 0; /* 清中断标志 */
135 1 EX0 = 1; /* 允许CH375中断 */
136 1 }
137
138 /* 加载上传数据 */
139 void LoadUpData( unsigned char data *Buf, unsigned char Len )
140 {
141 1 unsigned char i;
142 1 CH375_CMD_PORT = CMD_WR_USB_DATA7; /* 向USB端点2的发送缓冲区写入数据块 */
143 1 Delay2us( ); /* 如果时钟频率低于16MHz则无需该指令延时 */
144 1 CH375_DAT_PORT = Len; /* 首先写入后续数据长度 */
145 1 for ( i=0; i<Len; i++ ) CH375_DAT_PORT = Buf[i]; /* 加载数据 */
146 1 }
147
148 /* CH375中断服务程序INT0,使用寄存器组1 */
149 void mCH375Interrupt( ) interrupt 0 using 1
150 {
151 1 unsigned char InterruptStatus;
152 1 unsigned char length, c1, len1, len2, i;
153 1 #define cmd_buf ((unsigned char data *)(&CMD_PKT))
154 1 CH375_CMD_PORT = CMD_GET_STATUS; /* 获取中断状态并取消中断请求 */
155 1 Delay2us( ); /* 如果时钟频率低于16MHz则无需该指令延时 */
156 1 InterruptStatus = CH375_DAT_PORT; /* 获取中断状态 */
157 1 IE0 = 0; /* 清中断标志,对应于INT0中断 */
158 1 if ( InterruptStatus == USB_INT_EP2_OUT ) { /* 批量端点下传成功 */
159 2 CH375_CMD_PORT = CMD_RD_USB_DATA; /* 从当前USB中断的端点缓冲区读取数据块,并释放缓冲区 */
160 2 Delay2us( ); /* 如果时钟频率低于16MHz则无需该指令延时 */
161 2 length = CH375_DAT_PORT; /* 首先读取后续数据长度 */
162 2 if ( length == CONST_CMD_LEN ) { /* 命令块长度总是CONST_CMD_LEN,分析并处理命令 */
163 3 /* 分析通过USB接收到的命令块,长度总是CONST_CMD_LEN,首字节为命令,其余为可选的参数,这种命令结构是由单片机和
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -