stm32f103rct6的I2S连接wm8978使用DMA发送进不了中断

2019-07-20 23:42发布

#include        "i2s.h"
#include        "delay.h"

const        u16        I2S_PSC_TBL[][3]=
{
        {800 ,140,1},                //8Khz采样率
        {1102,13,0},                //11.025Khz采样率
        {1600,9,0},                //16Khz采样率
        {2205,6,1},                //22.05Khz采样率
        {3200,9,0},                //32Khz采样率
        {4410,25,1},                //44.1Khz采样率
        {4800,3,0},                //48Khz采样率
        {9600,2,0},          //96Khz采样率
};


void I2S2_Init(void)
{
        //管脚已经初始化了
        RCC->APB1ENR|=1<<14;
        RCC->APB1RSTR|=1<<14;        //复位SPI2
        RCC->APB1RSTR&=~(1<<14);//结束复位  
        SPI2->I2SCFGR=0;                //全部设置为0
        SPI2->I2SPR=0X02;                //分频寄存器为默认值
        SPI2->I2SCFGR|=1<<11;        //选择:I2S模式
        SPI2->I2SCFGR|=(u16)2<<8;//I2S工作模式设置
        SPI2->I2SCFGR|=0<<4;                //I2S标准设置
        SPI2->I2SCFGR|=1<<3;                //空闲时钟电平设置
        SPI2->I2SCFGR|=1<<0;                //32位声道长度
        SPI2->I2SCFGR|=0<<1;        //I2S标准设置
        SPI2->CR2|=1<<1;                        //SPI2 TX DMA请求使能.       
        SPI2->I2SCFGR|=1<<10;                //SPI2 I2S EN使能.
       
}

u8 I2S2_SampleRate_Set(u32 samplerate)
{
        u8 i=0;
        u32 tempreg=0;
        samplerate/=10;//缩小10倍   
        for(i=0;i<(sizeof(I2S_PSC_TBL)/6);i++)//看看改采样率是否可以支持
        {
                if(samplerate==I2S_PSC_TBL[i][0])break;
        }
        if(i==(sizeof(I2S_PSC_TBL)/6))return 1;//搜遍了也找不到
        SPI2->I2SCFGR&=~(1<<10);                //关闭I2S
        tempreg=I2S_PSC_TBL[i][1]<<0;        //设置I2SDIV
        tempreg|=I2S_PSC_TBL[i][2]<<8;        //设置ODD位
        tempreg|=1<<9;                                        //使能MCKOE位,输出MCK
        SPI2->I2SPR=tempreg;                        //设置I2SPR寄存器
        return 0;
}


void I2S2_TX_DMA_Init(u8* buf0,u16 num)
{
        RCC->AHBENR|=1<<0;
        delay_ms(10);
        DMA1->IFCR&=~(0xf<<16);
        DMA1->ISR=0x0;
       
        DMA1_Channel5->CPAR=(u32)&SPI2->DR;
        DMA1_Channel5->CMAR=(u32)buf0;
        DMA1_Channel5->CNDTR=num;
        DMA1_Channel5->CCR=0;
        DMA1_Channel5->CCR|=1<<4;
        DMA1_Channel5->CCR|=0<<5;
        DMA1_Channel5->CCR|=1<<7;
        DMA1_Channel5->CCR|=0<<6;
        DMA1_Channel5->CCR|=1<<8;
        DMA1_Channel5->CCR|=1<<10;
        DMA1_Channel5->CCR|=2<<12;
        DMA1_Channel5->CCR|=0<<14;
        DMA1_Channel5->CCR|=1<<1;
       
        MY_NVIC_Init(0,0,DMA1_Channel5_IRQn,2);
}

void (*i2s_tx_callback)(void);        //TX回调函数




//I2S开始播放
void I2S_Play_Start(void)
{             
        DMA1_Channel5->CCR|=1<<0;                //开启DMA TX传输                 
}
//关闭I2S播放
void I2S_Play_Stop(void)
{            
        DMA1_Channel5->CCR&=~(1<<0);        //结束播放                  
}


void DMA1_Channel5_IRQHandler(void)
{

                GPIOD->ODR&=~(1<<2);
}


===========================================================
#include "sys.h"
#include "usart.h"               
#include "delay.h"         
#include "led.h"
#include "key.h"
#include "myiic.h"
#include "wm8978.h"
#include "wavplay.h"
#include "spi.h"
#include "sdcard.h"
#include "ff.h"
#include "i2s.h"
#include "audioplay.h"
#include "malloc.h"


FATFS        fs;       
FIL                fp;
__wavctrl wavctr;                //WAV控制结构体
#define I2S_TX_DMA_BUF    50       

void play_song(void)
{
        u8 *i2sbuf1;
        u8 *i2sbuf2;
        u8 res;
        u32 bread;
        WM8978_ADDA_Cfg(1,0);        //开启DAC
        WM8978_Input_Cfg(0,0,0);//关闭输入通道
        WM8978_Output_Cfg(1,0);        //开启DAC输出   
        wav_decode_init((u8 *)"0:/MUSIC/奕跑青春.wav",&wavctr);
        WM8978_I2S_Cfg(2,0);        //飞利浦标准,16位数据长度
        //需要设置相应DMA的通道
        i2sbuf1=mymalloc(I2S_TX_DMA_BUF);
        i2sbuf2=mymalloc(I2S_TX_DMA_BUF);
        //打开文件
        res=f_open(&fp,(TCHAR*)"0:/MUSIC/奕跑青春.wav",FA_READ);        //打开文件
        if(1==res)
        {
                printf("文件0:/MUSIC/奕跑青春.wav打开失败 ");
        }
        f_lseek(&fp, wavctr.datastart);                //跳过文件头
        f_read(&fp,i2sbuf1,I2S_TX_DMA_BUF,(UINT*)&bread);//16bit音频,直接读取数据  
        I2S_Play_Stop();
        I2S2_TX_DMA_Init(i2sbuf1,I2S_TX_DMA_BUF/2);
        I2S2_Init();                //飞利浦标准,主机发送,时钟低电平有效,16位扩展帧长度
        I2S2_SampleRate_Set(wavctr.samplerate);//设置采样率
        I2S_Play_Start();
//        GPIOD->ODR&=~(1<<2);
        f_close(&fp);
        myfree(i2sbuf1);
        myfree(i2sbuf2);
}
int main(void)
{               
        u8 res;
        Stm32_Clock_Init(9);        //系统时钟设置
        delay_init(72);                          //延时初始化
        uart_init(72,9600);         //串口初始化为9600
        led_init();
        key_init();
        res=WM8978_Init();
        printf("res is %d ",res);
        WM8978_HPvol_Set(40,40);        //耳机音量设置
        WM8978_SPKvol_Set(55);                //喇叭音量设置
        while(SD_Initialize())//检测不到SD卡
        {
                printf("SD Card Error!");
                delay_ms(500);                                       
                printf("Please Check! ");
                delay_ms(500);
        }         
        res=f_mount (&fs,"0:",1);
        if(0==res)
        {
                printf("the fmount sucssful ");
        }       
       
        play_song();
       
       
  while(1)
        {

        }         
}

在此向各位看客讨教,或者相互讨论,我不知道是不是我的配置哪出问题了,感觉DMA没有工作。

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
2条回答
sina
1楼-- · 2019-07-21 02:16
其实我之前,使用DMA传输数据到串口,是可以看到数据的,并且进入中断了(通过点亮led灯判断)
渡渡
2楼-- · 2019-07-21 06:13
楼主有工程吗,我是把F4上面的一直到F1 上,做个音频播放器,遇到麻烦了

一周热门 更多>