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