硬汉嵌入式论坛

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

[FMC] STM32H730 FMC无法调通DAC

[复制链接]

9

主题

39

回帖

66

积分

初级会员

积分
66
发表于 2022-6-7 22:59:04 | 显示全部楼层 |阅读模式
最近遇到棘手的问题,用FMC驱动DAC时始终无信号输出,贴图贴代码如下原理图如下
image.png

SRAM_HandleTypeDef hsram2;

/* FMC initialization function */
void MX_FMC_Init(void)
{
  /* USER CODE BEGIN FMC_Init 0 */

  /* USER CODE END FMC_Init 0 */

  FMC_NORSRAM_TimingTypeDef Timing = {0};

  /* USER CODE BEGIN FMC_Init 1 */

  /* USER CODE END FMC_Init 1 */

  /** Perform the SRAM2 memory initialization sequence
  */
  hsram2.Instance = FMC_NORSRAM_DEVICE;
  hsram2.Extended = FMC_NORSRAM_EXTENDED_DEVICE;
  /* hsram2.Init */
  hsram2.Init.NSBank = FMC_NORSRAM_BANK2;
  hsram2.Init.DataAddressMux = FMC_DATA_ADDRESS_MUX_DISABLE;
  hsram2.Init.MemoryType = FMC_MEMORY_TYPE_SRAM;
  hsram2.Init.MemoryDataWidth = FMC_NORSRAM_MEM_BUS_WIDTH_16;
  hsram2.Init.BurstAccessMode = FMC_BURST_ACCESS_MODE_DISABLE;
  hsram2.Init.WaitSignalPolarity = FMC_WAIT_SIGNAL_POLARITY_LOW;
  hsram2.Init.WaitSignalActive = FMC_WAIT_TIMING_BEFORE_WS;
  hsram2.Init.WriteOperation = FMC_WRITE_OPERATION_ENABLE;
  hsram2.Init.WaitSignal = FMC_WAIT_SIGNAL_DISABLE;
  hsram2.Init.ExtendedMode = FMC_EXTENDED_MODE_DISABLE;
  hsram2.Init.AsynchronousWait = FMC_ASYNCHRONOUS_WAIT_DISABLE;
  hsram2.Init.WriteBurst = FMC_WRITE_BURST_DISABLE;
  hsram2.Init.ContinuousClock = FMC_CONTINUOUS_CLOCK_SYNC_ONLY;
  hsram2.Init.WriteFifo = FMC_WRITE_FIFO_ENABLE;
  hsram2.Init.PageSize = FMC_PAGE_SIZE_NONE;
  /* Timing */
  Timing.AddressSetupTime = 5;
  Timing.AddressHoldTime = 15;
  Timing.DataSetupTime = 5;
  Timing.BusTurnAroundDuration = 5;
  Timing.CLKDivision = 16;
  Timing.DataLatency = 17;
  Timing.AccessMode = FMC_ACCESS_MODE_A;
  /* ExtTiming */

  if (HAL_SRAM_Init(&hsram2, &Timing, NULL) != HAL_OK)
  {
    Error_Handler( );
  }

  /* USER CODE BEGIN FMC_Init 2 */

  /* USER CODE END FMC_Init 2 */
}

static uint32_t FMC_Initialized = 0;

