今天用之前AI8051U的程序修改的可以播放四个音的程序,需要注意的是这两个单片机I2S接口引脚不同,还有就是STC32G144K246必须使用PLL时钟才可以。
-
- //=================== 头文件包含 ============================================
- #include "STC32G144K246.H"
- #include "intrins.h"
-
- #include "yinxiao1.h"
- #include "yinxiao2.h"
- #include "yinxiao3.h"
- #include "yinxiao4.h"
-
-
- //=================== 主时钟和采样率定义宏 =================================
- #define FOSC 96000000UL // 系统主时钟 96MHz (由PLL产生)
- #define PLL_CLK 480000000UL // PLL输出时钟 480MHz
- #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:SCLK空闲时为低电平, 1:SCLK空闲时为高电平
- #define DATLEN 0 // 数据长度, 0:16位, 1:24位, 2:32位, 3:保留
- #define CHLEN 0 // 声道长度(在PCM模式下), 0:16位, 1: 32位
-
- //#define I2S_MCLKDIV (FOSC / (8 * 16 * 2 * SampleRate)) // MCLK分频系数, 支持16bit.
- //#define I2S_BCLKDIV (FOSC / (16 * 2 * SampleRate)) // BCLK分频系数, 支持16bit.
- ///2#define I2S_MCLKDIV (FOSC / (8 * 16 * 2 * SampleRate)) // MCLK分频系数, 支持16bit.
- ///2#define I2S_BCLKDIV (FOSC / (16 * SampleRate)) // BCLK分频系数, 支持16bit.
-
- // 分频系数计算
- #define I2S_MCLKDIV (FOSC / (8 * 16 * 2 * SampleRate)) // MCLK分频系数
- #define I2S_BCLKDIV (FOSC / (16 * 2 * SampleRate)) // BCLK分频系数
-
-
-
-
-
-
- //=================== 类型定义 ============================================
- typedef unsigned char u8;
- typedef unsigned int u16;
- typedef unsigned long u32;
-
- u16 yinxiao1_index;
- u16 yinxiao2_index;
- u16 yinxiao3_index;
- u16 yinxiao4_index;
-
- bit yinxiao1;
- bit yinxiao2;
- bit yinxiao3;
- bit yinxiao4;
-
- // 时间戳变量 - 用于记录音频开始播放的时间,实现"挤掉最先播放的"逻辑
- u16 start_time1;
- u16 start_time2;
- u16 start_time3;
- u16 start_time4;
- u16 current_time; // 当前时间计数器
-
- // 按键状态变量 - 用于检测按键按下事件
- bit key1_pressed;
- bit key2_pressed;
- bit key3_pressed;
- bit key4_pressed;
-
- u16 buffer[2];
- bit flip;
- bit flip_local;
-
-
-
- //=================== 延时函数 ==============================================
- void delay_ms(u16 ms)
- {
- u16 i;
- while(ms--)
- {
- i = 4000;
- while(i--);
- }
- }
-
- //=================== PLL时钟初始化 ==========================================
- void pll_init(void)
- {
- // STC32G的PLL初始化
- HPLLCR = 0x10; // 选择HIRC作为PLL输入
- HPLLPDIV = 8; // 预分频8, HIRC 48MHz/8 = 6MHz
- HPLLCR |= 0x0e; // 倍频80, 6MHz*80 = 480MHz
- HPLLCR |= 0x80; // 使能HPLL
-
- delay_ms(10); // 等待PLL稳定
-
- CLKDIV = 5; // 系统时钟分频: 480MHz/5 = 96MHz
- CLKSEL = 0x04; // 选择HPLL/2作为主时钟源
-
- delay_ms(10); // 等待时钟切换完成
- }
-
-
-
-
-
-
- //=================== 主函数 ==============================================
- void main(void)
- {
-
- // 初始化系统
- WTST = 0x00;
- CKCON = 0x00;
- EAXFR = 1;
-
- // 初始化PLL时钟
- pll_init();
-
- // 初始化IO口
-
-
- P0M0 = 0x00;
- P0M1 = 0x00;
- P1M0 = 0x00;
- P1M1 = 0x00;
-
- P2M0 = 0x00;
- P2M1 = 0x00;
- P2PU = 0xff;
-
- P3M0 = 0x00;
- P3M1 = 0x00;
- P3PU = 0xff;
-
- P4M0 = 0x00;
- P4M1 = 0x00;
- P5M0 = 0x00;
- P5M1 = 0x00;
-
- I2SMD = 0xff; // 模块使能寄存器,初始化为FFH
- I2SSR = 0x00; // 状态寄存器清零
- I2SCR = 0x80 + 0x00; // 使能I2S模块(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); // 高字节:bit1控制I2S_BMCLK输出使能, bit0为BCLK分频系数的bit0, 同时控制是否输出MCLK
- I2SPRL = I2S_BCLKDIV / 2; // 低字节:BCLK分频系数的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引脚切换,
-
复制代码 音效文件在头文件里,
yinxiao1.h
(154.56 KB, 下载次数: 0)
yinxiao2.h
(152 KB, 下载次数: 0)
yinxiao3.h
(85.68 KB, 下载次数: 0)
yinxiao4.h
(121.39 KB, 下载次数: 0)
我用AI写了个将MP3转化为头文件的网页版转换程序,可以方便的进行转换
转换.html
(24.39 KB, 下载次数: 1)
|