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

📄 a1600.asm

📁 凌阳单片机对语音的处理和调用
💻 ASM
📖 第 1 页 / 共 2 页
字号:
W_InterRAM_Ptr:    .DW     0;
DataFlag:	   .DW	   0;


//-----------------------------
//程序调用他时候给的2个值单元地址
.RAM
R_SongIndex:    .DW     0;
R_Volume:       .DW     0;




//.PUBLIC 	F_SACM_DVR1600_SendDAC
//F_SACM_DVR1600_SendDAC: .PROC

.CODE
//.PUBLIC _FSpeech
// _F_Speech: .proc_
.public _InilSpeech
	_InilSpeech: .proc
		//PUSH BP to [sp];
		PUSH R1 ,R4 to [SP] 
        PUSH BP to [SP]
		BP=sp+1;
		R1=[BP+7];
        [R_SongIndex] = R1;	       //歌曲索引为0        
        R1=[BP+8];                //歌曲的音量
        [R_Volume]=R1;
        
        //---IO口设置
 		R1 = [P_IOC_Dir];
 		R1|=0x40;
        [P_IOC_Dir] = R1;           // IOC  OutPut Mode
         
        R1=[P_IOC_Data];
        R1|=0x40;
		[P_IOC_Data]=R1;            //IOC  输出高电压
		 
		//---设置音量(0-15)共16级
		R1=[R_Volume];
        CALL F_SACM_DVR1600_Volume;
        
//?Go_play:	 	 	
        R1 = 0;
        [DataFlag] = R1;           //数据标志为0
        R2 -= R2;            
	    [W_InterRAM_Ptr] = R2;
	     
	     //---取语音索引号
	     R1=[R_SongIndex];
	     
  	     BP =offset T_SACM_A1600_Table;
         BP+ =R1;
         BP=[BP];
         
	     
	     //---For  manual mode,  fill the first 32 Data to HASC_FIFO
          R1 = HASC_FIFO;
          R2 = [BP++];
          R3 = [bp]
          R3 = R3 LSL 4
          R3 = R3 LSL 4
          R3 = R3 LSL 2                         //左移10位
          [SegDataRomAddr] = R3
?_FillHASC_FIFO:
          Sr &= 0x3FF			                //段寄存器  有程序段CS和数据段DS
          SR |= R3
          R4 =DS: [R2];
          R2 +=1
          JNZ		?L_Nover
          R3 +=0x400
          [SegDataRomAddr] = R3                //以上是放音频的基地址
?L_Nover:
	  	 CALL  F_ChangeHighLowByte;           //将R4的高、低位互掉
          [R1++] = R4;         
          CMP R1,HASC_FIFO+32;
          JNZ  ?_FillHASC_FIFO;//以上可能是从新放置音频信息吧?
          [DataRomAddr] = R2;

        
	  R1 = 0xFFFF;				// Voice Index , 0xFFFF means manual mode
	  R2 = 2;				// Volume Index, 0 ~ 3 .
	  call F_SACM_DVR1600_Init;//这个初始化,好象.asm文件中有的
	  
        pop BP from[sp];
        pop r1,r4 from[sp];
    RETF;
.endp


//---------------------------------
//    解码播放语音的主循环程序
//---------------------------------
?_play_loop:  
	 
?_wait_music_end:
		CALL	F_SACM_DVR1600_ServiceLoop;   //03080  执行DVR1600解码或编码操作
		CALL 	F_FillRingBuf;				// For manual mode, users must fill the HASC_DEC_FIFO
		CALL	F_SACM_DVR1600_Status;       //获取当前DVR1600录放音的状态
    	test R1, 0x0001;       			       //Voice end ?
    	JNZ ?_wait_music_end;
    	test R1,0x0002;				       // Voice Pause
        JNZ  ?_wait_music_end;
//        call F_Stop_Play;          		       //Stop playback DVR1600