static void HAL_FMC_MspInit(void){
  /* USER CODE BEGIN FMC_MspInit 0 */

  /* USER CODE END FMC_MspInit 0 */
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if (FMC_Initialized) {
    return;
  }
  FMC_Initialized = 1;
  RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};

  /** Initializes the peripherals clock
  */
    PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_FMC;
    PeriphClkInitStruct.FmcClockSelection = RCC_FMCCLKSOURCE_D1HCLK;
    if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
    {
      Error_Handler();
    }

  /* Peripheral clock enable */
  __HAL_RCC_FMC_CLK_ENABLE();

  /** FMC GPIO Configuration
  PF0   ------> FMC_A0
  PE7   ------> FMC_D4
  PE8   ------> FMC_D5
  PE9   ------> FMC_D6
  PE10   ------> FMC_D7
  PE11   ------> FMC_D8
  PE12   ------> FMC_D9
  PE13   ------> FMC_D10
  PE14   ------> FMC_D11
  PE15   ------> FMC_D12
  PD8   ------> FMC_D13
  PD9   ------> FMC_D14
  PD10   ------> FMC_D15
  PD14   ------> FMC_D0
  PD15   ------> FMC_D1
  PD0   ------> FMC_D2
  PD1   ------> FMC_D3
  PD4   ------> FMC_NOE
  PD5   ------> FMC_NWE
  PG9   ------> FMC_NE2
  */
  /* GPIO_InitStruct */
  GPIO_InitStruct.Pin = GPIO_PIN_0;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF12_FMC;

  HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);

  /* GPIO_InitStruct */
  GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10
                          |GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14
                          |GPIO_PIN_15;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF12_FMC;

  HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

  /* GPIO_InitStruct */
  GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_14
                          |GPIO_PIN_15|GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_4
                          |GPIO_PIN_5;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF12_FMC;

  HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

  /* GPIO_InitStruct */
  GPIO_InitStruct.Pin = GPIO_PIN_9;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF12_FMC;

  HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);

  /* USER CODE BEGIN FMC_MspInit 1 */

  /* USER CODE END FMC_MspInit 1 */
}

void HAL_SRAM_MspInit(SRAM_HandleTypeDef* sramHandle){
  /* USER CODE BEGIN SRAM_MspInit 0 */

  /* USER CODE END SRAM_MspInit 0 */
  HAL_FMC_MspInit();
  /* USER CODE BEGIN SRAM_MspInit 1 */

  /* USER CODE END SRAM_MspInit 1 */
}

static uint32_t FMC_DeInitialized = 0;

static void HAL_FMC_MspDeInit(void){
  /* USER CODE BEGIN FMC_MspDeInit 0 */

  /* USER CODE END FMC_MspDeInit 0 */
  if (FMC_DeInitialized) {
    return;
  }
  FMC_DeInitialized = 1;
  /* Peripheral clock enable */
  __HAL_RCC_FMC_CLK_DISABLE();

  /** FMC GPIO Configuration
  PF0   ------> FMC_A0
  PE7   ------> FMC_D4
  PE8   ------> FMC_D5
  PE9   ------> FMC_D6
  PE10   ------> FMC_D7
  PE11   ------> FMC_D8
  PE12   ------> FMC_D9
  PE13   ------> FMC_D10
  PE14   ------> FMC_D11
  PE15   ------> FMC_D12
  PD8   ------> FMC_D13
  PD9   ------> FMC_D14
  PD10   ------> FMC_D15
  PD14   ------> FMC_D0
  PD15   ------> FMC_D1
  PD0   ------> FMC_D2
  PD1   ------> FMC_D3
  PD4   ------> FMC_NOE
  PD5   ------> FMC_NWE
  PG9   ------> FMC_NE2
  */

  HAL_GPIO_DeInit(GPIOF, GPIO_PIN_0);

  HAL_GPIO_DeInit(GPIOE, GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10
                          |GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14
                          |GPIO_PIN_15);

  HAL_GPIO_DeInit(GPIOD, GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_14
                          |GPIO_PIN_15|GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_4
                          |GPIO_PIN_5);

  HAL_GPIO_DeInit(GPIOG, GPIO_PIN_9);

  /* USER CODE BEGIN FMC_MspDeInit 1 */

  /* USER CODE END FMC_MspDeInit 1 */
}

void HAL_SRAM_MspDeInit(SRAM_HandleTypeDef* sramHandle){
  /* USER CODE BEGIN SRAM_MspDeInit 0 */

  /* USER CODE END SRAM_MspDeInit 0 */
  HAL_FMC_MspDeInit();
  /* USER CODE BEGIN SRAM_MspDeInit 1 */

  /* USER CODE END SRAM_MspDeInit 1 */
}


