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

📄 main.c

📁 用凌阳的十六位单片机SPCE061A做得语音开发板,可以录播WMA格式的音乐,外挂ST39VF040存储,可以存几十首歌,有音频编解码代码
💻 C
字号:

//	功能描述:SPCE061A语音系统
#include "SPCE061A.h"
#include "DVR1600.h"

extern void ERASE_ST39VF040(void);
extern void Write_ST39VF040_One_Word(unsigned long m_addr,unsigned int m_data);
extern unsigned int Read_ST39VF040_One_Word(unsigned long m_addr);
extern void SACM_DVR1600_Stop(void);

#define C_UARTBaudRate_38400_H 0x01
#define C_UARTBaudRate_38400_L 0x40
#define uint unsigned int
#define ulong unsigned long
uint ext2flag,recvdata1,recvdata2,sendflag,playflag,playstate;
uint SOUND_NUM,VolumeIdx,writeflag,loopflag;
ulong flashaddr,timedelay;
int SndIdx;
uint uartrecvchar(uint *pchar)
{
	uint temprecv;
	timedelay=0;
	while(!(*P_UART_Command2 & 0x0080)){
        if(++timedelay==0x00100000)
		{		
	        *P_UART_Command1 = C_UART_RX_INT;
		    return 0;
	 	}
	 	*P_Watchdog_Clear = 0x0001;
	}
	temprecv = *P_UART_Data;
	temprecv &=0x00FF;
	*pchar=temprecv;
	return 1;
}
void Initial(void)
{	
//	*P_SystemClock = 0x0098;
	*P_INT_Mask = C_IRQ3_EXT2;
    *P_IOA_Dir=0xffff;
    *P_IOA_Attrib=0xffff;
    *P_IOA_Data=0xffff;
    *P_IOB_Dir=0xff77;
    *P_IOB_Attrib=0xffff;
    *P_IOB_Data=0xfff7;					
	*P_UART_BaudScalarHigh = C_UARTBaudRate_38400_H;		//波特率设为38400
	*P_UART_BaudScalarLow = C_UARTBaudRate_38400_L;
	*P_UART_Command1 = C_UART_RX_INT;				        //UART接收中断使能
	*P_UART_Command2 = C_UART_TX_EN | C_UART_RX_EN;		    //UART接收发送管脚使能
	__asm("IRQ ON");
}

void Record(void)
{
	SACM_DVR1600_Initial();							// DVR1600初始化
	SACM_DVR1600_Rec(0, BITRATE_16K);				// 开始录音,选择16Kbps码率。第一个参数无意义。
	while(SACM_DVR1600_Status()&STATUS_PLAY)		// 检测录音是否完成(当录音数据充满Flash后录音完成)
	{
		*P_Watchdog_Clear = 0x01;					// 清看门狗
		SACM_DVR1600_ServiceLoop();					// 进行压缩编码
	}
}

void PlayRecord(void)
{
	playstate=1;
	SACM_DVR1600_Play(SndIdx, DAC_1+DAC_2, RAMP_UP_DN);	// 开始放音,由DAC1和DAC2输出。第一个参数无意义。
	while(SACM_DVR1600_Status()&STATUS_PLAY)		// 检测放音是否完成
	{
		*P_Watchdog_Clear = 0x01;					// 清看门狗
		SACM_DVR1600_ServiceLoop();					// 进行解码
	}
	if (loopflag){
	    SndIdx++;
	    if (SndIdx==SOUND_NUM)
		    SndIdx=0;
	}
}

//========================================================================
//	主函数
//========================================================================
int main()
{	
	Initial();
	ext2flag=0;
	playflag=0;
	loopflag=1;
	playstate=0;
	flashaddr=0x00000004;
	
/*	flashaddr=0x00001000;
	for (loopflag=0;loopflag<0xff;loopflag++)
		SOUND_NUM=Read_ST39VF040_One_Word(flashaddr);
*/	
	SOUND_NUM=Read_ST39VF040_One_Word(flashaddr);
	if (SOUND_NUM>30)
		SOUND_NUM=30;
	VolumeIdx = 8;			// 音量等级,可在0~15之间变化,默认的音量等级为8。
	SndIdx = 0;
	SACM_DVR1600_Initial();							// DVR1600初始化
	SACM_DVR1600_Volume(VolumeIdx);
	while(1)
	{
		if (ext2flag)
		{
			if (playflag)
			    PlayRecord();    
			*P_INT_Mask = *P_INT_Mask | C_IRQ3_EXT2;
			ext2flag=0;
		}
		*P_Watchdog_Clear = 0x0001;
	}    	
}


