OpenEdv-开源电子网

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

SDRAM DMA 到 TIM2->ARR 数据搬移错误

[复制链接]

0

主题

2

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2016-8-1
在线时间
17 小时
发表于 2020-9-24 07:27:37 | 显示全部楼层 |阅读模式
1金钱
本帖最后由 乔布斯 于 2020-9-24 09:26 编辑

芯片是STM32H743,没有启用cache,也没配置mpu
用 DMA1_Stream2,由TIM2 update 触发,更新 tim2->arr 的值,以便在特定的时刻发出pwm脉冲
由于数据较多,数据保存在 SDRAM里面,是32位数据,指定在0xC0000000位置,应该也是4字节对齐了

目前现象是,当数据在stm32自身内存中时,数据搬移正确,波形正常
当数据在SDRAM里面时,搬移后读取 tim2->arr的值,数据错误,在debug模式下,偶尔也能发现有正确数据
当把dma改为memory to memory,地址都递增时,从sdram搬到stm32自身内存,数据是正确的

HAL_DMA_Start_IT(&hdma_tim2_up, (uint32_t) STM32_BUFFER1,(uint32_t)(&(TIM2->ARR)),3200);      //搬移正确
HAL_DMA_Start_IT(&hdma_tim2_up, (uint32_t) SDRAM_BUFFER,(uint32_t)(&(TIM2->ARR)),32000);     //数据不对
HAL_DMA_Start_IT(&hdma_tim2_up, (uint32_t) SDRAM_BUFFER,(uint32_t)(STM32_BUFFER2),32000);   //搬移正确

//数据更新周期约2.5ms,延时5-6mm能间隔取到ARR值

  MyDmaStart(0);

  osDelay(6);
        arr1=TIM2->ARR;A
  osDelay(6);
        arr2=TIM2->ARR;
  osDelay(5);
        arr3=TIM2->ARR;
  osDelay(6);
        arr4=TIM2->ARR;
  osDelay(5);
        arr5=TIM2->ARR;
  osDelay(6);
        arr6=TIM2->ARR;


正常值在 0x00002B00附近,   十进制500到1000
非正常值发现有 0x00A002A4,有时是别的数据,不稳定
debug跟踪,sdram有时也能出正常数据,运行时没发现过正常的


请问,应该从哪些地方入手调试?

SDRAM配置是用的原子的数据,
void MX_FMC_Init(void)
{
  FMC_SDRAM_TimingTypeDef SdramTiming = {0};

  /** Perform the SDRAM1 memory initialization sequence
  */
  hsdram1.Instance = FMC_SDRAM_DEVICE;
  /* hsdram1.Init */
  hsdram1.Init.SDBank = FMC_SDRAM_BANK1;
  hsdram1.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_9;
  hsdram1.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_13;
  hsdram1.Init.MemoryDataWidth = FMC_SDRAM_MEM_BUS_WIDTH_16;
  hsdram1.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4;
  hsdram1.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_2;
  hsdram1.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE;
  hsdram1.Init.SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_2;
  hsdram1.Init.ReadBurst = FMC_SDRAM_RBURST_ENABLE;
  hsdram1.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_0;
  /* SdramTiming */
  SdramTiming.LoadToActiveDelay = 2;
  SdramTiming.ExitSelfRefreshDelay = 8;
  SdramTiming.SelfRefreshTime = 6;
  SdramTiming.RowCycleDelay = 6;
  SdramTiming.WriteRecoveryTime = 5;
  SdramTiming.RPDelay = 2;
  SdramTiming.RCDDelay = 2;

  if (HAL_SDRAM_Init(&hsdram1, &SdramTiming) != HAL_OK)
  {
    Error_Handler( );
  }

}

////////////////////////////////
main中调用  SDRAM_Initialization_Sequence:

  MX_FMC_Init();
  MX_TIM2_Init();
  /* USER CODE BEGIN 2 */
        
  SDRAM_Initialization_Sequence(&hsdram1);
  ValueInit();
        
  /* USER CODE END 2 */

  /* Init scheduler */
  osKernelInitialize();  /* Call init function for freertos objects (in freertos.c) */
  MX_FREERTOS_Init();


///////////////////////////////////////
freertos task 中启动dma并检查数据


void StartTaskLed(void *argument)
{
  /* USER CODE BEGIN StartTaskLed */
  /* Infinite loop */
        osDelay(2000);

  MyDmaStart(0);
  osDelay(6);
        arr1=TIM2->ARR;
  osDelay(6);
        arr2=TIM2->ARR;
  osDelay(5);
        arr3=TIM2->ARR;
  osDelay(6);
        arr4=TIM2->ARR;
  osDelay(5);
        arr5=TIM2->ARR;
  osDelay(6);
        arr6=TIM2->ARR;

  for(;;)
  {







正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165508
金钱
165508
注册时间
2010-12-1
在线时间
2115 小时
发表于 2020-9-25 02:07:50 | 显示全部楼层
你的DMA触发条件是什么?如果是m2m模式,一下就传输完了,你只能得到最后一个值在ARR里面了。。。
回复

使用道具 举报

0

主题

2

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2016-8-1
在线时间
17 小时
 楼主| 发表于 2020-9-26 23:41:19 | 显示全部楼层
SDRAM的参数不对导致的,按照您的参数设置就没问题了,我原来不知道抄了谁的。
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-5-17 04:59

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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