stm32h743中文手册

问题 DMA is not working on STM32H7 devices Ethernet not working on STM32H7x3 关于STM32H743 recv()数据错误的问题分析 H7使用DMA注意事项 注意发送或者接收缓存的字节对齐问题,一般是要求4字节对齐 注意DMA和外设是否可访问发送或者接收缓存所在SRAM空间 注意Cache的一致性 MPU

问题

DMA is not working on STM32H7 devices
Ethernet not working on STM32H7x3
关于STM32H743 recv()数据错误的问题分析

H7使用DMA注意事项

  1. 注意发送或者接收缓存的字节对齐问题,一般是要求4字节对齐
  2. 注意DMA和外设是否可访问发送或者接收缓存所在SRAM空间
  3. 注意Cache的一致性

MPU

STM32H7的Cache和MPU
STM32H7-MPU的理解和配置
STM32H7系列MCU的MPU和Cache功能介绍
http://news.eeworld.com.cn/mcu/ic472514.html
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

FMC

FMC-LCD

如果程序和MX的配置都没问题显示还不正常那就先考虑读时序里的data setup time 时间拉长
【经验分享】STM32CubeMX之FMC驱动TFT-LCD屏
TFTLCD之FSMC详解述
TFTLCD之FSMC详解_超级霸霸强的博客-程序员秘

FMC-SDRAM

STM32H7的FMC总线应用之SDRAM
STM32F429驱动外部SDRAM
STM32CubeMX配置SDRAM
注意时钟线,控制线,地址线上的电阻,特别是地址线上的电阻焊接的是不是一样的,如果焊接错误,会导致数据出现错乱。
【STM32H7教程】第25章 STM32H7的TCM,SRAM等五块内存基础知识

STM32H7:解决DMA传输无效的问题

cache

Data alignment(数据、内存对齐)漫谈
M7内核的cache line 是 8字=32字节
在这里插入图片描述

#if (ENABLE_SD_DMA_CACHE_MAINTENANCE == 1)
                /*
                the SCB_InvalidateDCache_by_Addr() requires a 32-Byte aligned address,
                adjust the address and the D-Cache size to invalidate accordingly.
                */
                alignedAddr = (uint32_t)buff & ~0x1F;
                SCB_InvalidateDCache_by_Addr((uint32_t*)alignedAddr, count*BLOCKSIZE + ((uint32_t)buff - alignedAddr));