使用的是FMC_NE2因此地址范围是0x64000000,用示波器观察到
CS/NWE波形如下
3b544f571c3f92ee54d9e4c379fbca7.jpg
NEW出现了3次波形,不知道为何会这样




回复

使用道具 举报

9

主题

39

回帖

66

积分

初级会员

积分
66
 楼主| 发表于 2022-6-7 23:02:27 | 显示全部楼层
使用的是CUBEMX 生成代码,没有使能MPU、CACHE功能,刚刚接触H7
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106545
QQ
发表于 2022-6-8 10:26:40 | 显示全部楼层

回帖奖励 +1 个金币

最主要的MPU没有设置,要设置FMC操作的地址空间MPU熟悉为Device或者Strongly order。

详情此贴各种案例有说明

STM32H7视频教程第14期:超干货,MPU和Cache实战,一张图了解所有经典配置案例,争取人人都可以玩溜(2022-05-08)
https://www.armbbs.cn/forum.php? ... 2268&fromuid=58
(出处: 硬汉嵌入式论坛)
回复

使用道具 举报

9

主题

39

回帖

66

积分

初级会员

积分
66
 楼主| 发表于 2022-6-8 15:05:01 | 显示全部楼层
eric2013 发表于 2022-6-8 10:26
最主要的MPU没有设置,要设置FMC操作的地址空间MPU熟悉为Device或者Strongly order。

详情此贴各种案例 ...

好的,我试试,如果设置MPU功能,地址空间是如何操作的呢?例如我用到的SRAM地址是0X64000000,设置的MPU地址也设置为64000000吗?这里还不大懂
回复

使用道具 举报

9

主题

39

回帖

66

积分

初级会员

积分
66
 楼主| 发表于 2022-6-8 23:42:44 | 显示全部楼层
eric2013 发表于 2022-6-8 10:26
最主要的MPU没有设置,要设置FMC操作的地址空间MPU熟悉为Device或者Strongly order。

详情此贴各种案例 ...

static void MPU_Config( void )
{
        MPU_Region_InitTypeDef MPU_InitStruct;

        /* 禁止 MPU */
        HAL_MPU_Disable();

        /* 配置AXI SRAM的MPU属性为Non-cacheable  */
        MPU_InitStruct.Enable           = MPU_REGION_ENABLE;
        MPU_InitStruct.BaseAddress      = 0x24000000;
        MPU_InitStruct.Size             = MPU_REGION_SIZE_512KB;
        MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
        MPU_InitStruct.IsBufferable     = MPU_ACCESS_BUFFERABLE;
        MPU_InitStruct.IsCacheable      = MPU_ACCESS_CACHEABLE;
        MPU_InitStruct.IsShareable      = MPU_ACCESS_NOT_SHAREABLE;
        MPU_InitStruct.Number           = MPU_REGION_NUMBER0;
        MPU_InitStruct.TypeExtField     = MPU_TEX_LEVEL1;
        MPU_InitStruct.SubRegionDisable = 0x00;
        MPU_InitStruct.DisableExec      = MPU_INSTRUCTION_ACCESS_ENABLE;
        HAL_MPU_ConfigRegion(&MPU_InitStruct);
       
        /* 配置FMC扩展IO的MPU属性为Device或者Strongly Ordered */
        MPU_InitStruct.Enable           = MPU_REGION_ENABLE;
        MPU_InitStruct.BaseAddress      = 0x60000000;
        MPU_InitStruct.Size             = ARM_MPU_REGION_SIZE_64KB;       
        MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
        MPU_InitStruct.IsBufferable     = MPU_ACCESS_BUFFERABLE;
        MPU_InitStruct.IsCacheable      = MPU_ACCESS_NOT_CACHEABLE;        /* 不能用MPU_ACCESS_CACHEABLE;会出现2次CS、WE信号 */
        MPU_InitStruct.IsShareable      = MPU_ACCESS_NOT_SHAREABLE;
        MPU_InitStruct.Number           = MPU_REGION_NUMBER0;
        MPU_InitStruct.TypeExtField     = MPU_TEX_LEVEL0;
        MPU_InitStruct.SubRegionDisable = 0x00;
        MPU_InitStruct.DisableExec      = MPU_INSTRUCTION_ACCESS_ENABLE;
       
        HAL_MPU_ConfigRegion(&MPU_InitStruct);

        /*使能 MPU */
        HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}



