硬汉嵌入式论坛

 找回密码
 立即注册
查看: 467|回复: 1
收起左侧

[技术讨论] STM32F407定时器触发DMA传输FSMC数据失败问题

[复制链接]

1

主题

3

回帖

6

积分

新手上路

积分
6
发表于 2023-11-1 15:45:24 | 显示全部楼层 |阅读模式
#include "stm32f4xx.h"
#include "usart.h"
#include "delay.h"


#define Bank1_SRAM3_ADDR    ((uint32_t)0x68000000)//nor/psram第三块数据的地址

#define BUFFER_SIZE      200
uint16_t Buffer[BUFFER_SIZE]={0};



//config DMA for FSMC
void DMA_Config(void)
{
    DMA_InitTypeDef  DMA_InitStructure;
        /*时钟使能 */   
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
   
    DMA_InitStructure.DMA_Channel = DMA_Channel_7;                                                              //通道选择
    DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)Bank1_SRAM3_ADDR;                 
    DMA_InitStructure.DMA_Memory0BaseAddr =(u32)Buffer;                                                      //实际上只有后16位有效
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;                                                        //内存到内存
  DMA_InitStructure.DMA_BufferSize = BUFFER_SIZE;                                                                //数据传输量
  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_Normal;                                                               //使用循环模式
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;                                                        //高等优先级
  DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;                                         
  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;                                        //存储器突发单次传输
  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;                        //外设突发单次传输
   
    DMA_Init(DMA2_Stream1, &DMA_InitStructure);   
   
                //双缓冲模式设置
//                DMA_DoubleBufferModeConfig(DMA2_Stream0,(uint32_t)(u16 *)(ADC1ConvertedValue_b),DMA_Memory_1);    //DMA_Memory_0首先被传输
//                DMA_DoubleBufferModeCmd(DMA2_Stream0,ENABLE);
   
  DMA_Cmd(DMA2_Stream1, ENABLE);                                                                                                //将外部采集的ADC数值放到DMA数字流里面   
}





//初始化lcd
void FSMC_Init(void)
{                     
  GPIO_InitTypeDef  GPIO_InitStructure;
    FSMC_NORSRAMInitTypeDef  FSMC_NORSRAMInitStructure;//FSMC初始化
  FSMC_NORSRAMTimingInitTypeDef  readWriteTiming;
    FSMC_NORSRAMTimingInitTypeDef  writeTiming;
   
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOE, ENABLE);//使能PD,PE,
  RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FSMC,ENABLE);//使能FSMC时钟  
   
  GPIO_InitStructure.GPIO_Pin = (3<<0)|(3<<4)|(7<<8)|(3<<14);//PD0,1,4,5,8,9,10,14,15 AF OUT
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用输出
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
  GPIO_Init(GPIOD, &GPIO_InitStructure);//初始化  
   
  GPIO_InitStructure.GPIO_Pin = (0X1FF<<7);//PE7~15,AF OUT
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用输出
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
  GPIO_Init(GPIOE, &GPIO_InitStructure);//初始化  
   
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_11 | GPIO_Pin_6;//FSMC_NE1(lcd_cs) FSMC_A16(lcd_rs) FSMC_RST
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用输出
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
  GPIO_Init(GPIOD, &GPIO_InitStructure);//初始化  
   
  GPIO_PinAFConfig(GPIOD,GPIO_PinSource0,GPIO_AF_FSMC);//D2
  GPIO_PinAFConfig(GPIOD,GPIO_PinSource1,GPIO_AF_FSMC);//D3
  GPIO_PinAFConfig(GPIOD,GPIO_PinSource4,GPIO_AF_FSMC);//RD
  GPIO_PinAFConfig(GPIOD,GPIO_PinSource5,GPIO_AF_FSMC);//WR
  GPIO_PinAFConfig(GPIOD,GPIO_PinSource8,GPIO_AF_FSMC);//D13
  GPIO_PinAFConfig(GPIOD,GPIO_PinSource9,GPIO_AF_FSMC);//D14
  GPIO_PinAFConfig(GPIOD,GPIO_PinSource10,GPIO_AF_FSMC);//D3
  GPIO_PinAFConfig(GPIOD,GPIO_PinSource14,GPIO_AF_FSMC);//D0
  GPIO_PinAFConfig(GPIOD,GPIO_PinSource15,GPIO_AF_FSMC);//D1
   
  GPIO_PinAFConfig(GPIOE,GPIO_PinSource7,GPIO_AF_FSMC);//D4
  GPIO_PinAFConfig(GPIOE,GPIO_PinSource8,GPIO_AF_FSMC);
  GPIO_PinAFConfig(GPIOE,GPIO_PinSource9,GPIO_AF_FSMC);
  GPIO_PinAFConfig(GPIOE,GPIO_PinSource10,GPIO_AF_FSMC);
  GPIO_PinAFConfig(GPIOE,GPIO_PinSource11,GPIO_AF_FSMC);//D8
  GPIO_PinAFConfig(GPIOE,GPIO_PinSource12,GPIO_AF_FSMC);
  GPIO_PinAFConfig(GPIOE,GPIO_PinSource13,GPIO_AF_FSMC);
  GPIO_PinAFConfig(GPIOE,GPIO_PinSource14,GPIO_AF_FSMC);
  GPIO_PinAFConfig(GPIOE,GPIO_PinSource15,GPIO_AF_FSMC);//D12
   
    GPIO_PinAFConfig(GPIOD,GPIO_PinSource7,GPIO_AF_FSMC);//CS(FSMCNE1)
    GPIO_PinAFConfig(GPIOD,GPIO_PinSource11,GPIO_AF_FSMC);//RS(FSMCA16)
   
  readWriteTiming.FSMC_AddressSetupTime = 0;             //地址建立时间(ADDSET)为16个HCLK 1/168M=》16*6=96ns    //读数据
  readWriteTiming.FSMC_AddressHoldTime = 0x00;         //地址保持时间(ADDHLD)模式A未用到   
  readWriteTiming.FSMC_DataSetupTime = 10;                    //数据保存时间为n个HCLK    =10*6=36ns
  readWriteTiming.FSMC_BusTurnAroundDuration = 0x00;
  readWriteTiming.FSMC_CLKDivision = 0;
  readWriteTiming.FSMC_DataLatency = 0x00;
  readWriteTiming.FSMC_AccessMode = FSMC_AccessMode_A;     //模式A
   
    writeTiming.FSMC_AddressSetupTime =1;                      //地址建立时间(ADDSET)为9个HCLK =54ns //写时序
  writeTiming.FSMC_AddressHoldTime = 0x00;                    //地址保持时间(A        
  writeTiming.FSMC_DataSetupTime = 1;                                //数据保存时间为6ns*9个HCLK=54ns
  writeTiming.FSMC_BusTurnAroundDuration = 0x00;        //总线转换周期
  writeTiming.FSMC_CLKDivision = 0x16;                            //时钟分频因子
  writeTiming.FSMC_DataLatency = 0x00;                            //数据延迟时间,若控制异步存储器,本参数无效
  writeTiming.FSMC_AccessMode = FSMC_AccessMode_A;    //访问模式:模式A

  FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM3;//  这里我们使用FSMC_NE3
  FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable; // 不复用数据地址
  FSMC_NORSRAMInitStructure.FSMC_MemoryType =FSMC_MemoryType_SRAM;// FSMC_MemoryType_SRAM;  //SRAM   
  FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;//存储器数据宽度为16bit   
  FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode =FSMC_BurstAccessMode_Disable;// FSMC_BurstAccessMode_Disable;
  FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
    FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait=FSMC_AsynchronousWait_Disable;
  FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;   
  FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;  
  FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;    //  存储器写使能
  FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;   
  FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Enable; // 读写使用不同的时序
  FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
  FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &readWriteTiming; //读写时序
  FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &writeTiming;  //写时序

  FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);  //初始化FSMC配置

  FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM3, ENABLE);  // 使能FSMC_NE3
}


