问题
DMA is not working on STM32H7 devices
Ethernet not working on STM32H7x3
关于STM32H743 recv()数据错误的问题分析
H7使用DMA注意事项
- 注意发送或者接收缓存的字节对齐问题,一般是要求4字节对齐
- 注意DMA和外设是否可访问发送或者接收缓存所在SRAM空间
- 注意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配置参数说明
-
ContinuousConvMode
hadc3.Init.ContinuousConvMode = ENABLE;
如果ContinuousConvMode 配置为ENABLE,表示启动ADC之后,ADC自动连续转化,不需要再次启动 -
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
- 必须添加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
使用注意事项
- 必须使能SDMMC中断
- 必须配置SDMMC时钟频率为200MHz
只需要将SDIO的时钟频率配置为200MHz,HAL库会根据不同的SD卡设置不同的速率
- 使能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功能更强大,需要配置的参数更多,一般配置如下。需要注意几点
- MasterSSIdleness:设置第一个数据发送开始前CLK的延时
- MasterInterDataIdleness :设置每个DataSize 之间,CLK的延时
- MasterKeepIOState :设置是否保持SPI的IO状态(CLK和MOSI),如果关闭该功能,在使用完SPI后,SPI引脚状态释放。如果片选配置成SPI_NSS_SOFT,最好使能改功能,使SPI的IO口保持在正确的状态
- 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温度传感器测量