static void CPU_CACHE_Enable(void)
{
  /* Enable I-Cache */
  SCB_EnableICache();

  /* Enable D-Cache */
  SCB_EnableDCache();
}


我按照您给的参考配置了,MPU设置,FMC驱动的DAC还是没有输出,硬汉哥帮我看看。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106545
QQ
发表于 2022-6-9 08:35:34 | 显示全部楼层
image.png
回复

使用道具 举报

9

主题

39

回帖

66

积分

初级会员

积分
66
 楼主| 发表于 2022-6-9 19:10:45 | 显示全部楼层

非常感谢硬汉哥。现在改成0X64000000地址后,直接进入了Hardfault中断了,我的地址线只有一根A0,设置了范围为32B也是一样。不知道是哪里的问题

static void MPU_Config( void )
{
        MPU_Region_InitTypeDef MPU_InitStruct;

        /* 禁止 MPU */
        HAL_MPU_Disable();

        /* 配置AXI SRAM的MPU属性为Non-cacheable  */
        MPU_InitStruct.Enable           = MPU_REGION_ENABLE;
        MPU_InitStruct.BaseAddress      = 0x24000000;
        MPU_InitStruct.Size             = MPU_REGION_SIZE_512KB;
        MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
        MPU_InitStruct.IsBufferable     = MPU_ACCESS_BUFFERABLE;
        MPU_InitStruct.IsCacheable      = MPU_ACCESS_CACHEABLE;
        MPU_InitStruct.IsShareable      = MPU_ACCESS_NOT_SHAREABLE;
        MPU_InitStruct.Number           = MPU_REGION_NUMBER0;
        MPU_InitStruct.TypeExtField     = MPU_TEX_LEVEL1;
        MPU_InitStruct.SubRegionDisable = 0x00;
        MPU_InitStruct.DisableExec      = MPU_INSTRUCTION_ACCESS_ENABLE;
        HAL_MPU_ConfigRegion(&MPU_InitStruct);
       
        /* 配置FMC扩展IO的MPU属性为Device或者Strongly Ordered */
        MPU_InitStruct.Enable           = MPU_REGION_ENABLE;
        MPU_InitStruct.BaseAddress      = 0x64000000;
        MPU_InitStruct.Size             = ARM_MPU_REGION_SIZE_32KB;       
        MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
        MPU_InitStruct.IsBufferable     = MPU_ACCESS_BUFFERABLE;
        MPU_InitStruct.IsCacheable      = MPU_ACCESS_NOT_CACHEABLE;        /* 不能用MPU_ACCESS_CACHEABLE;会出现2次CS、WE信号 */
        MPU_InitStruct.IsShareable      = MPU_ACCESS_NOT_SHAREABLE;
        MPU_InitStruct.Number           = MPU_REGION_NUMBER1;
        MPU_InitStruct.TypeExtField     = MPU_TEX_LEVEL0;
        MPU_InitStruct.SubRegionDisable = 0x00;
        MPU_InitStruct.DisableExec      = MPU_INSTRUCTION_ACCESS_ENABLE;
       
        HAL_MPU_ConfigRegion(&MPU_InitStruct);

        /*使能 MPU */
        HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}
回复

使用道具 举报

9

主题

39

回帖

66

积分

初级会员

积分
66
 楼主| 发表于 2022-6-9 23:48:46 | 显示全部楼层