#endif
/**
  
  \brief   D-Cache Invalidate by address
  \details Invalidates D-Cache for the given address
  \param[in]   addr    address (aligned to 32-byte boundary)
  \param[in]   dsize   size of memory block (in number of bytes)
*/
__STATIC_INLINE void SCB_InvalidateDCache_by_Addr (uint32_t *addr, int32_t dsize)
{
  #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
     int32_t op_size = dsize;
    uint32_t op_addr = (uint32_t)addr;
     int32_t linesize = 32;                /* in Cortex-M7 size of cache line is fixed to 8 words (32 bytes) */

    __DSB();

    while (op_size > 0) {
      SCB->DCIMVAC = op_addr;
      op_addr += (uint32_t)linesize;
      op_size -=           linesize;
    }

    __DSB();
    __ISB();
  #endif
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

ADC

#define OVERSAMPLING_RATIO              1023                               /* 1024-oversampling */                                      
#define RIGHTBITSHIFT                   ADC_RIGHTBITSHIFT_6                /* 6-bit right shift of the oversampled summation */          
#define TRIGGEREDMODE                   ADC_TRIGGEREDMODE_SINGLE_TRIGGER   /* A single trigger for all channel oversampled conversions */
#define OVERSAMPLINGSTOPRESET           ADC_REGOVERSAMPLING_CONTINUED_MODE /* Oversampling buffer maintained during injection sequence */

void MX_ADC3_Init(void)
{
  ADC_ChannelConfTypeDef sConfig = {0};

  /** Common config
  */
  hadc3.Instance = ADC3;
  hadc3.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV2;
  hadc3.Init.Resolution = ADC_RESOLUTION_16B;
  hadc3.Init.ScanConvMode = ADC_SCAN_DISABLE;
  hadc3.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  hadc3.Init.LowPowerAutoWait = DISABLE;
  hadc3.Init.ContinuousConvMode = ENABLE;
  hadc3.Init.NbrOfConversion = 1;
  hadc3.Init.DiscontinuousConvMode = DISABLE;
  hadc3.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc3.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  hadc3.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DMA_ONESHOT;
  hadc3.Init.Overrun = ADC_OVR_DATA_PRESERVED;
  hadc3.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE;
  hadc3.Init.OversamplingMode = ENABLE;
  hadc3.Init.Oversampling.RightBitShift         = RIGHTBITSHIFT;         /* Right shift of the oversampled summation */
  hadc3.Init.Oversampling.TriggeredMode         = TRIGGEREDMODE;         /* Specifies whether or not a trigger is needed for each sample */
  hadc3.Init.Oversampling.OversamplingStopReset = OVERSAMPLINGSTOPRESET; /* Specifies whether or not the oversampling buffer is maintained during injection sequence */    
  
  if (HAL_ADC_Init(&hadc3) != HAL_OK)
  {
    Error_Handler();
  }
    
  /* ADCУ׼ */
  if ( HAL_ADCEx_Calibration_Start( &hadc3, ADC_CALIB_OFFSET, ADC_SINGLE_ENDED ) != HAL_OK )
  {
    Error_Handler();
  }

  if ( HAL_ADCEx_Calibration_Start( &hadc3, LL_ADC_CALIB_OFFSET_LINEARITY, ADC_SINGLE_ENDED ) != HAL_OK )
  {
    Error_Handler();
  }
    
  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_1;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SamplingTime = ADC_SAMPLETIME_8CYCLES_5;
  sConfig.SingleDiff = ADC_SINGLE_ENDED;
  sConfig.OffsetNumber = ADC_OFFSET_NONE;
  sConfig.Offset = 0;
  sConfig.OffsetSignedSaturation = DISABLE;
  if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }

}

ADC配置参数说明

  1. ContinuousConvMode
    hadc3.Init.ContinuousConvMode = ENABLE;
    如果ContinuousConvMode 配置为ENABLE,表示启动ADC之后,ADC自动连续转化,不需要再次启动

  2. ConversionDataManagement
    hadc3.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DMA_ONESHOT;
    当使用ADC查询模式或者中断模式时,需要配置为ADC_CONVERSIONDATA_DR
    当使用ADC DMA传输时,需要配置为ADC_CONVERSIONDATA_DMA_ONESHOT或者ADC_CONVERSIONDATA_DMA_CIRCULAR
    其中,ADC_CONVERSIONDATA_DMA_ONESHOT表示DMA只传输一次,需要再次开启DMAch
    如果配置为ADC_CONVERSIONDATA_DR,使用DMA传输,无法进入DMA传输完成中断。

oversample 过采样

ADC通过过采样技术,STM32H7的ADC可以做到26位分辨率
STM32H7 ADC 过采样对精度的影响效果
STM32H7的ADC过采样功能立竿见影,效果的确不错
过采样移位,会导致计算系数不一样