void TIMx_DMA_Config(u16 arr,u16 psc)
{
    GPIO_InitTypeDef     GPIO_InitStructure;   
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    TIM_OCInitTypeDef      TIM_OCInitStructure;
    NVIC_InitTypeDef         NVIC_InitStructure;

    /*外设时钟*/   
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8,ENABLE);      //TIM8时钟使能   
   
  /*--------------------时基结构体初始化-------------------------*/   
    TIM_TimeBaseStructure.TIM_Period=arr;   //自动重装载值  
    TIM_TimeBaseStructure.TIM_Prescaler=psc;  //定时器分频
    TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; //时钟分频因子
    TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
  TIM_TimeBaseStructure.TIM_RepetitionCounter=0;        // 重复计数器的值,没用到不用管
    TIM_TimeBaseInit(TIM8,&TIM_TimeBaseStructure);//初始化定时器8   
   

    TIM_OC1Init(TIM8, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM8 4OC1
//    /* 使能通道1重载 */
    TIM_OC1PreloadConfig(TIM8,TIM_OCPreload_Enable);  //使能TIM8在CCR1上的预装载寄存器  
   
  DMA_Cmd(DMA2_Stream1, ENABLE);        
    //将外部采集的ADC数值放到DMA数字流里面   
    TIM_Cmd(TIM8, ENABLE);  //使能TIM14   
    /*--------------------定时器触发DMA初始化-------------------*/
    TIM_DMAConfig(TIM8, TIM_DMABase_CCR1, TIM_DMABurstLength_2Bytes );
    TIM_DMACmd(TIM8,TIM_DMA_Update, ENABLE);    //定时器触发DMA请求            
}


////定时器x中断服务函数,
//void TIM8_UP_TIM13_IRQHandler(void)//整个程序是基于定时器中断
//{
//    if(TIM_GetITStatus(TIM8,TIM_IT_Update)==SET) //溢出中断
//    {   
//      
//    }
//    TIM_ClearITPendingBit(TIM8,TIM_IT_Update);  //清除中断标志位
//}



int FSMC_Read(void)
{
    return *(vu16*)(Bank1_SRAM3_ADDR) & 0x03ff;
}

int main(void)
{
    static int i = 0,k=0,n;   
    u16 temp[BUFFER_SIZE];        
   
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
    delay_init(168);                       //初始化延时函数,这部分用了正点原子的代码
    uart_init(115200);                        //初始化串口波特率为115200
   
    delay_ms(1000);

    FSMC_Init();                                    //1配置FSMC   
    TIMx_DMA_Config(1,0);
    DMA_Config();                                    //2配值DMA
   
    delay_ms(1000);
   
    for(i=0; i<BUFFER_SIZE;i++)
    {
        printf("%d\r\n",Buffer[i] & 0x03ff);
    }
   
    while(1);
}


我用F103定时器触发DMA传输GPIO数据是的速度是可控的,但是F4的一直都不行(也是传输GPIO数据),现在换成F407用DMA传输FSMC的数据也不行。难受



回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106745
QQ
发表于 2023-11-1 20:52:52 | 显示全部楼层
这个我有个例子,不过是HAL库的,你看有兴趣参看没,用的是TIM+DMA+FSMC采集的AD7606

https://www.armbbs.cn/forum.php?mod=viewthread&tid=93255

下载 (1).png


回复

使用道具 举报

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

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-3 15:17 , Processed in 0.318750 second(s), 29 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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