- 打卡等级:以坛为家I
- 打卡总天数:237
- 最近打卡:2026-03-07 00:19:39
已绑定手机
高级会员
- 积分
- 587
|
//=================== 头文件包含 ============================================
#include "AI8051U.H"
#include "intrins.h"
#include "firecrackers_16000_u8_mono.h"
//=================== 主时钟和采样率定义宏 =================================
#define FOSC 32000000UL // 定义主时钟
#define SampleRate 16000 // 定义采样率
//=================== I2S的宏定义 ==============================================
#define MCKOE 0 // I2S主时钟输出控制, 0:禁止I2S主时钟输出, 1:允许I2S主时钟输出
#define I2SEN 0x04 // I2S模块使能, 0x00:禁止, 0x04:允许
#define I2S_MODE 2 // I2S模式, 0:从机发送模式, 1:从机接收模式, 2:主机发送模式, 3:主机接收模式,
#define PCMSYNC 0 // PCM帧同步, 0: 短帧同步, 1: 长帧同步
#define STD_MODE 0 // I2S标准选择, 0: I2S飞利浦标准, 1: MSB左对齐标准, 2:LSB右对齐标准, 3:PCM标准, CS4334、CS4344使用0:I2S飞利浦标准,PT8211使用1: MSB左对齐标准。
#define CKPOL 0 // I2S稳态时钟极性, 0:时钟稳定状态为低电平, 1:时钟稳定状态为高电平
#define DATLEN 0 // 数据长度, 0:16位, 1:24位, 2:32位, 3:保留
#define CHLEN 0 // 通道长度(每个音频通道的位数), 0:16位, 1: 32位
#define I2S_MCLKDIV (FOSC / (8 * 16 * 2 * SampleRate)) // MCLK分频系数, 对于双声道16bit.
#define I2S_BCLKDIV (FOSC / (16 * 2 * SampleRate)) // BCLK分频系数, 对于双声道16bit.
//=================== 变量定义 ==============================================
typedef unsigned char u8;
typedef unsigned int u16;
typedef unsigned long u32;
u16 firecrackers_index;
u16 monkey_index;
u16 boom_index;
bit firecrackers;
u16 buffer[2];
bit flip;
bit flip_local;
//=================== 主函数 ==============================================
void main(void)
{
WTST = 0x00;
CKCON = 0x00;
EAXFR = 1;
P0M0 = 0x00;
P0M1 = 0x00;
P1M0 = 0x00;
P1M1 = 0x00;
P2M0 = 0x00;
P2M1 = 0x00;
P2PU = 0xff;
P3M0 = 0x00;
P3M1 = 0x00;
P4M0 = 0x00;
P4M1 = 0x00;
P5M0 = 0x00;
P5M1 = 0x00;
I2SMD = 0xff; // 内部保留字节,需设置为FFH
I2SSR = 0x00; // 状态寄存器清0
I2SCR = 0x80 + 0x00; // 使能发送缓冲区空中断(0x80), +0x00:Motorola格式, +0x10:TI格式
HSCLKDIV = 1; // 高速时钟分频器 1~255 (默认2)
I2S_CLKDIV = 1; // I2S主时钟分频
I2SMCKDIV = I2S_MCLKDIV; // I2S时钟分频,I2SMCLK = 主频/2/I2S_CLKDIV/HSCLKDIV/I2SMCKDIV, 或I2SMCLK = PLLCLK/2/I2S_CLKDIV/HSCLKDIV/I2SMCKDIV
I2SPRH = (MCKOE << 1) + (I2S_BCLKDIV & 1); // 设置I2S_BMCLK分频系数的bit0, 并允许或禁止输出MCLK。
I2SPRL = I2S_BCLKDIV / 2; // 设置I2S_BMCLK分频系数的bit8~bit1
I2SCFGH = I2S_MODE; // 设置I2S模式为主机发送模式
I2SCFGL = (PCMSYNC << 7) + (STD_MODE << 4) + (CKPOL << 3) + (DATLEN << 1) + CHLEN;
P_SW3 = (P_SW3 & 0x3f) | (2 << 6); // I2S端口切换,
// 00: P3.2(BCLK) P3.3(MCLK) P3.4(SD) P3.5(LRCK),
// 01: P1.7(BCLK) P1.6(MCLK) P1.5(SD) P1.4(LRCK),
// 10: P2.3(BCLK) P2.2(MCLK) P2.1(SD) P2.0(LRCK),
// 11: P4.3(BCLK) P1.6(MCLK) P4.1(SD) P4.0(LRCK)
I2SCFGH |= I2SEN; // 使能I2S
firecrackers_index = 0;
firecrackers = 0;
flip = 0;
flip_local = 0;
EA = 1;
while (1)
{
if (flip_local != flip)
{
if (1)
{
buffer[flip_local] = 0;
if (1) // 小洋鞭
{
buffer[flip_local] += firecrackers_16000_u8_mono_pcm[firecrackers_index++];
if (firecrackers_index >= firecrackers_16000_u8_mono_pcm_len)
{
firecrackers_index = 0;
}
}
flip_local = flip;
}
}
}
}
//=================== I2S中断函数 ==============================================
void I2S_ISR(void)
#ifdef __MODEL__
interrupt I2S_VECTOR
#endif
{
if (I2SSR & 0x02) // 发送缓冲区空
{
if (I2SSR & 0x04) // 右声道
{
u16 tmp = buffer[flip] << 6;
I2SDRH = (u8)(tmp / 256); // 发送下一帧音频数据
I2SDRL = (u8)(tmp % 256);
}
else // 左声道
{
u16 tmp = buffer[flip] << 6;
I2SDRH = (u8)(tmp / 256); // 发送下一帧音频数据
I2SDRL = (u8)(tmp % 256);
flip = !flip;
}
}
}
|
|