#define ADC_RIGHTBITSHIFT_NONE             (LL_ADC_OVS_SHIFT_NONE)    /*!< ADC oversampling no shift (sum of the ADC conversions data is not divided to result as the ADC oversampling conversion data) */
#define ADC_RIGHTBITSHIFT_1                (LL_ADC_OVS_SHIFT_RIGHT_1) /*!< ADC oversampling shift of 1 (sum of the ADC conversions data is divided by 2 to result as the ADC oversampling conversion data) */
#define ADC_RIGHTBITSHIFT_2                (LL_ADC_OVS_SHIFT_RIGHT_2) /*!< ADC oversampling shift of 2 (sum of the ADC conversions data is divided by 4 to result as the ADC oversampling conversion data) */
#define ADC_RIGHTBITSHIFT_3                (LL_ADC_OVS_SHIFT_RIGHT_3) /*!< ADC oversampling shift of 3 (sum of the ADC conversions data is divided by 8 to result as the ADC oversampling conversion data) */
#define ADC_RIGHTBITSHIFT_4                (LL_ADC_OVS_SHIFT_RIGHT_4) /*!< ADC oversampling shift of 4 (sum of the ADC conversions data is divided by 16 to result as the ADC oversampling conversion data) */
#define ADC_RIGHTBITSHIFT_5                (LL_ADC_OVS_SHIFT_RIGHT_5) /*!< ADC oversampling shift of 5 (sum of the ADC conversions data is divided by 32 to result as the ADC oversampling conversion data) */
#define ADC_RIGHTBITSHIFT_6                (LL_ADC_OVS_SHIFT_RIGHT_6) /*!< ADC oversampling shift of 6 (sum of the ADC conversions data is divided by 64 to result as the ADC oversampling conversion data) */
#define ADC_RIGHTBITSHIFT_7                (LL_ADC_OVS_SHIFT_RIGHT_7) /*!< ADC oversampling shift of 7 (sum of the ADC conversions data is divided by 128 to result as the ADC oversampling conversion data) */
#define ADC_RIGHTBITSHIFT_8                (LL_ADC_OVS_SHIFT_RIGHT_8) /*!< ADC oversampling shift of 8 (sum of the ADC conversions data is divided by 256 to result as the ADC oversampling conversion data) */
#define ADC_RIGHTBITSHIFT_9                (LL_ADC_OVS_SHIFT_RIGHT_9) /*!< ADC oversampling shift of 9 (sum of the ADC conversions data is divided by 512 to result as the ADC oversampling conversion data) */
#define ADC_RIGHTBITSHIFT_10               (LL_ADC_OVS_SHIFT_RIGHT_10)/*!< ADC oversampling shift of 10 (sum of the ADC conversions data is divided by 1024 to result as the ADC oversampling conversion data) */
#define ADC_RIGHTBITSHIFT_11               (LL_ADC_OVS_SHIFT_RIGHT_11)/*!< ADC oversampling shift of 11 (sum of the ADC conversions data is divided by 2048 to result as the ADC oversampling conversion data) */

