📄 cd_rom.c~
字号:
#include <mega16.h>
#include <delay.h>
//#include <i2c.h>
#define A0 PORTA.5
#define A1 PORTA.4
#define A2 PORTA.3 //
#define CS0 PORTB.0
#define CS1 PORTA.2
#define WR PORTA.7
#define RD PORTA.6
#define RST PORTB.4
#define A0D DDRA.5
#define A1D DDRA.4
#define A2D DDRA.3
#define CS0D DDRB.0
#define CS1D DDRA.2
#define WRD DDRA.7
#define RDD DDRA.6
#define RSTD DDRB.4
#define SCL PORTB.2
#define SDA PORTB.3
#define SCLD DDRB.2
#define SDAD DDRB.3
#define Power PINB.7
#define Uchar unsigned char
#define Uint unsigned int
#define Ulong unsigned long
//unsigned char keystatus;
//unsigned char TemREG;
sfrb ADCSRA=6;
#define ADPS0 0x01
#define ADPS1 0x02
#define ADPS2 0X04
#define ADIE 0X08 //ADC_Int_EN
#define ADIF 0X10 //Int_Flag
#define ADATE 0X20 //AUTO Conversion
#define ADSC 0X40 //ADC STSRT
#define ADEN 0X80
#define ADC0 0X00
#define DIV_8 0X03 //ADPS0ADPS1ADPS2=011
#define AREF_AVCC 0X40 //Avcc REFS1&0=01 note:(REFS1&0=11 save)
#define CLK_IO_64 0X03 //Come form divider
#define TOIE0 0x01 //T0 overflow EN
#define TOV0 0x01 //TO overflow Flag
#define OCF0 0x02 //TO compare Flag
#define TOV1 0X04 //T1 overflow Flag
#define OCF1B 0X08 //T1 compare B Flag
#define OCF1A 0X10 //T1 compare A Flag
#define ICF1 0X20 //T1 Catch Flag
#define TOV2 0X40 //T2 overflow Flag
#define OCF2 0X80 //T2 compare Flag
#define ON 0
//#define SCL PORTB.2
//#define SDA PORTB.3
#define INTRQ PORTB.5//INTRQ
//------------------------------------------//
////
// P0.0--------------------------------P0.7 //
// A0 A1 A2 CS0 CS1 WR RD ACT //
///
//------------------------------------------//
//用变量设置P0的值,以方便对应于各寄存器的地址值
#define REG_Data 0x00
#define REG_Err 0x01 //Features
//#define REG_Features 0xFA
#define REG_Sector 0x03
#define REG_CyLow 0x04
#define REG_CyHig 0x05
#define REG_DriveHead 0x06
#define REG_Status 0x07 //Command
#define REG_Command 0x07
unsigned char CurrentAudio=0x03;
unsigned char ack;
unsigned char const *p1[]={0x42,0x02,0x40,0x01,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x00}; //ReadSub命令信息包
unsigned char const *p2[]={0x43,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x00}; //ReadTOC命令信息包
unsigned char const *p3[]={0x47,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00}; //MSF播放命令信息包
unsigned char Size;
unsigned char PacketTemp[24]; //信息包暂存RAM,用写数据和读数据的暂存
unsigned char REGBL=0, REGBM=0; //用于暂存读取寄存器的值
unsigned char PacketSize; //用于保存CDROM定义的信息包长度,有12,16
unsigned char CDStatusREG; //可位寻址变量保存CDROM的状态寄存器值可位寻址变量保存CDROM的状态寄存器?
//unsigned char CDErr=0; //保存各种错误标识
unsigned char DEV; //选择驱动器时所用的参数
unsigned char AudioStatus; //当前的播放状态
unsigned char StartTrackNum; //开始曲目
unsigned char EndTrackNum; //结束曲目
unsigned char CurrentTrackNum=0x01; //当前曲目
unsigned char CurrentM, CurrentS, CurrentF; //当前MSF值
unsigned char StartM, StartS, StartF; //开始的MSF值
unsigned char EndM, EndS, EndF; //结束的MSF值
bit UKERR;
bit BSY;
bit DRQ;
bit PLAYKey=0;
bit PLAYING=0;
bit PAUSEING=0;
bit STOPKey=0;
bit NEXTKey=0;
bit PREVIOUSKey=0;
bit STOPING=1;
bit PCStatus=0;
void adc_key_scan(void);
void RedREG(unsigned char REG);
void WriREG(unsigned char LSB, unsigned char MSB, unsigned char REG);
void SendPacket(unsigned char SkipDRQ);
//void TestCD(void);
void ReadSub(void);
void DeviceD(void);
void i2cstart(void);
void i2cwrite(unsigned char shu);
void i2cstop(void);
//void Eject(unsigned char EJ);
//void other1(void);
//void other2(void);
void ReadTOC(unsigned char Track);
void WrAudioReg(unsigned char volume);
void ResData(unsigned char Count);
void AudioAdd(unsigned char AdSb);
void ReadStatus(void);
void PlayMSF(void);
void BSYWait(void);
//void WatchDogEn(void);
//void WatchDogOff((void);
//void AudioVolume(unsigned char volume);
void PCC(void);
void PBCheck(void);
//void ModeSlet(unsigned char SkipDRQ,unsigned char ncount);
//void INTRQWait(void);
//void Eject(unsigned char EJ);
void DRQWait(void);
void NDRQWait(void);
void GetBack(void);
//void ModesectL(unsigned int *RT);
void LoadPacket(unsigned int *RT);
void TestUnitReady(void);
void InitIO(void);
unsigned char DataC(unsigned char Dta);
void Pause(unsigned char PR);
void Stop(void);
//void WatchDogClr(void);
void Next(unsigned char NP);
void main(void)
{ // WatchDogEn();
do
{
adc_key_scan();
DeviceD();
PBCheck();
//WatchDogClr();
if (PLAYKey&!PCStatus)
{
if(!STOPING)
{
if (PAUSEING) //继续播放
{
delay_ms(100);
Pause(0);
PAUSEING = 0;
PLAYKey=0;
}
else //暂停播放
{
delay_ms(100);
Pause(1);
PAUSEING = 1;
PLAYKey=0;
}
}
else
{
InitIO();
TestUnitReady();
ReadTOC(0x01); //读当前TOC
ReadTOC(0xAA);
PlayMSF(); //播放
PLAYING = 1; //标识
PLAYKey=0;
STOPING=0;
//OpenVolume();
WrAudioReg(CurrentAudio);
}
}
if (STOPKey&!PCStatus) //当CD在播放中
{
if (PLAYING)
{
Pause(1); //暂停
Stop();
PLAYING=0;
PAUSEING=0;
STOPKey=0;
STOPING=1;
}
}
if (NEXTKey&!PCStatus)
{
if (PLAYING)
{
Next(1);
PAUSEING=0;
NEXTKey=0;
}
}
if (PREVIOUSKey&!PCStatus)
{
if (PLAYING)
{
Next(0);
PREVIOUSKey=0;
PAUSEING=0;
}
}
}
while(1);
}
void PCC(void){
DDRA.1=1;
PORTA.1=0;
DDRB=0;
PORTB=0;
delay_ms(500);
PREVIOUSKey=0;
NEXTKey=0;
STOPKey=0;
PLAYKey=0;
}
void WriREG(unsigned char LSB, unsigned char MSB, unsigned char REG){
A0=(REG>>0)&0X01;
A1=(REG>>1)&0X01;
A2=(REG>>2)&0X01;
DDRC=0XFF;
DDRD=0XFF;
PORTC=DataC(LSB);
PORTD=MSB;
CS0=0;
WRD=1;
WR=0;
delay_us(3);
WR=1;
CS0=1;
delay_us(10);
}
void RedREG(unsigned char REG){
A0=(REG>>0)&0X01;
A1=(REG>>1)&0X01;
A2=(REG>>2)&0X01;
PORTC=0XFF;
PORTD=0XFF;
DDRC=0;
DDRD=0;
CS0=0;
RDD=1;
RD=0;
delay_us(3);
REGBL=PINC;
REGBM=PIND;
RD=1;
CS0=1;
REGBL=DataC(REGBL);
delay_us(10);
}
void Pause(unsigned char PR)
{
LoadPacket(p3); //暂存数据到RAM
PacketTemp[0] = 0x4B; //PAUSE/RESUME Command
PacketTemp[8] = ~PR; //PR为1时暂停
SendPacket(0); //向CDROM送信息包
}
void Stop(void)
{
LoadPacket(p3); //暂存数据到RAM
PacketTemp[0] = 0x4E; //STOP/SCAN Command
SendPacket(0); //向CDROM送信息包
}
void Next(unsigned char NP)
{
ReadSub(); //读当前曲目
if (NP) //计算
NP = CurrentTrackNum + 1;
else
NP = CurrentTrackNum - 1;
if (NP < StartTrackNum)
NP = StartTrackNum;
if (NP > EndTrackNum)
NP = EndTrackNum;
ReadTOC(NP); //读下一首或前一首的TOC
PlayMSF(); //播放
}
void SendPacket(unsigned char SkipDRQ){
unsigned char TempCyc;
unsigned char dl;
if (!SkipDRQ)
NDRQWait();
WriREG(PacketSize, 0xFF, REG_CyLow);
WriREG(0x00, 0xFF, REG_CyHig);
WriREG(DEV, 0xFF, REG_DriveHead);
WriREG(0xA0,0xFF,REG_Command);
DRQWait();
A0=0;A1=0;A2=0;
DDRC=0XFF;DDRD=0XFF;
for(TempCyc=0;TempCyc<6;TempCyc++)
{
dl=DataC(PacketTemp[TempCyc*2]);
PORTC=dl;
PORTD=PacketTemp[TempCyc*2+1];
CS0=0;
WR=0;
delay_us(3);
WR=1;
CS0=1;
}
DDRC=0 ;DDRD=0;
}
void ResData(unsigned char Count){ //返回数据,Count为返回数据的多少
unsigned char TempCyc;
DRQWait();
PORTC=0XFF;PORTD=0XFF;
DDRC=0X00;DDRD=0X00;
A0=0;A1=0;A2=0;
for (TempCyc=0; TempCyc<Count;TempCyc++)
{
CS0=0;
RD=0;
delay_us(3);
PacketTemp[TempCyc*2]=PINC;
PacketTemp[TempCyc*2+1]=PIND;
RD=1;
CS0=1;
delay_us(5);
PacketTemp[TempCyc*2]=DataC(PacketTemp[TempCyc*2]);
}
}
void ReadStatus(void){ //读当前CDROM状态
RedREG(REG_Status);//读状态寄存器
CDStatusREG = REGBL; //放入可寻址位方便使用
}
void ReadTOC(unsigned char Track){
LoadPacket(p2); //暂存数据到RAM
PacketTemp[6] = Track; //要读取的轨道,值为0H-63H,写AAH为返回开始区段值
SendPacket(0); //向CDROM送信息包
DRQWait();
ResData(12);//返回数据4字节
StartTrackNum=PacketTemp[2]; //读首曲目数字
EndTrackNum=PacketTemp[3]; //读尾曲目数字
if (Track == 0xAA){
EndM = PacketTemp[9]; //读曲目的MSF值
EndS = PacketTemp[10];
EndF = PacketTemp[11];
}
else{
StartM = PacketTemp[9];
StartS = PacketTemp[10];
StartF = PacketTemp[11];
}
}
void PlayMSF(void){
LoadPacket(p3); //暂存数据到RAM
PacketTemp[3]=StartM; //写MSF值
PacketTemp[4]=StartS;
PacketTemp[5]=StartF;
PacketTemp[6]=EndM;
PacketTemp[7]=EndS;
PacketTemp[8]=EndF;
SendPacket(0); //向CDROM送信息包
}
void ReadSub(void){
LoadPacket(p1); //暂存数据到RAM
SendPacket(0); //向CDROM送信息包
DRQWait();
ResData(12);//返回数据16字节
AudioStatus = PacketTemp[1];
CurrentTrackNum = PacketTemp[6];
CurrentM = PacketTemp[9];
CurrentS = PacketTemp[10];
CurrentF = PacketTemp[11];
} //检查CDROM是否就绪
void TestUnitReady(void){
unsigned char TempCyc;
unsigned char TempS;
for (TempCyc=0; TempCyc<12;TempCyc++)
PacketTemp[TempCyc] = 0x00; //Packet for Test Unit Ready Command
do
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -