野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 11299|回复: 2

逻辑分析仪出来波形不正确,有没有大佬有时间帮忙看一下代码

[复制链接]
发表于 2018-10-15 17:34:47 | 显示全部楼层 |阅读模式
本帖最后由 你说冬瓜是冬瓜 于 2018-10-15 17:46 编辑

功能是存储器通过DMA双缓冲到SAI SAI主发送模式  逻辑分析仪 波形不对
[mw_shl_code=c,true]#include "stm32f4xx.h"
#include "bsp_sai.h"
#include "bsp_SysTick.h"
#include "bsp_led.h"


extern uint16_t SendBuff0[SENDBUFF_SIZE];
extern uint16_t SendBuff1[SENDBUFF_SIZE];
extern uint8_t Isread;           /* DMA传输完成标志 */
extern uint8_t bufflag;          /* 数据缓存区选择标志 */

/**
  * @brief  主函数
  * @param  无
  * @retval 无
  */
int main(void)
{
        uint32_t j;
        uint32_t i;
         
        SAI_stop();
        SAI_GPIO_Config();
        SAI_Config();
  SAI_DMA_Config();
  
               
        SAI_stop();
        
        bufflag=0;
        Isread=0;
        
        
                                
        while(1)
        {
                for(i=0;i<SENDBUFF_SIZE;i++)
                {
                        SendBuff0=0xABCD;
                }
                for(j=0;j<SENDBUFF_SIZE;j++)
                {
                        SendBuff1[j]=0x5A5A;
                }
                SAI_send_start();
               
                DMA_ITConfig(DEBUG_SAI1_A_DMA_STREAM,DMA_IT_TC,DISABLE);//开启传输完成中断

        }
}
#include "stm32f4xx.h"
#include "bsp_sai.h"
#include "bsp_led.h"


uint16_t SendBuff0[SENDBUFF_SIZE];
uint16_t SendBuff1[SENDBUFF_SIZE];



uint8_t Isread=0;           /* DMA传输完成标志 */
uint8_t bufflag=0;          /* 数据缓存区选择标志 */