AdcHandle.Init.Oversampling.RightBitShift         = ADC_RIGHTBITSHIFT_6;
 /* Read the converted value */
    uwConvertedValue = HAL_ADC_GetValue(&AdcHandle);

    /* Convert the result from 20 bit value to the voltage dimension (mV unit) */
    /* Vref = 3.3 V */
    uwInputVoltage = uwConvertedValue * 3300;  
    /* ADC_RIGHTBITSHIFT_6 计算结果需要除以64=2^4,左移4we
    uwInputVoltage = uwInputVoltage / 0xFFFF0; 

DMA数据长度范围为:1-65535
#define IS_DMA_BUFFER_SIZE(SIZE) (((SIZE) >= 0x01U) && ((SIZE) < 0x10000U))

第43章 STM32H7的DMA应用之双缓冲控制任意IO和脉冲数控制
在这里插入图片描述
在这里插入图片描述

最后特别注意一点,如果STM32H7工作在400MHz,ADC使用AHB做时钟源,超频是不可避免的。ADC1和ADC2位于200MHz的AHB1总线时钟,而ADC3位于200MHz的AHB4下。根据上面的框图,ADCx_CCR寄存器的CKMODE最高可以选择4分频,那么就是50MHz,而ADC数据手册限制最高是36MHz,也就是说已经超频了。

使用AHB作为时钟源的好处就是定时器等外部触发方式的效果好。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

STM32三个ADC同步规则采样
【STM32H7教程】第46章 STM32H7的ADC应用之DMA方式多通道采样
第44章 STM32H7的ADC基础知识和HAL库API
How to persistently write into option byte BOOT_ADD0/1
第51章 设置FLASH的读写保护及解除—零死角玩转STM32-F429系列

HAL_FLASH_Unlock();
HAL_FLASH_OB_Unlock();
FLASH_OBProgramInitTypeDef obData;
HAL_FLASHEx_OBGetConfig(&obData);
obData.BootAddr1 =(CalValue<<16);  //自定义数据
obData.OptionType = OPTIONBYTE_BOOTADD;
obData.BootConfig =OB_BOOT_ADD_BOTH;
if (  HAL_FLASHEx_OBProgram(&obData)!= HAL_OK){
    Error_Handler();
}
HAL_FLASH_OB_Launch();
HAL_FLASHEx_OBGetConfig(&obData);
HAL_FLASH_OB_Lock();
HAL_FLASH_Lock();

像使用内部SRAM一样定义使用STM32H7的外部SDRAM


1、在IAR的分散配置文件中,定义SDRAM放在“不初始化区域”(因为系统启动后,sdram并没有完成初始化配置,此时初始化sdram区域中的变量会导致系统进入硬件错误HardFault_Handler)

do not initialize  { section .noinit ,section .sdram2};

2、系统启动后,初始化SDRAM

3、将变量定义在sdram中

__attribute__((section (".sdram2")))  float x_buff[1024];
__attribute__((section (".sdram2")))  float farFFTBuffer_t[1024*2];
__attribute__((section (".sdram2")))  float farFFTOutBuffer[1024];

4、使用定义的变量(使用变量之前,必须完成SDRAM初始化,否则系统进入硬件错误HardFault_Handler)

memory map

在这里插入图片描述

在这里插入图片描述

ETH

  1. 必须添加MAC的复位操作,否则无法通信
    在ethernetif.c文件中的low_level_init函数中,添加复位操作
 /* USER CODE BEGIN MACADDRESS */
  LAN8720A_reset();
  /* USER CODE END MACADDRESS */
  hal_eth_init_status = HAL_ETH_Init(&heth);
static void LAN8720A_reset(void)
{
  ETH_CTR_RESET;
  HAL_Delay(50);
  ETH_CTR_SET;
  HAL_Delay(50);
}

SDIO

使用注意事项

  1. 必须使能SDMMC中断
    在这里插入图片描述
  2. 必须配置SDMMC时钟频率为200MHz
    只需要将SDIO的时钟频率配置为200MHz,HAL库会根据不同的SD卡设置不同的速率
    在这里插入图片描述
  3. 使能ENABLE_SD_DMA_CACHE_MAINTENANCE和ENABLE_SCRATCH_BUFFER
    使能sd_diskio.c中的ENABLE_SD_DMA_CACHE_MAINTENANCE和ENABLE_SCRATCH_BUFFER,否则数据读写不正确
    在这里插入图片描述

只需要将SDIO的时钟频率配置为200MHz,HAL库会根据不同的SD卡设置不同的速率。
STM32H7教程】第87章 STM32H7的SDMMC总线基础知识和HAL库API
[SD/SDIO] STM32H7的SDIO自带的DMA控制器数据传输的地址是强制4字节对齐
在这里插入图片描述

SD卡的协议上说上限是48MHz,但许多SD卡上不了这么高的频率
一般设置为36MHz或者24MHz
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

SD specification上明确写着speed class存在SSR寄存器中,[447:440] 是speed class,[399:396]是UHS speed grade。如下图所示。另外,SSR的访问向SD device发送ACMD13即可在data line上返回SSR的内容。下图中的内容是V5.0中呈现的。
作者:晴天
链接:https://www.zhihu.com/question/55487660/answer/171128582
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

在这里插入图片描述
图中1-9序号分别表示:

1、品牌

2、产品定位或系列

3、容量等级32GB

4、SDHC容量等级为2GB - 32GB

5、最快读取速度95MB/s

6、Class等级C10,即最低写入速度10MB/s

7、UHS等级U3,即支持UHS模式时,最低写入速度30MB/s

8、支持UHS-I模式,最大读取速度104MB/s

9、VSC视频速度等级V3,即最低写入速度30MB/s

