OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4658|回复: 2

F103RFT6通过I2S给WM8978发送音频数据,为什么DMA的中断进不了?

[复制链接]

23

主题

73

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
449
金钱
449
注册时间
2016-7-12
在线时间
121 小时
发表于 2016-9-20 14:37:24 | 显示全部楼层 |阅读模式
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]




最佳答案

查看完整内容[请看2#楼]

原来是程序写的不对!
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

23

主题

73

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
449
金钱
449
注册时间
2016-7-12
在线时间
121 小时
 楼主| 发表于 2016-9-20 14:37:25 | 显示全部楼层
原来是程序写的不对!
回复

使用道具 举报

1

主题

4

帖子

0

精华

初级会员

Rank: 2

积分
88
金钱
88
注册时间
2019-7-8
在线时间
39 小时
发表于 2020-11-11 10:40:32 | 显示全部楼层
我现在也遇到和你一样的问题 进入不了DMA的终端 请问楼主是怎么解决的?
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-21 18:13

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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