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

📄 main.c

📁 这是周立功开发板上的实验程序,这是周立功开发板上的实验程序
💻 C
字号:
/****************************************Copyright (c)**************************************************
**                               Guangzou ZLG-MCU Development Co.,LTD.
**                                      graduate school
**                                 http://www.zlgmcu.com
**
**--------------File Info-------------------------------------------------------------------------------
** File name:			main.c
** Last modified Date:  2004-09-16
** Last Version:		1.0
** Descriptions:		The main() function example template
**
**------------------------------------------------------------------------------------------------------
** Created by:			litiantian
** Created date:		2007-03-19
** Version:				1.0
** Descriptions:		查询方式下的I2S WAV播放。
**
**------------------------------------------------------------------------------------------------------
** Modified by:			Caiqinglong
** Modified date:		2007-08-31
** Version:
** Descriptions:		校对例程的风格及注释。
**
** Rechecked by:        Litiantian
********************************************************************************************************/
#include "config.h"

extern	  uint8		WaveData[];			// WAV文件的声音数据,该WAV的音频特征:采样率22KHz、16位数据、立体声

volatile  uint32 	I2SSndPt;			// WAV声音数据指针

/* UDA1341控制脚定义 */
#define   L3MODE        	(1 << 27) 	// 为0时,使能ADDRESS模式;为1时,使能数据传输模式
#define   L3DATA        	(1 << 29) 	
#define   L3CLOCK       	(1 << 19) 	

/* 	   I2S相关宏 	 */
#define	  WORDWIDTH_MASK	0x3
#define	  TRACKNSEL_MASK	0x4
#define   WSHALF_MASK		0x00007ec0
#define	  WSHALFPERIOD  	0x0f
#define   IIS_INT			31
#define	  I2SSNDIRQ_EN()		(I2SIRQ |= 0x02)
#define   I2SSNDIRQ_DISABLE()	(I2SIRQ &= ~0x02)
#define	  WaitUntilSndEND()		while (((I2SSTATE >> 16) & 0xFF) != 0)	
#define	  I2SSNDIRQ_ON	    	((I2SSTATE & 0x01) == 0x01)
#define	  SNDTHELAST			(I2SSndPt  > WAVFILESIZ - 4)
#define   I2SOUT_STOP()			(I2SDAO |= (0x01 << 3) | (0x01 << 4))
#define   MusicStartPos		45
/* 预先完成I2S初始化参数的计算 */
#define	  SAMPLERATE        22000
#define   BIT_N				16
#define	  CHANNEL_N			2
#define	  I2SBITRATE		(SAMPLERATE *  BIT_N *  CHANNEL_N)
#define   I2STXRATE_VAL		(Fpclk / I2SBITRATE - 1)

/* 声音文件大小 */
#define	  WAVFILESIZ		119384
/*   静音控制   */
#define	  MUTE_OFF()		WrL3Addr(0x14);WrL3Data(0x80)
#define	  MUTE_ON()			WrL3Addr(0x14);WrL3Data(0x84)
/* 声音大小控制 */
#define	  LOUD				0x0
#define	  SOFT				0x0f
#define   DUMB				0x3f

/*********************************************************************************************************
** 函数名称 :I2S_SndNchar
** 函数功能 :从数据缓存datbuf的某处开始发送指定数目的字节到I2S_FIFO,并自动调整数据缓存的发送指针
** 入口参数 :uint8* datbuf  :需发送出去的数据缓存首地址
			  uint32* datbufpt_pt:从datbuf[*datbufpt_pt]开始发送4个字节
**            uint32 snd_N	 :需发送的数据个数			  
** 出口参数 :无
**********************************************************************************************************/
void  I2S_SndNchar(uint8* datbuf, 
					volatile uint32* datbufpt_pt, 
					uint32 snd_N) 
{
  	volatile uint32 WavDat = 0;
  	
  	switch (snd_N)
  	{
  		case 4:
  			WavDat	= (datbuf[*datbufpt_pt  + 2]  << 24)
					  | (datbuf[*datbufpt_pt + 3] << 16)
					  | (datbuf[*datbufpt_pt]     << 8)
					  | (datbuf[*datbufpt_pt + 1]);
			break;
		case 3:
			WavDat 	= (datbuf[*datbufpt_pt + 2] << 24)
					  | (datbuf[*datbufpt_pt]   << 8)
					  | (datbuf[*datbufpt_pt + 1]);
			break;
		case 2:
			WavDat  = (datbuf[*datbufpt_pt] << 8)
					  | (datbuf[*datbufpt_pt + 1]);
			break;
		case 1:
			WavDat = datbuf[*datbufpt_pt];
			break;
		default:
			break;
	}

	I2STXFIFO 		= WavDat;	
	*datbufpt_pt   += snd_N;				
	WaitUntilSndEND();
}

/*********************************************************************************************************
** 函数名称 :I2S_SNDWAV
** 函数功能 :以查询方式将WAV文件发送完毕
** 入口参数 :无
** 出口参数 :无
**********************************************************************************************************/
void  I2S_SNDWAV(void) 
{
  	volatile uint32 LastDatToSnd_N  = 0;
	volatile uint32	Snd_End 		= 0;			// 为1时,表明WAV文件已经播放完毕

	while (0 == Snd_End)
	{   	
		if (SNDTHELAST)								// 需发送的数据已经不足4个,按照剩下的数据字节数目为1、2、3的情况分类处理
		{
			LastDatToSnd_N = WAVFILESIZ - I2SSndPt;
			I2S_SndNchar(WaveData, &I2SSndPt, LastDatToSnd_N); 
			Snd_End = 1;		
		}
		else
		{
			I2S_SndNchar(WaveData, &I2SSndPt, 4); 
		}
	}
}

/*********************************************************************************************************
** 函数名称 :I2SInit
** 函数功能 :初始化I2S接口
** 入口参数 :无
** 出口参数 :无
**********************************************************************************************************/
void I2SInit(void) 
{
	uint32 DAOValue;

	PCONP |= (1 << 27);	  							// 在PCONP中使能I2S接口

	/* 初始化P0.6-P0.9、P0.23、P0.24为I2S接口引脚 */
	PINSEL0 = 0x00055000;
	PINSEL1 = 0x00028000;
	
	/* I2S接口的位速率,也就是I2S的串行时钟I2S_BitRate = 采样率Sample rate * 声音的通道数 CHn * 所产生声音数据的位数BITn */
	I2STXRATE = I2STXRATE_VAL;					 	// I2S接口的发送位速率I2S_BitSndRate = Fpclk / (TXRATE + 1)

	/*   设置音频输出通道的工作模式   */
	I2SDAO &= ~WORDWIDTH_MASK;						// 配置数据宽度
	I2SDAO |= 0x01;									// 0x00:数据字宽度8位;0x01:宽度16位;0x02:保留;0x03:32位
	
	I2SDAO &= ~TRACKNSEL_MASK;						// 配置声道模式
	I2SDAO |= 0x00; 								// 0x04:单声道;0x0:立体声							
	
	I2SDAO &= ~WSHALF_MASK;
	I2SDAO |= WSHALFPERIOD << 6;					// 分频值WSHALFPERIOD可从0到511

⌨️ 快捷键说明

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