📄 main.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 + -