打印
[STM32F1]

我的VS1003为什么会出现卡顿,调了好久了!

[复制链接]
1382|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
lujin49|  楼主 | 2015-3-11 11:04 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
使用了 DMA方式,整体运行过程很正常,发送数据也正常,就是无规律出现卡顿一下.听起来很不爽,请高手指点一下,我贴出所有的代码
VS1003代码:
#include <stm32f10x.h>
#include <stdio.h>
#include "vs1003.h"
#include "LED.h"
#include "RTL.h"


#define GPIOA_Clr(PIN)                  (GPIOA->BRR = PIN)
#define GPIOA_Set(PIN)                  (GPIOA->BSRR = PIN)
#define WT_DREQ                          while((GPIOC->IDR & VS_DREQ_Pin)==0)
#define SPI_I2S_FLAG_RXNE               ((uint16_t)0x0001)
#define SPI_I2S_FLAG_TXE                ((uint16_t)0x0002)       

#define SPI1_DR   (0x4001300C)

#define SIZE  1024

u8  SrcA[SIZE];
u8  SrcB[SIZE];
u8  up;
u8  dw; //µ±Îª1ʱ±íʾ£¬ÐèÒª¼ÓÔØ

static FILE *fm = NULL;

void VS_DREQ_IRQ(void)
{
       
        AFIO->EXTICR[0] &=~0x0000F000;
        AFIO->EXTICR[0] |= 0x00002000;
       
        NVIC->IP[9] = 0x40;
        NVIC->ISER[0] |= 0x0200;
       
        EXTI->IMR &= ~0x00000008;
  EXTI->EMR &= ~0x00000008;       
        EXTI->IMR |=  0x00000008;       
        EXTI->FTSR &= ~0x00000008;
        EXTI->RTSR |= 0x00000008; //ÉÏÉýÑØ´¥·¢
}

//ÍⲿÖжϴ¦Àíº¯Êý
void EXTI3_IRQHandler(void)
{
        //LED_TURN(2);
        EXTI->PR =0x00000008;
}



//ÕâÊÇ´ÖÂÔµÄÑÓʱ£¬ÏµÍ³Ê±ÖÓΪ72M
static void delay_ms(u16 time)
{     
   u16 i=0;   
   while(time--)
   {
      i=8000;  
      while(i--) ;     
   }
}




void VS_SPI_SetSpeed_Low(void)
{
//SPI1->CR1 &=~ (uint16_t)0x0040;               
SPI1->CR1 |= (SPI1->CR1 & (uint16_t)0xFFC7)|((uint16_t)0x0038);
SPI1->CR1 |= (uint16_t)0x0040;
}


void VS_SPI_SetSpeed_Hig(void)
{
SPI1->CR1 |= (SPI1->CR1 & (uint16_t)0xFFC7);//|((uint16_t)0x0010);
SPI1->CR1 |= (uint16_t)0x0040;
}


void VS_GPIO_Init(void)
{
        RCC->APB2ENR |= 0x00001015;       
        GPIOA->CRL &=~0xFFFFF00F;
        GPIOA->CRL |= 0xBBB33003;
        GPIOC->CRL &=~0x0000F000;
        GPIOC->CRL |= 0x00008000;
        GPIOC->BRR |= 0x00000008;
}

void VS_SPI_Init(void)
{
        SPI1->CR1 = 0x0374;
        SPI1->CR2 = 0x0000;
        SPI1->CRCPR = 0x0007;
        SPI1->I2SCFGR = 0x0000;
}


void VS_DMA_M2P_Init(void)
{
        RCC->AHBENR |= 0x00000001;
        DMA1->IFCR = 0x00000F00;
        NVIC->IP[13] = 0x40;
        NVIC->ISER[0] |= 0x2000;       
       
        up = 0;
        dw = 0;
        /*
        ÓÅÏȼ¶£º¸ß
        ÄÚ´æÓëÍâÉè¿í¶È 8λ
        ÄÚ´æµØÖ·£º×ÔÔö
        ÍâÉèµØÖ·£º²»±ä
        ·½Ïò£ºÄÚ´æµ½ÍâÉè
        Öжϣº´«ÊäÍê³ÉÖжÏ
        Æô¶¯£º·ñ
        */
  DMA_CH->CCR = 0x00002092;
        DMA_CH->CNDTR = 32;//ÿ´Î´«Êä 32×Ö½Ú
        DMA_CH->CPAR = (uint32_t)SPI1_DR;
        DMA_CH->CMAR = (uint32_t)&SrcA[0];       
       
}

void VS_DMA_M2P_Start(char* filename)
{               
        int ok;
        ok=finit("M");
        if(ok==0)
        {
    fm = fopen((const char*)filename,"r");
    if(fm!=NULL)
                {
                        fread((void *)SrcA,1,SIZE,fm);
                        fread((void *)SrcB,1,SIZE,fm);
    }                       
  }
       
        GPIOA_Set(VS_XCS_Pin);
        GPIOA_Clr(VS_XDCS_Pin);
        DMA1->IFCR = 0x00000F00;
        DMA_CH->CNDTR = 32;
        DMA_CH->CCR |= 0x00000001;
        SPI1->CR2 |= 0x0002;

}




void VS_DMA_M2P_Stop(void)
{
        DMA_CH->CCR &=~ 0x00000001;
        DMA1->IFCR = 0x00000F00;
        //while((SPI1->SR & SPI_I2S_FLAG_TXE) == 0);
        //while((SPI1->SR & 0x0080)>0);//´«ÊäÈ«²¿Íê³É
}

void VS_DMA_M2P_Continue(void)
{
//        GPIOA_Set(VS_XCS_Pin);
//        GPIOA_Clr(VS_XDCS_Pin);
        DMA_CH->CNDTR = 32;
        DMA_CH->CCR |= 0x00000001;
}


void DMA1_Channel3_IRQHandler(void)//SPI_DMA´«ÊäÍê³Éºó
{
        static u16 addr=0;
        static u32 sp=1;
        VS_DMA_M2P_Stop();

  addr+=32;
        if(addr==SIZE*2)
        {
                addr = 0;
                dw = sp++;
                LED_ON(4);
  }
        if(addr==SIZE)
        {
                up=sp++;
                LED_ON(3);
  }

        if(addr<SIZE)
          DMA_CH->CMAR = (uint32_t)&SrcA[addr];
       
        if(addr>=SIZE)
          DMA_CH->CMAR = (uint32_t)&SrcB[addr-SIZE];               
       
if((up ==0 && addr<SIZE ) || (dw == 0 && addr>=SIZE ))
        if((GPIOC->IDR & VS_DREQ_Pin)>0)
                {
                         VS_DMA_M2P_Continue();
                }

}





void VS_Load_Data(DataItem im)
{
        LED_TURN(2);
       
        if(im == I_Up)
        {fread((void *)SrcA,1,SIZE,fm);
                LED_OFF(3);
          up=0;
        }
  
        if(im == I_Dw)
        {fread((void *)SrcB,1,SIZE,fm);
                LED_OFF(4);
          dw=0;
        }
       
        if(feof(fm)){rewind(fm);}
       
       
       
}






void VS1003_CMD_Write_32b(u8 address,u16 data)
{
   WT_DREQ;         
         GPIOA_Set(VS_XDCS_Pin);
         GPIOA_Clr(VS_XCS_Pin);
       
   SPI_ReadWrite_Byte(0x02);//дÃüÁî
         SPI_ReadWrite_Byte(address);//дÃüÁî
         SPI_ReadWrite_Byte((u8)(data>>8));//дÃüÁî
         SPI_ReadWrite_Byte((u8)data);//дÃüÁî
         
   GPIOA_Set(VS_XCS_Pin);
}



void VS1003_SoftReset(void)
{
        VS1003_CMD_Write_32b(VS_CMD_MODE,VS_SM_SDINEW|VS_SM_RESET);
        delay_ms(3);
        WT_DREQ;
        delay_ms(1);
        GPIOA_Clr(VS_XDCS_Pin);
        GPIOA_Clr(VS_XCS_Pin);
        SPI_ReadWrite_Byte(0xFF);
        SPI_ReadWrite_Byte(0xFF);
        SPI_ReadWrite_Byte(0xFF);
        SPI_ReadWrite_Byte(0xFF);
       
        GPIOA_Set(VS_XDCS_Pin);

}


void VS1003_Reset(void)
{
        GPIOA_Clr(VS_RST_Pin);
        delay_ms(100);
        SPI_ReadWrite_Byte(0xFF);
       
        GPIOA_Set(VS_XCS_Pin);
        GPIOA_Set(VS_XDCS_Pin);
        GPIOA_Set(VS_RST_Pin);
       
        delay_ms(100);
        WT_DREQ;
       
        delay_ms(100);
        VS1003_CMD_Write_32b(VS_CMD_MODE,VS_SM_SDINEW|VS_SM_RESET);//·¢Ë͸´Î»ÃüÁî  02 00 08 04
        delay_ms(5);
        WT_DREQ;
  VS1003_SoftReset();//Èí¼þ¸´Î»Ò»´Î
       
}

