#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "wm8711.h"
#include "pcm1870.h"
#include "eeprom.h"
#include "wm8978.h"
/*--------------------------------------
--------音频DAC I2S3 引脚 PA15 PB3 PB5--
---------PB6 PB7 wm8711 IIC配置引脚 ----
---------PC7 MCLK输出引脚---------------
---------------------------------------*/
//I2S_3 PB12-WS PB13-CK PB15-SD PC6-MCLK
void WM8711_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 |GPIO_Pin_14 | GPIO_Pin_15;//WS CK SD
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource12, GPIO_AF_SPI2);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_SPI2);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_SPI2);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_I2S2ext);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; //MCLK
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_SPI2);
//------------------wm8711 I2C GPIO Init
// pcm1770 cs- pc8 md- pa8 mc- pc9
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;//md
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;//mc
// GPIO_Init(GPIOA, &GPIO_InitStructure);
IIC_SDA=1;
IIC_SCL=1;
}
// I2S3 初始化
void I2S3_Init(void)
{
I2S_InitTypeDef I2S_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
SPI_I2S_DeInit(SPI2);
I2S_StructInit(&I2S_InitStructure);
I2S_InitStructure.I2S_AudioFreq = I2S_AudioFreq_8k;;
I2S_InitStructure.I2S_Standard = I2S_Standard_Phillips;
I2S_InitStructure.I2S_DataFormat = I2S_DataFormat_16b;
I2S_InitStructure.I2S_CPOL = I2S_CPOL_Low;
I2S_InitStructure.I2S_Mode = I2S_Mode_MasterTx;
I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Enable;
I2S_Init(SPI2, &I2S_InitStructure);
I2S_FullDuplexConfig(I2S2ext, &I2S_InitStructure);
I2S_Cmd(SPI2, ENABLE);
I2S_Cmd(I2S2ext, ENABLE);
}
void I2S3_NVIC(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = SPI2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority =4;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_TXE, DISABLE);
}
// WM8711初始化
void WM8711_Init(void)
{
WM8711_GPIO_Init();
WM8711_Config();
I2S3_Init();
printf("WM1870初始化 \r\n\n");
}
void SDA_OUT(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
void SDA_IN(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
void I2S_Start(void)
{
SPI_I2S_ITConfig(SPI3, SPI_I2S_IT_RXNE, DISABLE);
SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_TXE, DISABLE);
I2S_Cmd(SPI2, ENABLE);
I2S_Cmd(SPI3, ENABLE);
printf("REAL_VOICE START \r\n\n");
}
void delayus(u8 nus)
{
u32 i,j;
for(i=0;i<nus;i++)
for(j=0;j<50;j++);
}
//产生IIC起始信号
void IIC_Start(void)
{
SDA_OUT(); //sda线输出
IIC_SDA=1;
IIC_SCL=1;
delayus(2); //min 1.3us
IIC_SDA=0; //START:when CLK is high,DATA change form high to low
delayus(1); //min 600ns
IIC_SCL=0; //钳住I2C总线,准备发送或接收数据
delayus(2); //min 1.3us
}
//产生IIC停止信号
void IIC_Stop(void)
{
SDA_OUT();//sda线输出
IIC_SCL=0;
IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
delayus(2);//min 1.3us
IIC_SCL=1;
delayus(1);//min 600ns
IIC_SDA=1;//发送I2C总线结束信号
delayus(2);//min 1.3us
}
//等待应答信号到来
//返回值:1,接收应答失败
// 0,接收应答成功
u8 IIC_Wait_Ack(void)
{
u16 ucErrTime=0;
IIC_SDA=1;
IIC_SCL=1;
delayus(1);//min 600ns
SDA_IN(); //SDA设置为输入
while(READ_SDA)
{
ucErrTime++;
if(ucErrTime>450)
{
IIC_Stop();
return 1;
}
}
IIC_SCL=0;//时钟输出0
return 0;
}
//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答
void IIC_Send_Byte(u8 txd)
{
u8 t;
IIC_SDA=0;
IIC_SCL=0;//拉低时钟开始数据传输
SDA_OUT();
for(t=0;t<8;t++)
{
if(txd&0x80)
IIC_SDA=1;
else
IIC_SDA=0;
txd<<=1;
IIC_SCL=1;
delayus(1); // min 600ns
IIC_SCL=0;
}
}
void WM8711_Control(u8 reg,u8 Wdata)
{
IIC_Start(); //起始信号
IIC_Send_Byte(WM8711_Address&WM8711_Write); //WM8711地址 + 写入
IIC_Wait_Ack();
IIC_Send_Byte(reg); //寄存器地址
IIC_Wait_Ack();
IIC_Send_Byte(Wdata); //寄存器值
IIC_Wait_Ack();
IIC_Stop();
}
void codec_send(u16 Wdata)
{
IIC_Start(); //起始信号
IIC_Send_Byte(0x34); //WM8711地址 + 写入
IIC_Wait_Ack();
IIC_Send_Byte((Wdata>>8)&0xFF); //寄存器地址
IIC_Wait_Ack();
IIC_Send_Byte(Wdata&0xFF); //寄存器值
IIC_Wait_Ack();
IIC_Stop();
}
extern uint16_t const VirtAddVarTab[];
void WM8711_Config(void)
{
FLASH_Unlock(); //获取标志信息
EE_Init();
Vol=0xDA;
WM8711_Control(0x1E,0x00); //reset
WM8711_Control(0x1E,0x00); //reset
WM8711_Control(0x04,0x80|Vol); //Left Channel Zero Cross detect enable volume:1111001
WM8711_Control(0x06,0x80|Vol); //Right Channel Zero Cross detect enable volume:1111001
WM8711_Control(0x08,0x18); //R4 DAC SEL BYPASS Enable
WM8711_Control(0x0A,0x01); //DAC MUTE Disable
WM8711_Control(0x0C,0x07); //R6 power OFF: 0x87 ON :0x07
WM8711_Control(0x0E,0x22); //MODE : Master Slaver
WM8711_Control(0x10,0x04); // Normal mode 8K
WM8711_Control(0x12,0x01); // Activate Interface
}
void TUNING(void)
{
WM8711_Control(0x05,0x80|Vol);
WM8711_Control(0x07,0x80|Vol);
}
void vol(uint16_t v) // 0~99
{
v = 63*v/100;
v = (v & VOL_MASK) << VOL_POS;
codec_send(REG_LOUT1_VOL | v);
codec_send(REG_ROUT1_VOL | HPVU | v);
codec_send(REG_LOUT2_VOL | v);
codec_send(REG_ROUT2_VOL | SPKVU | v);
}
static uint16_t r06 = REG_CLOCK_GEN | CLKSEL_MCLK | MCLK_DIV1 | BCLK_DIV16;
void sample_rate(int sr)
{
uint16_t r07 = REG_ADDITIONAL;
switch (sr)
{
case 8000:
r06 = REG_CLOCK_GEN | CLKSEL_MCLK | MCLK_DIV1 | BCLK_DIV16 ;
// r06 = REG_CLOCK_GEN | CLKSEL_MCLK | MCLK_DIV6 | BCLK_DIV8 | (r06 & MS);
r07 |= SR_8KHZ;
break;
case 11025:
r06 = REG_CLOCK_GEN | CLKSEL_PLL | MCLK_DIV8 | BCLK_DIV8 | (r06 & MS);
r07 |= SR_12KHZ;
break;
#i
I2S.rar_I2S全双工_i2s 全双工_stm32f4 I2S_全双工I2S_本田f4i配置


2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
STM32F4系列微控制器是STMicroelectronics公司推出的一款高性能、低功耗的32位微控制器,广泛应用于各种嵌入式系统设计。在音频处理领域,I2S(Inter-IC Sound)接口是一种标准的通信协议,用于在数字音频设备之间传输音频数据。在本文中,我们将深入探讨STM32F4实现I2S全双工模式的配置及其实现过程。 了解I2S协议的基本概念是至关重要的。I2S由主设备和从设备组成,主设备负责时钟信号的产生和帧同步信号,而从设备根据这些信号接收或发送数据。I2S数据线包括数据线(Data Line)、时钟线(Clock Line)和帧同步线(Word Select Line)。在全双工模式下,设备同时可以发送和接收数据,提高了数据传输效率。 STM32F4配置I2S全双工模式需要进行以下几个关键步骤: 1. **时钟配置**:I2S功能的使用依赖于内部的APB1或APB2总线时钟,因此首先要开启相应的时钟源,如RCC_APB1PeriphClockCmd和RCC_APB2PeriphClockCmd函数。 2. **GPIO配置**:根据I2S接口的引脚分配,配置GPIO为 Alternate Function(AF)模式,设置合适的输出类型、速度和上拉/下拉电阻。例如,I2S_SCK、I2S_WS和I2S_SD等引脚。 3. **I2S初始化**:使用I2S_InitTypeDef结构体初始化I2S外设,设置工作模式(全双工)、数据格式、同步模式、标准、分频因子等参数。例如,使用I2S_Mode_FullDuplex设定全双工模式,I2S_DataFormat_16b设定16位数据格式。 4. **I2S外设配置**:通过I2S_Init和I2S_Cmd函数启动I2S外设,并启用I2S传输。 5. **DMA配置**:为了实现连续无阻塞的数据传输,通常会结合DMA(Direct Memory Access)使用。通过DMA_InitTypeDef结构体初始化DMA通道,指定外设寄存器地址、内存地址、传输大小等,然后使用DMA_Cmd开启DMA传输。 6. **中断配置**:如果需要在数据传输完成后执行特定操作,可以配置I2S的中断,如半帧完成中断、帧错误中断等,然后使用NVIC_EnableIRQ开启中断。 7. **数据传输**:当所有配置完成后,可以通过I2S_SendData发送数据,并使用I2S_ReceiveData接收数据。在全双工模式下,发送和接收可同时进行。 在实际应用中,例如本田F4i的音频系统配置,可能需要结合车辆的特定硬件和软件需求进行适配。开发者可以根据提供的代码进行调试,确保I2S通信稳定可靠。 总结来说,STM32F4实现I2S全双工模式涉及多个层面的配置,包括时钟、GPIO、I2S外设、DMA以及中断等。在理解了这些基本知识点后,开发者可以灵活地应用到自己的项目中,实现高效的数据传输。





- 1

























- 粉丝: 113
- 资源: 1万+





我的内容管理 展开
我的资源 快来上传第一个资源
我的收益
登录查看自己的收益我的积分 登录查看自己的积分
我的C币 登录后查看C币余额
我的收藏
我的下载
下载帮助


最新资源



评论0