找回密码
 立即注册
查看: 69|回复: 1

I2S程序移植

[复制链接]
  • 打卡等级:以坛为家I
  • 打卡总天数:237
  • 最近打卡:2026-03-07 00:19:39
已绑定手机

11

主题

69

回帖

587

积分

高级会员

积分
587
发表于 2026-2-21 00:04:55 | 显示全部楼层 |阅读模式

//=================== 头文件包含 ============================================
#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;
                }
        }
}

回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:347
  • 最近打卡:2026-03-07 12:55:14

842

主题

1万

回帖

2万

积分

管理员

积分
22606
发表于 2026-2-21 08:10:40 | 显示全部楼层
截图202602210810307913.jpg
回复

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2026-3-7 16:49 , Processed in 0.100387 second(s), 49 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表