//----------------------------
//定时器和ADC的设置
//----------------------------
//-----------------------------------------------------
// Set Fosc , TimerA or TimerB , TimerData , P_DAC_Ctrl
//-----------------------------------------------------
//F_SACM_DVR1600_Init_:                    //这个初始化,好象.asm文件中有的
//      // PUSH R1,R5 TO [SP]
//        INT OFF;
//	   R1 = 0x0081;
//        [P_SystemClock] = R1;               //Set High Speed and (/1)
//        R1 = 0x0080;
//        //R1|=[P_SystemClock];
//        [P_SystemClock] = R1;               //Set High Speed and (/1)
//        	
////        R1 = 0x04;
////        [P_IntClr]= R1;
//
//        R1 = 0xD500;                            //Base 32768Hz
//        [P_Tmr_Ctrl] = R1;
//
//        R1 = 0xFFFC;                       // 8.192k
//        [P_TmrA_Data] = R1;                //Set play rate
//        [P_TmrA_Load] = R1;
//
//        R1 = 0x0004;
//        R1|=[P_Int];
//        [P_Int] = R1;                      //Enabel TimerA INT
//
//        R1 = 0x0200;                            //From DACO pin
////        R1|=[P_DtmfTone];
//        [P_DtmfTone] = R1;
//        
//         r1= [0x7022] 
//    r1 |= 0x0300  //OPEN 0x7022(P_DtmfTone_Def)REG  的  DACEN  和 Tone_DACO  两位
//    [0x7022] =r1
//
//		
//		r1= [0x7026]   
//    	r1 |= 0x1   //U_AFECtrl->B.EN_DAC2 =1;
//    	[0x7026] = r1
//		
//        INT IRQ;                                //IRQ ON;
//	POP R1,R5 FROM [SP]	
//	RETF;

F_SACM_DVR1600_Init_:                    //这个初始化,好象.asm文件中有的

        INT OFF;

        R1 = 0x0081;
        R1|=[P_SystemClock];
        [P_SystemClock] = R1;               //Set High Speed and (/1)
        R1=0x80;	
        [P_SystemClock] = R1;               //Set High Speed and (/1)
        	
        R1 = 0x04;
        [P_IntClr]= R1;

        R1 = 0xD500;                            //Base 32768Hz
        [P_Tmr_Ctrl] = R1;

        R1 = 0xFFFC;                       // 8.192k
        [P_TmrA_Data] = R1;                //Set play rate
        [P_TmrA_Load] = R1;

        R1 = 0x0004;
        R1|=[P_Int];
        [P_Int] = R1;                      //Enabel TimerA INT

        R1 = 0x0200;                            //From DACO pin
//        R1|=[P_DtmfTone];
        [P_DtmfTone] = R1;

		R1 = 1
//		R1|=[0x7026];
		[0x7026] = R1
        INT IRQ;                                //IRQ ON;
		
	RETF;	
	


//*************************************************************************************
// Stop MIDI : Clear Flag, Disable TimerA and INT
// 停止播放音乐时,清楚相应的标志位
//*************************************************************************************
.public _T_Stop_Play
        _T_Stop_Play: .proc
        push R1,R5 to [sp];
        R1 = 0x4;
        [P_IntClr] = R1;

        R1 = 0x0000;                            //Disable TimerA
        [P_Tmr_Ctrl] = R1;

        R1 = [P_Int];
        R1 &= 0xFFFF - 0x0004;
        [P_Int] = R1;                           //Disable INT

		r1= [0x7022] 
    	r1 &= 0xfcff  //关闭0x7022(P_DtmfTone_Def)REG  的  DACEN  和 Tone_DACO  两位
    	[0x7022] =r1
    	
    	r1= [0x7026]   
    	r1 &= 0xfffe   //U_AFECtrl->B.EN_DAC2 =0;
    	[0x7026] = r1
    
    	r1= [P_IOC_Data]   
    	r1 &=0xffbf    //话机 通过PD。3关闭功放POS机 PC。6
    	[P_IOC_Data] = r1 
    
		pop R1,R5 from [sp];
	retf
	.endp

// ------------------------------------------------------------------------------------------------------------//
// Purpose: In the manual mode, user must fill the ring buf after each F_SACM_DVR1600_ServiceLoop is over
//	    HascDEC_FIFO_PTR will show the message that the next "Data Pointer"
//	    And user must fill the HascDEC_FIFO according to HascDEC_FIFO_PTR
//	    To make encode data is compatible with SPDC, the ending code is 0xFF,0xFF,0xFF 
// ------------------------------------------------------------------------------------------------------------//
F_FillRingBuf:       