//========================================================================
//	中断服务程序
//========================================================================
void FIQ(void)__attribute__((ISR));
void FIQ()
{
	*P_INT_Clear = C_FIQ_TMA;				// 清中断请求标志
	SACM_DVR1600_ISR();						// 调用中断服务子程序
}
void IRQ3(void) __attribute__ ((ISR));      //外部中断
void IRQ3(void)
{
	ext2flag=1;
	*P_INT_Clear = C_IRQ3_EXT2;
}
void IRQ5(void) __attribute__ ((ISR));      //定时中断
void IRQ5(void)
{       
}
void IRQ7(void) __attribute__ ((ISR));      //串口中断                    
void IRQ7(void)
{ 
	writeflag=0;
	*P_UART_Command1 = 0x0000;
	
    if (!uartrecvchar(&recvdata1))
    	return;
	if (recvdata1==0x0001)
	{
		SACM_DVR1600_Stop();
		playflag=1;	
	    loopflag=1;
	    if (playstate)
	    	SndIdx=-1;
	    else
	        SndIdx=0;
		*P_UART_Command1 = C_UART_RX_INT;
		return;
	}
	else if (recvdata1==0x0002)
	{
		SACM_DVR1600_Stop();
		if (!uartrecvchar(&recvdata1))
    	    return;
		playflag=1;	
	    loopflag=0;
	    SndIdx=recvdata1;
		*P_UART_Command1 = C_UART_RX_INT;
		return;
	}
	else if (recvdata1==0x0003)
	{
		SACM_DVR1600_Stop();
		playstate=0;
		playflag=0;	
		loopflag=0;
		*P_UART_Command1 = C_UART_RX_INT;
		return;
	}
	else if (recvdata1==0x0004)
	{
		VolumeIdx += 1;
		if(VolumeIdx>15)
			VolumeIdx = 0;
		SACM_DVR1600_Volume(VolumeIdx);
		*P_UART_Command1 = C_UART_RX_INT;
		return;
	}	
	else if (recvdata1==0x0005)
	{
		if(VolumeIdx>0)
		    VolumeIdx -= 1;
		SACM_DVR1600_Volume(VolumeIdx);
		*P_UART_Command1 = C_UART_RX_INT;
		return;
	}
	else if (recvdata1==0x0006)
	{
		SACM_DVR1600_Stop();
		writeflag=1;
	    ERASE_ST39VF040();
	}
	else
	{
		*P_UART_Command1 = C_UART_RX_INT;
	    return;
	}
	    
	sendflag=0;
	flashaddr=0x00000000;
    while (1)
    {
    	flashaddr++;
        if (!uartrecvchar(&recvdata1))
        {
            if (sendflag && writeflag)
	        {
	            Write_ST39VF040_One_Word(flashaddr,recvdata2);
	        }
	        break;
        	return;
        }
	    if (sendflag==0)
	    {
	    	sendflag=1;
	        recvdata2 = recvdata1;
	    }
	    else
	    {
	    	sendflag=0;
	        recvdata1 = recvdata1 <<8;
	        recvdata1 = recvdata1 + recvdata2;
	        Write_ST39VF040_One_Word(flashaddr,recvdata1);	
	    }
//	    if (recvint==4096)
//	    {
//	    	recvint=0;
//	        *P_UART_Data = 0x01;
//	        while(!(*P_UART_Command2 & 0x0040)){
//	 	        *P_Watchdog_Clear = 0x0001;
//	        }
//	    }
	    *P_Watchdog_Clear = 0x0001;
    }           
}

⌨️ 快捷键说明

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