总结一下卡面信息就是:

(1)容量32GB。

(2)普通模式,最低读写速度10MB/s。

(2)支持UHS模式,最低写入速度30MB/s,最高读取速度95MB/s。
在这里插入图片描述
在这里插入图片描述

【图拉丁】SD卡速度规范
深入理解SD卡:协议
都是高速SD卡,支持UHS-I和UHS-II的区别是什么?
UHS-I、UHS-II、UHS-III接口
STM32H7的SDIO外接支持UHS-I 模式 (SDR12, SDR25, SDR50, SDR104和DDR50)需要1.8的电平转换器

USART

串口时钟的大小影响通信速率,时钟速率设置过高会导致低速率时无法通信。
串口时钟频率设置过高,导致最低通信速率被限制,之前是120000KHz,16倍过采样,最高120000/16=7500Kbps,最低120000/65535=1.8310Kbps,超过1200bps。
修改串口分频为4分频,串口时钟为30000KHz,最高30000/16=1875Kbps,最低30000/65535=0.457Kbps,满足要求
在这里插入图片描述

在这里插入图片描述

LTDC

STM32F429之LTDC驱动图解
H743教程五:stm32H743 cubumx配置驱动LTDC RGB屏幕
基于STM32H743设计UI界面心得(还没写完)
LTDC/DMA2D——液晶显示
第27章 LTDC/DMA2D—液晶显示

DMA2D

STM32的“GPU”——DMA2D实例详解

QSPI

STM32硬件基础–QaudSPI总线读写片外FLASH(二)

SPI

H7的SPI功能更强大,需要配置的参数更多,一般配置如下。需要注意几点

  1. MasterSSIdleness:设置第一个数据发送开始前CLK的延时
  2. MasterInterDataIdleness :设置每个DataSize 之间,CLK的延时
  3. MasterKeepIOState :设置是否保持SPI的IO状态(CLK和MOSI),如果关闭该功能,在使用完SPI后,SPI引脚状态释放。如果片选配置成SPI_NSS_SOFT,最好使能改功能,使SPI的IO口保持在正确的状态
  4. IOSwap :设置是否交换MISO和MOSI口
  hspi4.Instance = SPI4;
  hspi4.Init.Mode = SPI_MODE_MASTER;
  hspi4.Init.Direction = SPI_DIRECTION_2LINES;
  hspi4.Init.DataSize = SPI_DATASIZE_8BIT;
  hspi4.Init.CLKPolarity = SPI_POLARITY_HIGH;
  hspi4.Init.CLKPhase = SPI_PHASE_2EDGE;
  hspi4.Init.NSS = SPI_NSS_SOFT;
  hspi4.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64;
  hspi4.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi4.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi4.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi4.Init.CRCPolynomial = 0x0;
  hspi4.Init.NSSPMode = SPI_NSS_PULSE_ENABLE;
  hspi4.Init.NSSPolarity = SPI_NSS_POLARITY_LOW;
  hspi4.Init.FifoThreshold = SPI_FIFO_THRESHOLD_01DATA;
  hspi4.Init.TxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN;
  hspi4.Init.RxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN;
  hspi4.Init.MasterSSIdleness = SPI_MASTER_SS_IDLENESS_00CYCLE;
  hspi4.Init.MasterInterDataIdleness = SPI_MASTER_INTERDATA_IDLENESS_00CYCLE;
  hspi4.Init.MasterReceiverAutoSusp = SPI_MASTER_RX_AUTOSUSP_DISABLE;
  hspi4.Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_ENABLE;
  hspi4.Init.IOSwap = SPI_IO_SWAP_DISABLE;
  if (HAL_SPI_Init(&hspi4) != HAL_OK)
  {
    Error_Handler();
  }

I2C

i2c timing配置
STM32H7的硬件I2C fast mode 速度不能到400K?

内置温度传感器

[ADC] STM32H7的ADC温度传感器测量

知秋君
上一篇 2024-08-31 12:36
下一篇 2024-08-31 12:02

相关推荐