.public _FillRamBuf
	_FillRamBuf: .proc
	push R1,R5 to [sp];
 FillRamBuf1:
	    R1 = [HascDEC_FIFO_PTR];             // Fill Ring-Buf
        R2 = [W_InterRAM_Ptr];          
        CMP  R1,R2;
        JZ   EndFillRingBuf;
        R3 = [DataFlag];
        CMP R3,0xFFFF;
        JZ   EndFillRingBuf;		// Data is over , don't fill memory.
        R3 = [SegDataRomAddr]
        R5 = [DataRomAddr];
        Sr &= 0x3FF			
        SR |= R3
        R4 =DS: [R5];
        R5 +=1
        JNZ		?L_Nover
        R3 +=0x400
        [SegDataRomAddr] = R3       //以上程序应该是获取音频的基地址
?L_Nover:
        [DataRomAddr] = R5;
        CALL	F_ChangeHighLowByte;
        R3 = R2 + HASC_FIFO;        
        R2 += 1;
        R2 &= 0x001F;
        [W_InterRAM_Ptr] = R2;
		CMP  R4,0xFFFF;
		JNZ  NotCheckEndingCode;
		R5 = [DataRomAddr];
		R5 = DS:[R5];			
		CMP R5,0x00FF;
		JNZ  NotCheckEndingCode;
		R4 = 0xFFFF;
		[DataFlag] = R4;		// Ending Code,don't store in the HASC_FIFO
EndFillRingBuf:
       	pop  R1,R5 from [sp];
		retf
		.endp

NotCheckEndingCode:
        [R3] = R4;		 	// Not Ending Code        
        JMP  FillRamBuf1;


//-----------------------------------
//将R4的高、低字节进行交换(16字节的)
//-----------------------------------
// ------------------------------------------------------------------------------------------------------------//
// Purpose: To make encode data is compatible with SPDC.  We must change High-Low Byte 
// Input:   R4
// Output:  R4
// Change:  R4,R5;
// ------------------------------------------------------------------------------------------------------------//
F_ChangeHighLowByte:
		//	PUSH R4,R5 TO [SP]
          R5 = R4 And 0x00FF;
          R5 = R5 LSL 4;
          R5 = R5 LSL 4;
          R4 = R4 LSR 4;
          R4 = R4 LSR 4;
          R4 |= R5;
        // POP R4,R5 FROM [SP]
          RETF;
          
          
//--------------------------
//发送DAC信号的
//--------------------------
////////////////////////////////////////////////////////
// Function: F_SACM_DVR1600_SendDAC
// Description: send data to DAC from library 
// Syntax  : F_SACM_DVR1600_SendDAC
// Destory: R4   
// Input  : R4: 16-bit sign PCM
// Return    :None
////////////////////////////////////////////////////////
.PUBLIC 	F_SACM_DVR1600_SendDAC
F_SACM_DVR1600_SendDAC: .PROC
	push R4 to [sp];
    R4 &=0xFFC0
    CMP  R4,0x8700;
	JG 	?NotUnderFlow;
	R4 = 0x8700;
?NotUnderFlow:
	R4 += 0x7900;     
	   
    [0x7029] = r4
    POP R4 FROM [sp];
    retf;

.ENDP

.public _T_SACM_DVR1600_ServiceLoop
	_T_SACM_DVR1600_ServiceLoop:.proc
		push R1,R5 to [sp];
		CALL F_SACM_DVR1600_ServiceLoop;
		pop  R1,R5 from [sp];
	retf
	.endp
	
.public _T_SACM_DVR1600_Status
	_T_SACM_DVR1600_Status:.proc
		push R1,R5 to [sp];
		CAll F_SACM_DVR1600_Status;
		[_StatusData]=R1;
		pop  R1,R5 from [sp];
	retf
	.endp
	
.public _T_SACM_DVR1600_Volume
	_T_SACM_DVR1600_Volume: .proc           //设定DVR1600的播放音量
    	//push R1, bp to [sp];
    	PUSH R1 to [SP] 
	    push bp to [sp];
    	BP=sp+1;
	//	R1=[BP+3];
		R1=[BP+4];
    	CALL F_SACM_DVR1600_Volume;
    	pop bp from [sp];
	    pop r1 from [sp]
    	//pop R1,bp from [sp];
    retf
    .endp          
    