void SAI_GPIO_Config(void)
{
        
        GPIO_InitTypeDef          GPIO_InitStructure;
        
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE,ENABLE);
        //RCC_APB2PeriphClockCmd(RCC_APB2Periph_SAI1,ENABLE);
               
        
  //GPIO口配置
  
        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF;      //复用
        GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;    //推挽
        GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;      //上拉
        GPIO_InitStructure.GPIO_Speed= GPIO_High_Speed;  //高速  GPIO_Low_Speed   GPIO_High_Speed
        GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2;
        GPIO_Init(GPIOE, &GPIO_InitStructure);        
        
        GPIO_InitStructure.GPIO_Pin=GPIO_Pin_3;
        GPIO_Init(GPIOE, &GPIO_InitStructure);        
        
        GPIO_InitStructure.GPIO_Pin=GPIO_Pin_4;
        GPIO_Init(GPIOE, &GPIO_InitStructure);        
        
        GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;
        GPIO_Init(GPIOE, &GPIO_InitStructure);        
        
        GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;
        GPIO_Init(GPIOE, &GPIO_InitStructure);        
        
        GPIO_PinAFConfig(GPIOE,GPIO_PinSource2,GPIO_AF_SAI1);
        GPIO_PinAFConfig(GPIOE,GPIO_PinSource3,GPIO_AF_SAI1);
        GPIO_PinAFConfig(GPIOE,GPIO_PinSource4,GPIO_AF_SAI1);
        GPIO_PinAFConfig(GPIOE,GPIO_PinSource5,GPIO_AF_SAI1);
        GPIO_PinAFConfig(GPIOE,GPIO_PinSource6,GPIO_AF_SAI1);        

}        
void SAI_Config(void)
{
        SAI_InitTypeDef           SAI_InitStructure;
        SAI_FrameInitTypeDef      SAI_FrameInitStructure;
        SAI_SlotInitTypeDef       SAI_SlotInitStructure;        
        uint32_t n = 0;
        FlagStatus status = RESET;

//        DMA_Cmd(DEBUG_SAI1_A_DMA_STREAM, DISABLE);       //配置 SAI 模块前,必须禁止 SAI DMA 通道。
/***********************配置SAI和FIFO阈值***********************************/
        RCC_PLLSAIConfig(128,15,3);        

        SAI_DeInit(SAI1);
        
        RCC_SAIBlockACLKConfig(RCC_SAIACLKSource_PLLSAI);
        RCC_PLLSAICmd(ENABLE);
        
        for (n = 0; n < 500; n++)
        {
                status = RCC_GetFlagStatus(RCC_FLAG_PLLSAIRDY);
                if (status == 1)break;
        }
                                
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_SAI1,ENABLE);

        
        SAI_InitStructure.SAI_AudioMode=SAI_Mode_MasterTx;     //主模式发送
        SAI_InitStructure.SAI_Protocol=SAI_Free_Protocol;    //自由协议
        SAI_InitStructure.SAI_DataSize=SAI_DataSize_16b;   //16bit数据
        SAI_InitStructure.SAI_FirstBit=SAI_FirstBit_MSB;  //从高位开始读
        SAI_InitStructure.SAI_ClockStrobing=SAI_ClockStrobing_FallingEdge;//时钟下降沿有效
        SAI_InitStructure.SAI_Synchro=SAI_Asynchronous;    //音频模块异步
        SAI_InitStructure.SAI_OUTDRIV=SAI_OutputDrive_Enabled;//输出驱动使能
        SAI_InitStructure.SAI_NoDivider=SAI_MasterDivider_Enabled; //主时钟分频器开启
        SAI_InitStructure.SAI_MasterDivider=12;        
        SAI_InitStructure.SAI_FIFOThreshold=SAI_FIFOThreshold_1QuarterFull; //当FIFO没有数据时产生中断  设置FIFO阈值,1/4 FIFO  SAI_Threshold_FIFOEmpty  SAI_FIFOThreshold_1QuarterFull
        
        
        SAI_Init(SAI1_Block_A,&SAI_InitStructure);
        
        //帧配置
        SAI_FrameInitStructure.SAI_FrameLength=128;     //帧长度
        SAI_FrameInitStructure.SAI_ActiveFrameLength=1;   //帧有效长度为1
        SAI_FrameInitStructure.SAI_FSDefinition=SAI_FS_StartFrame; // 帧同步定义,SOF信号 FS=0
        SAI_FrameInitStructure.SAI_FSPolarity=SAI_FS_ActiveHigh; //FS上升沿有效  SAI_FS_ActiveHigh   SAI_FS_ActiveLow
        SAI_FrameInitStructure.SAI_FSOffset=SAI_FS_BeforeFirstBit;//最后一位使能FS   SAI_FS_BeforeFirstBit   SAI_FS_FirstBit
        
        SAI_FrameInit(SAI1_Block_A,&SAI_FrameInitStructure);
        
        //SAI Block Slot Init
  SAI_SlotInitStructure.SAI_FirstBitOffset=0;   //Specifies the position of first data transfer bit in the slot.This parameter must be a number between 0 and 24.
        SAI_SlotInitStructure.SAI_SlotSize=SAI_SlotSize_16b;//slot大小为16位
        SAI_SlotInitStructure.SAI_SlotNumber=8;          //slot个数为8
        SAI_SlotInitStructure.SAI_SlotActive=SAI_SlotActive_0|SAI_SlotActive_1|SAI_SlotActive_2|SAI_SlotActive_3|SAI_SlotActive_4|SAI_SlotActive_5|SAI_SlotActive_6|SAI_SlotActive_7;

  SAI_SlotInit(SAI1_Block_A,&SAI_SlotInitStructure);
}

/*********************配置SAI DMA通道*************************************/