我看了您的视频,硬件错误中断是由于不是4字节对齐引起的
设置成了如下4字节对齐方式还是进入了硬件中断
ALIGN_32BYTES (static uint32_t valuereg );
valuereg = 0x00000001;
*(uint32_t *)0x64000001 = valuereg;


回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106545
QQ
发表于 2022-6-10 10:15:41 | 显示全部楼层
ajianyes 发表于 2022-6-9 23:48
我看了您的视频,硬件错误中断是由于不是4字节对齐引起的
设置成了如下4字节对齐方式还是进入了硬件中断 ...

这个帖子看下就明白了。

石锤内存访问不支持非对齐是否STM32H7的硬件bug
https://www.armbbs.cn/forum.php? ... 4562&fromuid=58
(出处: 硬汉嵌入式论坛)
回复

使用道具 举报

9

主题

39

回帖

66

积分

初级会员

积分
66
 楼主| 发表于 2022-6-10 11:06:25 | 显示全部楼层
eric2013 发表于 2022-6-10 10:15
这个帖子看下就明白了。

石锤内存访问不支持非对齐是否STM32H7的硬件bug

谢谢硬汉哥,我看到您帖子上写的如下
4、解决办法
配置内存空间的MPU属性为Device 和 Strongly-ordered以外的属性就可以了


意思就是我这FMC驱动的SRAM不能配置为Device 和 Strongly-ordered这两种设备吗?还有就是我的地址只用了A0一根,写数据命令是0X64000000是4字节对齐的,但是如果写控制命令地址0X64000001,就无法进行操作了吗?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106545
QQ
发表于 2022-6-10 17:44:01 | 显示全部楼层
ajianyes 发表于 2022-6-10 11:06
谢谢硬汉哥,我看到您帖子上写的如下
4、解决办法
配置内存空间的MPU属性为Device 和 Strongly-ordered ...

0X64000001地址操作4字节属于非对齐访问。
回复

使用道具 举报

9

主题

39

回帖

66

积分

初级会员

积分
66
 楼主| 发表于 2022-6-11 11:58:48 | 显示全部楼层
eric2013 发表于 2022-6-10 17:44
0X64000001地址操作4字节属于非对齐访问。

好的,谢谢硬汉哥。按照6400004访问 就可以了,现在FMC已经可以正常工作了。感谢您的帮助
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106545
QQ
发表于 2022-6-12 10:56:35 | 显示全部楼层
ajianyes 发表于 2022-6-11 11:58
好的,谢谢硬汉哥。按照6400004访问 就可以了,现在FMC已经可以正常工作了。感谢您的帮助

回复

使用道具 举报

9

主题

39

回帖

66

积分

初级会员

积分
66
 楼主| 发表于 2022-6-18 20:37:11 | 显示全部楼层

再次感谢硬汉哥,我调试另一个外设W5300,也是用FMC驱动SRAM设备,用的地址线是A9-A17,NE1(外设地址是0x60000000)、按照手册的设置外设地址是不是就是0x60000400(A9往右移一位)。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106545
QQ
发表于 2022-6-19 10:05:45 | 显示全部楼层
ajianyes 发表于 2022-6-18 20:37
再次感谢硬汉哥,我调试另一个外设W5300,也是用FMC驱动SRAM设备,用的地址线是A9-A17,NE1(外设地址是0 ...

这个要跟你的数据位宽匹配。
回复

使用道具 举报

9

主题

39

回帖

66

积分

初级会员

积分
66
 楼主| 发表于 2022-6-19 12:49:46 | 显示全部楼层
eric2013 发表于 2022-6-19 10:05
这个要跟你的数据位宽匹配。

我的数据位宽是16bit的
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106545
QQ
发表于 2022-6-21 01:24:19 | 显示全部楼层
ajianyes 发表于 2022-6-19 12:49
我的数据位宽是16bit的

应该是左移<<,而不是右移>>。
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-24 13:12 , Processed in 0.408673 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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