?? 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 + -