中级会员
 
- 积分
- 449
- 金钱
- 449
- 注册时间
- 2016-7-12
- 在线时间
- 121 小时
|
10金钱
F103RFT6通过I2S给WM8978发送音频数据,为什么DMA的中断进不了?[mw_shl_code=c,true]u8 WM8978_Init(void)
{
u8 res;
/*配置是stm32的I2S引脚,用来与WM8978进行连接*/
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC, ENABLE); //使能外设GPIOB,GPIOC时钟 |RCC_APB2Periph_AFIO
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_15;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOC, &GPIO_InitStructure);
IIC_Init();//初始化IIC接口,用于对WM8978芯片寄存器的配置
res=WM8978_Write_Reg(0,0); //WM8978的寄存器0,软复位WM8978
if(res)return 1; //发送指令失败,WM8978异常
//以下为通用设置
WM8978_Write_Reg(1,0X1B); //R1,MICEN设置为1(MIC使能),BIASEN设置为1(模拟器工作),VMIDSEL[1:0]设置为:11(5K)
WM8978_Write_Reg(2,0X1B0); //R2,ROUT1,LOUT1输出使能(耳机可以工作),BOOSTENR,BOOSTENL使能
WM8978_Write_Reg(3,0X6C); //R3,LOUT2,ROUT2输出使能(喇叭工作),RMIX,LMIX使能
WM8978_Write_Reg(6,0); //R6,MCLK由外部提供
WM8978_Write_Reg(43,1<<4); //R43,INVROUT2反向,驱动喇叭
WM8978_Write_Reg(47,1<<8); //R47设置,PGABOOSTL,左通道MIC获得20倍增益
WM8978_Write_Reg(48,1<<8); //R48设置,PGABOOSTR,右通道MIC获得20倍增益
WM8978_Write_Reg(49,1<<1); //R49,TSDEN,开启过热保护
WM8978_Write_Reg(10,1<<3); //R10,SOFTMUTE关闭,128x采样,最佳SNR
WM8978_Write_Reg(14,1<<3); //R14,ADC 128x采样率
return 0;
}
[/mw_shl_code]
[mw_shl_code=c,true]void I2S2_Init(u16 I2S_Standard,u16 I2S_Mode,u16 I2S_Clock_Polarity,u16 I2S_DataFormat)
{
I2S_InitTypeDef I2S_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);//使能SPI2时钟
// RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2,ENABLE); //复位SPI2
// RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2,DISABLE);//结束复位
SPI_I2S_DeInit(SPI2); //效果同上面两行代码
I2S_InitStructure.I2S_Mode=I2S_Mode;//IIS模式
I2S_InitStructure.I2S_Standard=I2S_Standard;//IIS标准
I2S_InitStructure.I2S_DataFormat=I2S_DataFormat;//IIS数据长度
I2S_InitStructure.I2S_MCLKOutput=I2S_MCLKOutput_Disable;//主时钟输出禁止
I2S_InitStructure.I2S_AudioFreq=I2S_AudioFreq_Default;//IIS频率设置
I2S_InitStructure.I2S_CPOL=I2S_Clock_Polarity;//空闲状态时钟电平
I2S_Init(SPI2,&I2S_InitStructure);//初始化IIS
NVIC_InitStructure.NVIC_IRQChannel =DMA1_Channel4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;//抢占优先级0
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;//子优先级0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能外部中断通道
NVIC_Init(&NVIC_InitStructure);//配置
// SPI_I2S_DMACmd(SPI2,SPI_I2S_DMAReq_Tx,ENABLE);//SPI2 TX DMA请求使能.
// I2S_Cmd(SPI2,ENABLE);//SPI2 I2S EN使能.
} [/mw_shl_code]
[mw_shl_code=c,true]void I2S2_TX_DMA_Init(u8* buf0,u8 *buf1,u16 num)
{
// NVIC_InitTypeDef NVIC_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);//DMA1时钟使能
DMA_DeInit(DMA1_Channel4); //将DMA1的通道4寄存器重设为缺省值
DMA_Cmd(DMA1_Channel4, DISABLE ); //关闭DMA1 通道4
/* 配置 DMA Stream */
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&SPI2->DR);//外设地址为 u32)&SPI2->DR
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)buf0;//DMA 存储器0地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;//存储器到外设模式
DMA_InitStructure.DMA_BufferSize = num;//数据传输量
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设非增量模式
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//存储器增量模式
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//外设数据长度:16位
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//存储器数据长度:16位
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;// 使用循环模式
DMA_InitStructure.DMA_Priority = DMA_Priority_High;//高优先级
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //DMA通道x没有设置为内存到内存传输
DMA_Init(DMA1_Channel4, &DMA_InitStructure);//初始化DMA Channel4
// DMA_Cmd(DMA1_Channel4,ENABLE);
SPI_I2S_DMACmd(SPI2,SPI_I2S_DMAReq_Tx,ENABLE);//SPI2 TX DMA请求使能.
I2S_Cmd(SPI2,ENABLE);//SPI2 I2S EN使能.
DMA_ITConfig(DMA1_Channel4,DMA_IT_TC,ENABLE);//开启传输完成中断
// NVIC_InitStructure.NVIC_IRQChannel =DMA1_Channel4_IRQn;
// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;//抢占优先级0
// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;//子优先级0
// NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能外部中断通道
// NVIC_Init(&NVIC_InitStructure);//配置
} [/mw_shl_code]
还有就是I2S的采样率这样设置对不对?
[mw_shl_code=c,true]const u16 I2S_PSC_TBL[][3]=
{
{800 ,17,1}, //8Khz采样率
{1102,13,0}, //11.025Khz采样率
{1600, 9,0}, //16Khz采样率
{2205, 6,1}, //22.05Khz采样率
{3200, 4,1}, //32Khz采样率
{4410, 3,0}, //44.1Khz采样率
{4800, 3,0}, //48Khz采样率
{9600, 2,0}, //96Khz采样率
};
//设置IIS的采样率(@MCKEN)
//samplerate:采样率,单位:Hz
//返回值:0,设置成功;1,无法设置.
u8 I2S2_SampleRate_Set(u32 samplerate)
{
u8 i=0;
u32 tempreg=0;
samplerate/=10;//缩小10倍
for(i=0;i<(sizeof(I2S_PSC_TBL)/7);i++)//看看该采样率是否可以支持
{
if(samplerate==I2S_PSC_TBL[0])break;
}
// RCC_PLLI2SCmd(DISABLE);//先关闭PLLI2S
if(i==(sizeof(I2S_PSC_TBL)/10))return 1;//搜遍了也找不到
// RCC_PLLI2SConfig((u32)I2S_PSC_TBL[1],(u32)I2S_PSC_TBL[2]);//设置I2SxCLK的频率(x=2) 设置PLLI2SN PLLI2SR
RCC_HSEConfig(RCC_HSE_ON);
tempreg=I2S_PSC_TBL[1]<<0; //设置I2SDIV
tempreg|=I2S_PSC_TBL[2]<<8; //设置ODD位
tempreg|=1<<9; //使能MCKOE位,输出MCK
SPI2->I2SPR=tempreg; //设置I2SPR寄存器
return 0;
}
[/mw_shl_code]
在播放MP3数据时开启DMA,但是一直进入不了DMA中断?不知道怎么回事,求大神指教!在DMA中断里设置了双缓冲。
[mw_shl_code=c,true]//DMA1_Channel4中断服务函数
void DMA1_Channel4_IRQHandler(void)
{
if(DMA_GetITStatus(DMA1_IT_TC4)==SET)////DMA1_Channel4,传输完成标志
{
LED0=0;
DMA_Cmd(DMA1_Channel4,DISABLE);
// if(mp3witchbuf==0)
if((DMA1_Channel4->CMAR)==((u32)audiodev.i2sbuf1))
DMA1_Channel4->CMAR=(u32)audiodev.i2sbuf2;
else
DMA1_Channel4->CMAR=(u32)audiodev.i2sbuf1;
DMA_Cmd(DMA1_Channel4,ENABLE);
DMA_ClearITPendingBit(DMA1_IT_TC4);
i2s_tx_callback(); //执行回调函数,读取数据等操作在这里面处理
}
} [/mw_shl_code]
|
|