//³õʼ»¯vs1003
void VS1003_Init(void)
{
        VS_GPIO_Init();
        VS_SPI_Init();

        VS_DMA_M2P_Init();
       
        //VS_DREQ_IRQ();
       
        //VS_SPI_SetSpeed_Low();
       
        VS1003_Reset();//¸´Î»Ò»´Î,°üÀ¨Ó²¸´Î» ÓëÈí¼þ¸´Î»,¸÷Ò»´Î       
        VS1003_CMD_Write_32b(VS_CMD_MODE,0x0800);
        VS1003_CMD_Write_32b(VS_CMD_CLOCKF,0x9800);
        VS1003_CMD_Write_32b(VS_CMD_AUDATA,0xBB81);
        VS1003_CMD_Write_32b(VS_CMD_BASS,0x0055);
        VS1003_CMD_Write_32b(VS_CMD_VOL,0x0000);
       
        //VS_SPI_SetSpeed_Hig();
}



u8 SPI_ReadWrite_Byte(u8 data)
{
  while((SPI1->SR & SPI_I2S_FLAG_TXE) == 0);       
        SPI1->DR = data;
        while((SPI1->SR & SPI_I2S_FLAG_RXNE) == 0);       
  return SPI1->DR;
}





u16 VS1003_CMD_Read_32b(u8 address)
{
        u8  data1=0;
        u8  data2=0;
        WT_DREQ;
        GPIOA_Set(VS_XDCS_Pin);
        GPIOA_Clr(VS_XCS_Pin);
       
   SPI_ReadWrite_Byte(0x03);//¶ÁÃüÁî
         SPI_ReadWrite_Byte(address);//µØ
         data1 = SPI_ReadWrite_Byte(0xAA);//дÃüÁî
         data2 = SPI_ReadWrite_Byte(0xAA);//дÃüÁî
               
        GPIOA_Set(VS_XCS_Pin);         
        return ((u16)data1<<8)|((u16)data2);
}

void VS1003_DATA_Write_1Byte(u8 dat)
{
        GPIOA_Clr(VS_XDCS_Pin);
        GPIOA_Set(VS_XCS_Pin);

        SPI_ReadWrite_Byte(dat);
  GPIOA_Set(VS_XDCS_Pin);          
}



//Ò»´Î·¢ËÍ32×Ö½Ú£¬²»ÊÇ32룬ÇмÇ
void VS1003_DATA_Write_32Byte(u8 *buf)
{
        u8 i;
        GPIOA_Set(VS_XCS_Pin);
        GPIOA_Clr(VS_XDCS_Pin);

        for(i=0;i<32;i++)
        {
                SPI_ReadWrite_Byte(*(buf+i));
  }
        GPIOA_Set(VS_XDCS_Pin);
}


u8 VS_DREQ_Hig(void)
{
        return ((GPIOC->IDR & VS_DREQ_Pin)==0)?0:1;
}


main函数代码

#include "stm32f10x.h"
#include "printf.h" //¼ÓÔØ´ËÍ·Îļþ
#include "SPI.h"
#include <string.h>
#include <stdio.h>
#include "LED.h"
#include "vs1003.h"
#include "RTL.h"



extern u8  up;
extern u8  dw; //µ±Îª1ʱ±íʾ£¬ÐèÒª¼ÓÔØ

int main(void)
{

  USART_Init();
        SPI_Init_ALL();
        VS1003_Init();
        LED_Init();
       
        VS_DMA_M2P_Start("1.mp3");
       
        while(1)
        {

      if((up>0&&dw==0)||(up>0&&dw>0&&up<dw))
                        {
                                VS_Load_Data(I_Up);
      }
                       
                        if((dw>0&&up==0)||(dw>0&&up>0&&dw<up))
                        {
                                VS_Load_Data(I_Dw);
      }       
                       
                       
                        if((GPIOC->IDR & VS_DREQ_Pin)>0){
                      if((DMA_CH->CCR & 0x00000001) ==0)
                                                {
                                                 VS_DMA_M2P_Continue();
                                                }
                                }
               
  }
       
       
}

现在可以播放SD卡上的文件,就是在播放时 偶尔出现卡顿!
需要什么测试数据,波形什么的,尽管给我说,我做给大家看!

---如果有什么好的建议也是可以的
沙发
airwill| | 2015-3-11 14:36 | 只看该作者
支持一下新人啊
我估计是读卡的问题, 或者读卡函数里有长时间执行的函数,占用了太多时间. 而你的 SPI 读写也是读写中傻等 SPI 通讯结束, 浪费了好多时间.
得好好动动脑筋优化一下, 比如 SPI 通讯可否放在中断里以节省时间.

使用特权

评论回复
板凳
lujin49|  楼主 | 2015-3-11 18:33 | 只看该作者
哦,对不起,代码下半部分,是原来的 不使用DMA时的代码 现在使用DMA后,不再使用下面的代码了

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

4

帖子

0

粉丝