.public _T_SACM_DVR1600_Pause
	_T_SACM_DVR1600_Pause: .proc
		push R1,R5 to [sp];
		CALL F_SACM_DVR1600_Pause;
		pop R1,R5 from [sp];
	retf
	.endp
	
.public _T_SACM_DVR1600_Resume
	_T_SACM_DVR1600_Resume: .proc
		push R1,R5 to [sp];
		CALL F_SACM_DVR1600_Resume;
		pop R1,R5 from [sp];
	retf
	.endp

//*************************************************************************************
//ISR : TimerA INT  //定时器中断
//*************************************************************************************
.TEXT
_IRQ2:  
	push R1, R5 to [sp];
        R1 = 0x0004;
        [P_IntClr] = R1;
	    CALL	F_SACM_DVR1600_IRQ_ServiceLoop;  //怎么没有看到啊?
	    r1=[_toteldata]
	    r1+=1
	    [_toteldata] = r1
	pop R1, R5 from [sp];
	RETI;	


//---语音信息表
T_SACM_A1600_Table:
//.DW _RES_A13_ENC_SA;
//.DW _RES_A39_ENC_SA;
 // .DW _RES_SHUAKA_1_ENC_SA
.DW _RES_A02_ENC_SA;
.DW _RES_A03_ENC_SA;
.DW _RES_A04_ENC_SA;
.DW _RES_A05_ENC_SA;
.DW _RES_A06_ENC_SA;
.DW _RES_A07_ENC_SA;
.DW _RES_A08_ENC_SA;
.DW _RES_A09_ENC_SA;
//.DW _RES_A10_ENC_SA;
//
//.DW _RES_A11_ENC_SA;
//.DW _RES_A12_ENC_SA;
//.DW _RES_A13_ENC_SA;
//.DW _RES_A14_ENC_SA;
//.DW _RES_A15_ENC_SA;
//.DW _RES_A16_ENC_SA;
//.DW _RES_A17_ENC_SA;
//.DW _RES_A18_ENC_SA;
//.DW _RES_A19_ENC_SA;
//.DW _RES_A20_ENC_SA;

//.DW _RES_A21_ENC_SA;
//.DW _RES_A22_ENC_SA;
//.DW _RES_A23_ENC_SA;
//.DW _RES_A24_ENC_SA;
//.DW _RES_A25_ENC_SA;
//.DW _RES_A26_ENC_SA;
//.DW _RES_A27_ENC_SA;
//.DW _RES_A28_ENC_SA;
//.DW _RES_A29_ENC_SA;
//.DW _RES_A30_ENC_SA;
//
//.DW _RES_A31_ENC_SA;
//.DW _RES_A32_ENC_SA;
//.DW _RES_A33_ENC_SA;
//.DW _RES_A34_ENC_SA;
//.DW _RES_A35_ENC_SA;
//.DW _RES_A36_ENC_SA;
//.DW _RES_A37_ENC_SA;
//.DW _RES_A38_ENC_SA;
//.DW _RES_A39_ENC_SA;
//.DW _RES_A40_ENC_SA;

//.DW _RES_A41_ENC_SA;
//.DW _RES_A42_ENC_SA;
//.DW _RES_A43_ENC_SA;
//.DW _RES_A44_ENC_SA;
//.DW _RES_A45_ENC_SA;
//.DW _RES_A46_ENC_SA;
//.DW _RES_A47_ENC_SA;
//.DW _RES_A48_ENC_SA;
//.DW _RES_A49_ENC_SA;
//.DW _RES_A50_ENC_SA;
//
//.DW _RES_A51_ENC_SA;
//.DW _RES_A52_ENC_SA;
//.DW _RES_A53_ENC_SA;
//.DW _RES_A54_ENC_SA;
//.DW _RES_A55_ENC_SA;
//.DW _RES_A56_ENC_SA;
//.DW _RES_A57_ENC_SA;
//.DW _RES_A58_ENC_SA;



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -