📄 demo.lst
字号:
C51 COMPILER V7.09 DEMO 06/07/2004 00:25:23 PAGE 1
C51 COMPILER V7.09, COMPILATION OF MODULE DEMO
OBJECT MODULE PLACED IN Demo.OBJ
COMPILER INVOKED BY: C:\Keil\C51\BIN\C51.EXE Demo.c ROM(SMALL) BROWSE DEBUG OBJECTEXTEND TABS(2)
line level source
1 //-------------------------------------------//
2 // ATAPI-CDROM 驱动程序 //
3 // //
4 // 这源码为ATAPI基本驱动程序,main()中只有 //
5 // 几个基本功能,为演示版,存在一些很多BUG //
6 // //
7 // 本程序为共享版本,但不得用于商业性质。 //
8 // //
9 // 不提供任何无偿的技术支持。 //
10 // 使用或转载时请保留些版权信息。 //
11 // 更多升级版本请留意: //
12 // 主页:http://www.cdle.net //
13 // 论坛:http://bbs.cdle.net //
14 // //
15 // 联系方式:pnzwzw@cdle.net //
16 // pnzwzw@163.com //
17 // //
18 //版权所有 http://www.cdle.net 2001-2004 明浩//
19 //-------------------------------------------//
20 #include <at89x51.h>
21
22 #define A0 P0_0
23 #define A1 P0_1
24 #define A2 P0_2
25 #define CS0 P0_3
26 #define CS1 P0_4
27 #define WR P0_5
28 #define RD P0_6
29 #define RST P0_7
30 #define CDCOM P0 //CDROM控制线
31 #define INTRQ P3_7 //INTRQ
32 #define DBM P2 //CDROM数据线高8位
33 #define DBL P1 //CDROM数据线低8位
34
35 //------------------------------------------//
36 // //
37 // P0.0--------------------------------P0.7 //
38 // A0 A1 A2 CS0 CS1 WR RD ACT //
39 // //
40 //------------------------------------------//
41 //用变量设置P0的值,以方便对应于各寄存器的地址值
42 #define REG_Data 0xE0
43 #define REG_Err 0xE1 //Features
44 #define REG_Features 0xE1
45 #define REG_Sector 0xE2
46 #define REG_CyLow 0xE4
47 #define REG_CyHig 0xE5
48 #define REG_DriveHead 0xE6
49 #define REG_Status 0xE7 //Command
50 #define REG_Command 0xE7
51 #define PLAYKey P3_2
52 #define EJECTKey P3_3
53 #define STOPKey P3_5
54 #define NEXTKey P3_4
55 #define PREVIOUSKey P3_6
C51 COMPILER V7.09 DEMO 06/07/2004 00:25:23 PAGE 2
56 #define ERRLED P3_7
57
58 unsigned char code ReadSubP[]={0x42,0x02,0x40,0x01,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x00}; //ReadSub命令
-信息包
59 unsigned char code ReadTOCP[]={0x43,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x00}; //ReadTOC命令
-信息包
60 unsigned char code PlayMSFP[]={0x47,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; //MSF播放命令
-信息包
61 unsigned char data PacketTemp[24]; //信息包暂存RAM,用写数据和读数据的暂存
62
63 unsigned char REGBL=0, REGBM=0; //用于暂存读取寄存器的值
64 unsigned char PacketSize; //用于保存CDROM定义的信息包长度,有12,16
65 unsigned char bdata CDStatusREG; //可位寻址变量保存CDROM的状态寄存器值
66 sbit ERR = CDStatusREG^0; //错误
67 sbit DRQ = CDStatusREG^3; //数据请求
68 sbit DRDY = CDStatusREG^6; //设备就绪
69 sbit BSY = CDStatusREG^7; //忙
70
71 unsigned char bdata CDErr=0; //保存各种错误标识
72 sbit INITERR = CDErr^0; //初始化错误
73 sbit TESTERR = CDErr^1; //CDROM自身诊断错误
74 sbit UKERR = CDErr^2; //未知错误
75 sbit EJECTING = CDErr^3; //弹出
76 sbit CDOK = CDErr^4; //CD就绪
77 sbit PLAYING = CDErr^5;
78 sbit PAUSEING = CDErr^6;
79 sbit STOPING = CDErr^7;
80
81 unsigned char DEV; //选择驱动器时所用的参数
82 unsigned char AudioStatus; //当前的播放状态
83 unsigned char StartTrackNum; //开始曲目
84 unsigned char EndTrackNum; //结束曲目
85 unsigned char CurrentTrackNum; //当前曲目
86 unsigned char CurrentM, CurrentS, CurrentF; //当前MSF值
87 unsigned char StartM, StartS, StartF; //开始的MSF值
88 unsigned char EndM, EndS, EndF; //结束的MSF值
89
90 void dmsec(unsigned int msec);
91 void RedREG(unsigned char REG);
92 void WriREG(unsigned char LSB, unsigned char MSB, unsigned char REG);
93 void SendPacket(unsigned char SkipDRQ);
94 void TestCD(void);
95 void ReadSub(void);
96 void ReadTOC(unsigned char Track);
97 void ResData(unsigned char Count);
98 void ReadStatus(void);
99 void InitCDROM(void);
100 void BSYWait(void);
101 //void INTRQWait(void);
102 void DRQWait(void);
103 void NDRQWait(void);
104 void LoadPacket(unsigned char code *RT);
105 void TestUnitReady(void);
106 void PlayMSF(void);
107 void Eject(unsigned char EJ);
108 void Pause(unsigned char PR);
109 void Next(unsigned char NP);
110 void Stop(void);
111
112 void main(void)
113 {
114 1 InitCDROM();
C51 COMPILER V7.09 DEMO 06/07/2004 00:25:23 PAGE 3
115 1
116 1 do
117 1 {
118 2 if (!PLAYKey) //play or pause 要求CD就绪才响应
119 2 {
120 3 if (CDOK)
121 3 {
122 4 dmsec(20); //延时20ms防抖动
123 4 if (!PLAYKey)
124 4 {
125 5 if (PLAYING) //CD正在播放中的处理
126 5 {
127 6 if (PAUSEING) //继续播放
128 6 {
129 7 Pause(0);
130 7 PAUSEING = 0;
131 7 }
132 6 else //暂停播放
133 6 {
134 7 Pause(1);
135 7 PAUSEING = 1;
136 7 }
137 6 }
138 5 else //CD就绪按play后播放
139 5 {
140 6 ReadTOC(CurrentTrackNum); //读当前TOC
141 6 ReadTOC(0xAA);
142 6 PlayMSF(); //播放
143 6 PLAYING = 1; //标识
144 6 }
145 5 }
146 4 }
147 3 dmsec(2000);
148 3 }
149 2
150 2 if (!STOPKey) //当CD在播放中
151 2 {
152 3 if (PLAYING)
153 3 {
154 4 dmsec(20);
155 4 if (!STOPKey)
156 4 {
157 5 Pause(1); //暂停
158 5 Stop();
159 5 PLAYING = 0;
160 5 PAUSEING = 0;
161 5 }
162 4 }
163 3 dmsec(2000);
164 3 }
165 2
166 2 if (!NEXTKey)
167 2 {
168 3 if (PLAYING)
169 3 {
170 4 dmsec(20);
171 4 if (!NEXTKey)
172 4 {
173 5 Next(1);
174 5 }
175 4 }
176 3 dmsec(2000);
C51 COMPILER V7.09 DEMO 06/07/2004 00:25:23 PAGE 4
177 3 }
178 2
179 2 if (!PREVIOUSKey)
180 2 {
181 3 if (PLAYING)
182 3 {
183 4 dmsec(20);
184 4 if (!PREVIOUSKey)
185 4 {
186 5 Next(0);
187 5 }
188 4 }
189 3 dmsec(2000);
190 3 }
191 2
192 2 if (!EJECTKey)
193 2 {
194 3 dmsec(20);
195 3 if (!EJECTKey)
196 3 {
197 4 if (EJECTING)
198 4 {
199 5 Eject(3); //装载
200 5 EJECTING = 0;
201 5 dmsec(3000);
202 5 InitCDROM();
203 5 }
204 4 else
205 4 {
206 5 Eject(2);
207 5 EJECTING = 1;
208 5 CDOK = 0;
209 5 PAUSEING = 0;
210 5 PLAYING = 0;
211 5 STOPING = 0;
212 5 }
213 4 }
214 3 dmsec(2000);
215 3 }
216 2
217 2 ReadStatus();//读状态
218 2 ERRLED = ~ERR; //ERR指示
219 2 }
220 1 while(1);
221 1 }
222
223 //1ms延时 11.0592MHz /不是太精确
224 void dmsec(unsigned int msec)
225 {
226 1 unsigned int TempCyc;
227 1 while(msec--)
228 1 {
229 2 for(TempCyc=0; TempCyc<125; TempCyc++);
230 2 }
231 1 }
232
233 //写寄存器
234 void WriREG(unsigned char LSB, unsigned char MSB, unsigned char REG)
235 {
236 1 CDCOM = REG; //设要写的REG
237 1 //EA=0;//程序中有中断程序时应先关中断
238 1 CS1 = 1;
C51 COMPILER V7.09 DEMO 06/07/2004 00:25:23 PAGE 5
239 1 DBL = LSB;
240 1 DBM = MSB; //写数据
241 1 WR = 0;
242 1 WR = 1;
243 1 CS1 = 0; //WD,CS1置回
244 1 DBL = 0xFF;
245 1 DBM = 0xFF;
246 1 dmsec(3); //延时
247 1 //EA=1; 在这开中断
248 1 }
249
250 //读寄存器
251 void RedREG(unsigned char REG)
252 {
253 1 CDCOM = REG; //设要读的寄存器
254 1 //EA=0;//程序中有中断程序时应先关中断
255 1 CS1 = 1;
256 1 RD = 0; //开始读数据线
257 1 REGBL = DBL; //从数据线上读状态寄存器值
258 1 REGBM = DBM;
259 1 RD = 1;
260 1 CS1 = 0; //RD,CS1置回
261 1 dmsec(3); //延时
262 1 //EA=1; 在这开中断
263 1 }
264
265 //Count向CDROM发送信息包的大小
266 void SendPacket(unsigned char SkipDRQ)
267 {
268 1 unsigned char TempCyc;
269 1
270 1 if (!SkipDRQ)
271 1 NDRQWait();
272 1 WriREG(PacketSize, 0xFF, REG_CyLow); //设CyLow,CyHig的值不应小于传输的数量否则PacketCommand时ERR出错
273 1 WriREG(0x00, 0xFF, REG_CyHig); //
274 1 WriREG(DEV, 0xFF, REG_DriveHead); //选择Device 0
275 1 WriREG(0xA0,0xFF,REG_Command); //发送A0H,Packet命令,准备发送Packet
276 1 DRQWait(); //注:有些命令可能返回没有就绪的错误,这里没做考虑
277 1 for (TempCyc=0; TempCyc<PacketSize; TempCyc++)
278 1 {
279 2 CDCOM = REG_Data; //设控制IO,CS0-1=0,A0-2=0,WR-RD=1,RST=1
280 2 //EA=0;//程序中有中断程序时应先关中断
281 2 CS1 = 1; //这时CS1=1,CS0=0,A0-2=0,为选择数据寄存器Data Register
282 2 DBL = PacketTemp[TempCyc*2];
283 2 DBM = PacketTemp[TempCyc*2+1]; //写信息包数据
284 2 WR = 0;
285 2 WR = 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -