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

📄 main.c

📁 SmartARM2400系列开发板全套资料
💻 C
字号:
/****************************************Copyright (c)****************************************************
**                         Guangzhou ZHIYUAN electronics Co.,LTD.                               
**                                     
**                               http://www.embedtools.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:			Chenmingji
** Created date:		2004-09-16
** Version:				1.0
** Descriptions:		The original version
**
**--------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
** Version:
** Descriptions:
**
*********************************************************************************************************/
#include "main.h"

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

volatile  uint32	Snd_End;			                                /* 为1时,表明WAV文件已经播放完毕*/
volatile  uint32 	I2SSndPt;			                                /* WAV声音数据指针              */

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

/* 	        
 *  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

/*********************************************************************************************************
** 函数名称 :I2SIRQISR
** 函数功能 :发送中断
** 入口参数 :无
** 出口参数 :无
**********************************************************************************************************/
void __irq I2SIRQISR(void) 
{
  	volatile uint32 WavDat = 0;
  	volatile uint32 LastDatToSnd_N = 0;
  	
  	if (I2SSNDIRQ_ON) {
		if (SNDTHELAST) {
			LastDatToSnd_N = WAVFILESIZ - I2SSndPt;
		
			switch (LastDatToSnd_N) {
				case 1:
					WavDat    = WaveData[I2SSndPt];
					I2STXFIFO = WavDat;			 			
					I2SSndPt += 1;
					break;
				case 2:
					WavDat    = (WaveData[I2SSndPt] << 8 ) 
								| (WaveData[I2SSndPt + 1]);
					I2STXFIFO = WavDat;			 			
					I2SSndPt += 1;
					break;
				case 3:
					WavDat    = (WaveData[I2SSndPt + 2] << 24) 
								| (WaveData[I2SSndPt]   << 8 ) 
								| (WaveData[I2SSndPt + 1]);
					I2STXFIFO = WavDat;			 			
					I2SSndPt += 2;
					break;
				default:
					break;
			}
			Snd_End = 1;
			WaitUntilSndEND();
			I2SSNDIRQ_DISABLE();
			VICVectAddr = 0;								
			return;
		}
		else {
			WavDat 	  =   (WaveData[I2SSndPt + 2] << 24) 
						| (WaveData[I2SSndPt + 3] << 16) 
						| (WaveData[I2SSndPt]     << 8 ) 
						| (WaveData[I2SSndPt + 1]);
			I2STXFIFO = WavDat;			 					
			I2SSndPt += 4;
		}
	}
	I2SSNDIRQ_DISABLE();							                    /* 需以禁止IRQ发送中断的方式返回*/
    VICVectAddr = 0;										
}

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

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

	
	PINSEL0 = 0x00055500;                                               /* 初始化P0.4-P0.9为I2S接口引脚  */
	
	/* 
	 *  I2S接口的位速率,也就是I2S的串行时钟I2S_BitRate =
	 *  采样率Sample rate * 声音的通道数 CHn * 所产生声音数据的位数BITn 
	 */
	I2STXRATE = I2STXRATE_VAL;						                    /* I2S接口的发送位速率           */
	                                                                    /* = 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  */
	                                                                    /* WS周期=(WSHALFPERIOD+1)*2     */

	/*
	 *  初始化音频输出通道,先复位   
	 */
	DAOValue  = I2SDAO;								
	DAOValue &= ~((0x01 << 5) | (0x01 << 15));		                    /* 设置音频输出通道为主机,       */
	                                                                    /* 取消静音                      */
	I2SDAO    = (0x01 << 4) | (0x01 << 3) | DAOValue;	                /* 异步复位音频输出通道和FIFO,   */
	                                                                    /* 禁用FIFO,同时将输出通道置于   */
	                                                                    /* 静音模式                      */

	/*
	 *  音频输出通道开始按设定模式工作
	 */
	DAOValue = I2SDAO;
	I2SDAO   = DAOValue & (~((0x01 << 4) | (0x01 <<3)));                /* 停止复位,使能FIFO,            */
	                                                                    /* 不使用静音模式                */
	
	/*         
	 *  设置I2S发送中断        
	 */
	I2SIRQ        = 0x04 << 16;						                    /* 设置I2S发送中断触发深度为     */
	                                                                    /* 4个字节                       */
    VICIntEnClr  |= 0x80000000;	
	VICVectPri31  = 0x06;					
	VICVectAddr31 = (uint32)I2SIRQISR;	
	VICIntEnable |= 0x80000000;		
	IRQEnable();
}

/*********************************************************************************************************
** 函 数 名: WrL3Addr												
** 功能说明:地址模式下,通过L3接口发送一个字节到UDA1341							
** 入口参数: out	 发送的字节												
** 出口参数: 无																
*********************************************************************************************************/
void WrL3Addr(uint8 out)
{
    uint32 i = 0, j = 0;

	FIO3CLR |=  L3MODE;									                /* 选择地址模式                  */

	/* 
	 *  数据发送 
	 */
	for (i = 0; i < 8; i++) {
		if ((out & 0x01) == 0x01) {
			FIO3SET |= L3DATA;
		}
		else {
			FIO3CLR |= L3DATA;		
		}
		out = (unsigned char)(out >> 1);			
		FIO3CLR |= L3CLOCK;			

		for (j = 0; j < 10; j++);

		FIO3SET |= L3CLOCK;			
		for (j = 0; j < 10; j++);
	}
}

/*********************************************************************************************************
** 函 数 名: WrL3Data												 
** 功能说明:DATA模式下通过L3接口发送一个字节到UDA1341					 
** 入口参数: out	 发送的字节	
** 出口参数: 无																 
*********************************************************************************************************/
void WrL3Data(uint8 out)
{
    uint32 i = 0, j = 0;

	FIO3SET |= L3MODE;		 							                /* 选择Data模式                 */

	for (i = 0; i < 8; i++) {
		FIO3CLR |= L3CLOCK;			
		
		if ((out & 0x01) == 0x01) {
			FIO3SET |= L3DATA;
		}
		else {
			FIO3CLR |= L3DATA;		
		}
		out = (unsigned char)(out >> 1);			

		for (j = 0; j < 10; j++);

		FIO3SET |= L3CLOCK;			

		for (j = 0; j < 10; j++);

	}
}

/*********************************************************************************************************
** 函数名称:UDA1341Init																												
** 功能说明:UDA1341的初始化				
** 入口参数: 无																
** 出口参数: 无																
*********************************************************************************************************/
void  UDA1341Init(void)
{  
	/* 
	 *  设置P3.19~P3.21管脚为L3接口,因而这些引脚被设置为GPIO 
	 */
	PINSEL7 = 0;
  	FIO3DIR  = L3MODE | L3CLOCK | L3DATA;
	FIO3SET |= L3CLOCK;		                                            /* L3接口空闲时,                */
	                                                                    /* 时钟线上维持高电平           */
	
	WrL3Addr(0x14 + 2); 	                                            /* 进入状态设置模式(000101xx+10)*/
	
//	WrL3Data(0x60); 		                                            /* 0,1,10,000,0 复位,256fs,     */
                                                                        /* I2S Bus,不使用DCfilter       */
                                                                        
	WrL3Data(0x40); 		                                            /* 0,1,00,000,0 复位,512fs,     */
	                                                                    /* I2S Bus,不使用DCfilter       */
	
	WrL3Addr(0x14 + 2); 				
//	WrL3Data(0x20); 		                                            /* 0,0,10,000,0 停止复位,256fs, */
                                                                        /* I2S Bus,不使用DCfilter       */
	WrL3Data(0x00); 		                                            /* 0,0,00,000,0 停止复位,512fs, */
	                                                                    /*I2S Bus,不使用DCfilter        */
	
	WrL3Addr(0x14 + 2); 
    WrL3Data(0x81);    		                                            /* 1,0,0,0,0,0,11 输出和输入增益*/
                                                                        /* 都为0,ADC_无极性,DAC_无极性, */
                                                                        /* 单倍回放速度,仅DAC打开       */
    
    
	MUTE_OFF();                                                         /* 取消静音                     */
		
	/* 
	 *  声音大小 
	 */
	WrL3Addr(0x14);
	WrL3Data(LOUD);			                                            /* Bit5~0为音量控制位,0x00时为最*/
	                                                                    /* 大声音,0x3f时为声音最小.     */
}

/*********************************************************************************************************
** 函数名称 :main
** 函数功能 :I2S WAV播放
** 调试说明 :1、连接底板和I2S PACK板
**			  2、程序不能在内部RAM中调试
*********************************************************************************************************/
int main(void)
{
	volatile uint32 WavDat = 0;
	Snd_End  = 0;
	I2SSndPt = MusicStartPos;					                        /* 初始化为指向Wav文件里的声音数*/
	                                                                    /* 据起始处                     */

	I2SInit();
	UDA1341Init();
	
	/* 
	 *  先发送8个字节的音频数据,触发I2S发送中断 
	 */
	WavDat 	  =   (WaveData[I2SSndPt + 2] << 24) 
				| (WaveData[I2SSndPt + 3] << 16) 
				| (WaveData[I2SSndPt] << 8) 
				| (WaveData[I2SSndPt + 1]);		                        /* 优先发送低16位数据字,        */
				                                                        /* 数据字里优先发送MSB          */
	
	I2SSndPt += 4;
	I2STXFIFO = WavDat;					 	
	
	WavDat    =   (WaveData[I2SSndPt + 2] << 24) 
				| (WaveData[I2SSndPt + 3] << 16) 
				| (WaveData[I2SSndPt] << 8) 
				| (WaveData[I2SSndPt + 1]);
	
	I2SSndPt += 4;
	I2STXFIFO = WavDat;			 	
	
	while (1){
		if (Snd_End == 0) {	
			I2SSNDIRQ_EN();
		}
		else {
			MUTE_ON();
			I2SOUT_STOP();
			break;
		}
	}
	while  (1);
    return (0);
}
/*********************************************************************************************************
  END FILE
*********************************************************************************************************/

⌨️ 快捷键说明

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