void SAI_DMA_Config(void)
{
        
        DMA_InitTypeDef           DMA_InitStructure;
        NVIC_InitTypeDef          NVIC_InitStructure;
        
  /*开启DMA时钟*/
         RCC_AHB1PeriphClockCmd(DEBUG_SAI1_A_DMA_CLK, ENABLE);
  
        DMA_DeInit(DEBUG_SAI1_A_DMA_STREAM);
  /* 确保DMA数据流复位完成 */
  while (DMA_GetCmdStatus(DEBUG_SAI1_A_DMA_STREAM) != DISABLE)  {
  }
        
        DMA_ClearITPendingBit(DEBUG_SAI1_A_DMA_STREAM,DMA_IT_FEIF3|DMA_IT_DMEIF3|DMA_IT_TEIF3|DMA_IT_HTIF3|DMA_IT_TCIF3);//清空DMA2_Stream3上所有中断标志

  /*sai1_a 对应dma2,通道0,数据流3*/        
  DMA_InitStructure.DMA_Channel = DEBUG_SAI1_A_DMA_CHANNEL;  
  /*设置DMA源:SAI1_A数据寄存器地址*/
  DMA_InitStructure.DMA_PeripheralBaseAddr = DEBUG_SAI1_A_DR_BASE;         
  /*内存地址(要传输的变量的指针)*/
  DMA_InitStructure.DMA_Memory0BaseAddr =(uint32_t)SendBuff0;
  /*方向:从内存到外设*/               
  DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;        
  /*传输大小DMA_BufferSize=SENDBUFF_SIZE*/        
  DMA_InitStructure.DMA_BufferSize = SENDBUFF_SIZE;
  /*外设地址不增*/            
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  /*内存地址自增*/
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;        
  /*外设数据长度 16位*/        
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
  /*内存数据长度 16位 */
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;        
  /*DMA模式:循环   DMA_Mode_Circular   DMA_Mode_Normal*/
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;         
  /*优先级:高*/        
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;      
  /*禁用FIFO,直接模式   DMA_FIFOMode_Enable     DMA_FIFOMode_Disable*/
  DMA_InitStructure.DMA_FIFOMode =DMA_FIFOMode_Disable;        
  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull;   
  /*存储器突发传输 单次传输*/
  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;   
  /*外设突发传输 单次传输*/
  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;  
  /*配置DMA2的数据流3*/                  
  DMA_Init(DEBUG_SAI1_A_DMA_STREAM, &DMA_InitStructure);
        
        
        
        DMA_DoubleBufferModeConfig(DEBUG_SAI1_A_DMA_STREAM,(uint32_t)SendBuff0,DMA_Memory_0);//双缓冲模式配置
        DMA_DoubleBufferModeConfig(DEBUG_SAI1_A_DMA_STREAM,(uint32_t)SendBuff1,DMA_Memory_1);//双缓冲模式配置

  DMA_DoubleBufferModeCmd(DEBUG_SAI1_A_DMA_STREAM,ENABLE);//双缓冲模式开启

  DMA_ITConfig(DEBUG_SAI1_A_DMA_STREAM,DMA_IT_TC,ENABLE);//开启传输完成中断
        
        SAI_DMACmd(SAI1_Block_A, ENABLE);//SAIA DMA 请求使能
                        
        
        NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream3_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;//抢占优先级1
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;//子优先级1
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能外部中断通道
  NVIC_Init(&NVIC_InitStructure);//配置        

}
/* DMA发送完成中断回调函数 */

void SAIA_DMA_Callback(void)
{
        if(DEBUG_SAI1_A_DMA_STREAM->CR&(1<<19)) //当前使用DMA_Memory_1数据  CT位
        {
                bufflag=0;                       //可以将数据读取到缓冲区0
        }
        else                               //当前使用DMA_Memory_0数据
        {
                bufflag=1;                       //可以将数据读取到缓冲区1
        }
        Isread=1;                          // DMA传输完成标志
        
}
/**
        * @brief  SPIx_TX_DMA_STREAM中断服务函数
        * @param  无
        * @retval 无
        */
void SAIA_DMA_STREAM_IRQFUN(void)
{      
        if(DMA_GetITStatus(DEBUG_SAI1_A_DMA_STREAM, DMA_IT_TCIF3)==SET)//DMA传输完成标志
        {
                DMA_ClearITPendingBit(DEBUG_SAI1_A_DMA_STREAM,DMA_IT_TCIF3);//清DMA传输完成标准
    SAIA_DMA_Callback();        //执行回调函数,读取数据等操作在这里面处理  
        }
}
/*********************禁止SAI DMA通道*************************************/
void SAI_stop(void)
{
        DMA_Cmd(DEBUG_SAI1_A_DMA_STREAM, DISABLE);       //配置 SAI 模块前,必须禁止 SAI DMA 通道。
}

void SAI_send_start(void)
{
         __IO uint32_t    Timeout = TIMEOUT_MAX;
        DMA_Cmd(DEBUG_SAI1_A_DMA_STREAM, ENABLE);       //开启 SAI DMA 通道。
         /* 检测DMA数据流是否传输完成并带有超时检测功能 */
  Timeout = TIMEOUT_MAX;
  while ((DMA_GetFlagStatus(DEBUG_SAI1_A_DMA_STREAM,DMA_FLAG_TCIF3)==DISABLE) && (Timeout-- > 0))
  {
  }
   
  /* 判断是否超时 */
  if (Timeout == 0)
  {
    /* 超时就让程序运行下面循环:RGB彩色灯闪烁 */
    while (1)
    {      
      LED_RED;
      Delay(0xFFFFFF);
      LED_RGBOFF;
      Delay(0xFFFFF);
                }
        }
}[/mw_shl_code]

回复

使用道具 举报

发表于 2018-10-16 08:44:47 | 显示全部楼层
建议使用示波器呢
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-10-16 14:58:31 | 显示全部楼层
Brave000 发表于 2018-10-16 08:44
建议使用示波器呢

还是不对,应该是程序问题
回复 支持 反对

使用道具 举报

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

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-11-27 10:18 , Processed in 0.051664 second(s), 23 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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