⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cd_rom.c~

📁 AVR单片机控制实现播放CD音频数据
💻 C~
📖 第 1 页 / 共 2 页
字号:

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