stm32h743替代芯片(STM32H723、STM32H743、STM32H750的區(qū)別)


1、stm32h743替代芯片
STM32H743/753系列產(chǎn)品集成了工作頻率高達(dá)480 MHz的Arm? Cortex?-M7內(nèi)核(具有雙精度浮點(diǎn)單元)。
性能
在480 MHz的CPU頻率下,從Flash執(zhí)行程序時(shí),STM32H742系列能夠提供2424 CoreMark /1027 DMIPS的性能,利用其L1緩存實(shí)現(xiàn)了0等待執(zhí)行
L1緩存(16 KB的I-緩存 +16 KB的D-緩存)提高外部存儲(chǔ)器的執(zhí)行性能
安全性
STM32H753 MCU包含以下額外安全特性:
加密/哈希硬件加速
STM32H755還支持安全固件安裝(SFI)嵌入式安全服務(wù),可在執(zhí)行初始程序時(shí)執(zhí)行安全驗(yàn)證并保護(hù)軟件IP
安全啟動(dòng)和安全固件升級(jí)(SBSFU)
高能效
多電源域架構(gòu)可實(shí)現(xiàn)將不同的電源域配置為低功耗模式,進(jìn)而優(yōu)化功耗效率。
USB調(diào)節(jié)器提供嵌入式物理接口層(PHY)。
在內(nèi)核運(yùn)行模式(關(guān)閉外設(shè))下,功耗典型值為275 μA/MHz @VDD = 3.3 V和25 °C
低功耗待機(jī)模式下的典型功耗電流為2.43 μA
帶RTC的VBAT模式(低功耗模式)下通常為460 nA
圖形
LCD-TFT控制器接口支持雙層圖形
Chrom-ART Accelerator?提高了圖形內(nèi)容創(chuàng)建速度,并為其它應(yīng)用節(jié)省了MCU內(nèi)核處理帶寬
JPEG硬件加速器,可進(jìn)行快速JPEG編碼和解碼,從而減輕CPU編解碼負(fù)荷
片內(nèi)外設(shè)
多達(dá)35個(gè)通信接口包括FD-CAN、USB 2.0高速/全速、以太網(wǎng)MAC、攝像頭接口
可利用帶有32位并行接口或雙模Quad-SPI串行閃存接口的靈活存儲(chǔ)控制器輕松擴(kuò)展存儲(chǔ)器容量
模擬外設(shè):12位DAC,快速16位ADC
16位高精度定時(shí)器上的多個(gè)16位和32位定時(shí)器運(yùn)行頻率高達(dá)480 MHz
STM32H743/753 MCU系列提供1到2 MB的Flash存儲(chǔ)器,具有以下結(jié)構(gòu)的1 MB SRAM:192 KB的TCM RAM(包括64 KB的ITCM RAM和128 KB的DTCM RAM,用于時(shí)間關(guān)鍵型程序和數(shù)據(jù)),512 KB、288 KB和64 KB的用戶(hù)SRAM,以及用于在最低功耗模式下保存數(shù)據(jù)的備份域4 KB SRAM。另外,它提供100至240引腳的BGA和LQFP封裝型號(hào)。
在智能家居與汽車(chē)電子所需芯片中,MCU芯片的占比是最高的,隨著智能家居與智能汽車(chē)的發(fā)展,MCU芯片的需求量被進(jìn)一步加大,這就要求MCU芯片無(wú)論是在技術(shù)研發(fā)還是在生產(chǎn)數(shù)量上都要滿(mǎn)足市場(chǎng)的需求,不過(guò),由于MCU市場(chǎng)的供需失衡,自2021年起,ST的部分高端MCU產(chǎn)品開(kāi)始漲價(jià),許多下游終端廠(chǎng)商為此焦頭爛額。
以意法半導(dǎo)體為例,渠道經(jīng)銷(xiāo)商價(jià)格飛漲,通過(guò)查詢(xún)IC交易網(wǎng)創(chuàng)新指數(shù)得知,其高端芯片型STM32H743XIH6近日漲幅嚴(yán)重,由1017元上漲到2599元,幅度高達(dá)155.56%,并且在價(jià)格上漲的同時(shí)還陷入了缺貨狀態(tài),交期長(zhǎng)達(dá)3周。
其另一款芯片STM32H743IIT6價(jià)格同樣有所上漲,從333.35元上漲到772元,再回落到509元,漲幅高達(dá)52.69%。
我們都知道,芯片缺貨的后果有多嚴(yán)重。此前全球陷入MCU缺貨、漲價(jià)危機(jī),導(dǎo)致了部分車(chē)企和工業(yè)電子企業(yè)出現(xiàn)停產(chǎn)的情況,且各大廠(chǎng)商均出現(xiàn)交期嚴(yán)重延長(zhǎng)的情況,部分甚至達(dá)到了40周以上。
但危機(jī)同樣代表著機(jī)遇。
芯片漲價(jià)且交期過(guò)長(zhǎng)導(dǎo)致國(guó)內(nèi)企業(yè)開(kāi)始面臨成本飆升、被迫減產(chǎn),停產(chǎn)的窘境,為擺脫這一情況,許多國(guó)內(nèi)企業(yè)開(kāi)始嘗試用國(guó)產(chǎn)芯片替代原來(lái)芯片。這就為國(guó)內(nèi)芯片公司迎來(lái)了絕佳的發(fā)展窗口期。
目前國(guó)內(nèi)已經(jīng)出現(xiàn)具備較好技術(shù)積累和廣泛產(chǎn)品布局或具有特殊定位優(yōu)勢(shì)的MCU廠(chǎng)商。國(guó)產(chǎn)化進(jìn)程不可逆轉(zhuǎn),大陸領(lǐng)先MCU廠(chǎng)商有望迎來(lái)快速增長(zhǎng)期。
此外,如今的下游終端廠(chǎng)商已逐步開(kāi)始替換,中國(guó)本土MCU廠(chǎng)商迎來(lái)了機(jī)遇期。以先楫半導(dǎo)體為例,其基于RISC-V內(nèi)核開(kāi)發(fā)的HPM系列國(guó)產(chǎn)MCU,與國(guó)際廠(chǎng)商產(chǎn)品相比,CPU主頻更高,內(nèi)存更多,易用性更高,成本也更低,外設(shè)也較為豐富,集成度更高,更適應(yīng)本土化應(yīng)用需求,HPM6700/6400、HPM6300、HPM6200等都可較好與國(guó)際大廠(chǎng)兼容,部分實(shí)現(xiàn)國(guó)產(chǎn)化替代。
接下來(lái)就由我愛(ài)方案網(wǎng)為大家分享先楫半導(dǎo)體的幾款高性能RISC-V MCU芯片。
HPM6700/6400系列芯片
HPM6700/6400 系列產(chǎn)品是先楫半導(dǎo)體推出的高性能高實(shí)時(shí) RISC-V MCU 旗艦產(chǎn)品,目前已經(jīng)量產(chǎn)。與國(guó)際競(jìng)品相比,HPM6700系列芯片單核運(yùn)行主頻即可達(dá)到驚人的816MHz,在CoreMark跑分測(cè)試中,HPM6700獲得了9220的高分,成功刷新了國(guó)際MCU領(lǐng)域的性能記錄。
在具體性能方面,HPM6700/6400系列芯片采用RISC-V 內(nèi)核,支持雙精度浮點(diǎn)運(yùn)算及強(qiáng)大的 DSP 擴(kuò)展,主頻頻率創(chuàng)下了MCU 性能新紀(jì)錄,是目前市場(chǎng)上高性能MCU的理想之選。此外,該系列芯片還配置了高效 L1 緩存和本地存儲(chǔ)器,加上 2MB 內(nèi)置通用SRAM,極大避免了低速外部存儲(chǔ)器引發(fā)的性能損失。
HPM6700/6400系列芯片還擁有強(qiáng)大的多媒體支持能力和豐富外設(shè)接口,其適配的LCD顯示控制器可支持高達(dá)1366x768 60fps的八圖層RGB顯示支持,支持圖形加速功能,可支持雙千兆以太網(wǎng),IEEE1588,雙目攝像頭。并具有4個(gè)獨(dú)立的pwm模塊,每個(gè)模塊可生成8通道互補(bǔ)PWM,及16通道普通PWM、3 個(gè) 12 位高速 ADC 5MSPS、1 個(gè) 16 位高精度 ADC 2MSPS、4 個(gè)模擬比較器等多個(gè)接口。
在安全性方面,HPM6700/6400系列芯片集成了 AES-128/256, SHA-1/256 加速引擎,支持固件軟件簽名認(rèn)證、加密啟動(dòng)和加密執(zhí)行。
HPM6300系列
先楫半導(dǎo)體推出的HPM6300全系列產(chǎn)品采用晶心Andes D45 RISC-V內(nèi)核,支持雙精度浮點(diǎn)運(yùn)算。模擬模塊包括16bit-ADC,12-bit DAC和模擬比較器,配以多組納秒級(jí)高分辨率PWM,為馬達(dá)控制和數(shù)字電源應(yīng)用提供強(qiáng)大硬件支持;通訊接口包括了實(shí)時(shí)以太網(wǎng),支持IEEE1588,內(nèi)置PHY的高速USB,多路CAN-FD及豐富的UART,SPI,I2C等接口。(已量產(chǎn))
HPM6300的主頻達(dá)到648MHz, 并具有FFA協(xié)處理器,能實(shí)現(xiàn)FFT/FIR快速計(jì)算,具備3個(gè)16位的ADC、10/100M以太網(wǎng)等,適合工業(yè)自動(dòng)化、電網(wǎng)等行業(yè)應(yīng)用,如工業(yè)自動(dòng)化領(lǐng)域的伺服驅(qū)動(dòng)器、PLC、工業(yè)控制器,電網(wǎng)的DTU、斷路器等產(chǎn)品。
不僅在性能方面表現(xiàn)優(yōu)異,HPM6300同時(shí)也是一款高性?xún)r(jià)比的產(chǎn)品,其高實(shí)時(shí)性、互聯(lián)性、16位ADC的特性,一經(jīng)推出就獲得了自動(dòng)化、電網(wǎng)、新能源客戶(hù)的認(rèn)可。目前已在行業(yè)頭部客戶(hù)中導(dǎo)入產(chǎn)品設(shè)計(jì),在FFT、AI推理性能上超越了傳統(tǒng)的DSP。
在工業(yè)領(lǐng)域,電機(jī)驅(qū)動(dòng)是整個(gè)自動(dòng)化的基礎(chǔ)應(yīng)用,如用于CNC機(jī)床、機(jī)器人的伺服驅(qū)動(dòng)器,用于新能源汽車(chē)的主驅(qū)、壓縮機(jī)驅(qū)動(dòng)等。由于這些行業(yè)本身的發(fā)展和需求增加,對(duì)MCU提出了更高的要求,如高算力、高實(shí)時(shí)性、16位ADC、單芯片多軸控制等。
另外,HPM6300系列在功耗上進(jìn)行了深度優(yōu)化,對(duì)于電源管理域進(jìn)行了更加精細(xì)的劃分,實(shí)現(xiàn)了低至1.5uA的待機(jī)功耗,及低至40mA的運(yùn)行功耗(全速運(yùn)行coremark,外設(shè)時(shí)鐘關(guān)閉),皆低于市場(chǎng)上同類(lèi)國(guó)際品牌的功耗。
HPM6200系列
HPM6200是先楫半導(dǎo)體推出的高性能、高實(shí)時(shí)、高精度混合信號(hào)的通用微控制器系列,為精準(zhǔn)控制而生,主要應(yīng)用領(lǐng)域包括新能源,儲(chǔ)能,電動(dòng)汽車(chē),工業(yè)自動(dòng)化等。(2023Q1量產(chǎn))
與國(guó)際品牌T公司C2000相比,先楫半導(dǎo)體HPM6200系列CPU性能實(shí)現(xiàn)了超越。HPM6200主頻600MHz,而C2000在200MHz以?xún)?nèi);
對(duì)比國(guó)際品牌S公司的G4系列,HPM6200系列在CPU性能、16位ADC、PLA等性能和功能上實(shí)現(xiàn)超越。
性能方面,HPM6200系列芯片主頻達(dá)到600MHz, 是RISC-V 單雙核處理器,帶有FPU和DSP,內(nèi)置4 組8通道增強(qiáng)型 PWM 控制器(8ch/組),提升了系統(tǒng)控制精度,可實(shí)現(xiàn)單芯片控制多軸電機(jī)或者單芯片實(shí)現(xiàn)復(fù)雜拓?fù)涞臄?shù)字電源。同時(shí)配備了可編程邏輯陣列 PLA, 3 個(gè) 2MSPS 16 位高精度 ADC, 16個(gè)模擬輸入通道以及4 個(gè)模擬比較器和 2 個(gè) 1MSPS 12 位 DAC。
此外,HPM6200系列還具備多種通訊接口:1 個(gè)內(nèi)置 PHY 的高速 USB,多達(dá)4路CAN-FD, 4 路 LIN 及豐富的 UART、 SPI、I2C 等。
2、STM32H743基于SPI的SD卡驅(qū)動(dòng)開(kāi)發(fā)流程簡(jiǎn)析
STM32H743以太網(wǎng)驅(qū)動(dòng)調(diào)試
硬件環(huán)境:
基于STM32H743IIT6自研單板
(1)外部時(shí)鐘:25MHz
(2)調(diào)試串口: PC12 ———> UART5_TX
PD2 ———> UART5_RX
(3)SPI6
PG12 ———> SPI6_MISO
PG13 ———> SPI6_SCK
PG14 ———> SPI6_MOSI
PG8 ———> SPI6_NSS
軟件開(kāi)發(fā)環(huán)境
RT-Thread Studio
版本: 2.2.6
構(gòu)建ID: 202211231640
OS: Windows 10, v.10.0, x86_64 / win32
調(diào)試串口+以太網(wǎng)
RT-Thread配置
1.jpg
1.jpg
SPI配置
在board.h文件中,參考SPI配置說(shuō)明依次配置SPI參數(shù)
/ -------------------------- SPI CONFIG BEGIN -------------------------- /
/** if you want to use spi bus you can use the following instructions.
STEP 1, open spi driver framework support in the RT-Thread Settings file
STEP 2, define macro related to the spi bus* ```
such as #define BSP_USING_SPI1
STEP 3, copy your spi init function from stm32xxxx_hal_msp.c generated by stm32cubemx to the end of board.c file
such as void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
STEP 4, modify your stm32xxxx_hal_config.h file to support spi peripherals. define macro related to the peripherals
such as #define HAL_SPI_MODULE_ENABLED
/
#define BSP_USING_SPI
/ #define BSP_USING_SPI1*/
/ #define BSP_USING_SPI2 /
/ #define BSP_USING_SPI3 /
/ #define BSP_USING_SPI4 /
/ #define BSP_USING_SPI5 /
#define BSP_USING_SPI6
/ -------------------------- SPI CONFIG END -------------------------- /
在board.c文件中添加HAL_SPI_MspInit函數(shù)
void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
if(spiHandle->Instance==SPI1)
{
/* USER CODE BEGIN SPI1_MspInit 0 /
/ USER CODE END SPI1_MspInit 0 /
/ * Initializes the peripherals clock
/
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SPI1;
PeriphClkInitStruct.Spi123ClockSelection = RCC_SPI123CLKSOURCE_PLL;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
Error_Handler();
}
/ SPI1 clock enable */
__HAL_RCC_SPI1_CLK_ENABLE();
__HAL_RCC_GPIOG_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/**SPI1 GPIO Configuration
PG9 ------> SPI1_MISO
PG11 ------> SPI1_SCK
PB5 ------> SPI1_MOSI
/
GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_11;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/ SPI1 interrupt Init /
HAL_NVIC_SetPriority(SPI1_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(SPI1_IRQn);
/ USER CODE BEGIN SPI1_MspInit 1 /
/ USER CODE END SPI1_MspInit 1 */
}
else if(spiHandle->Instance==SPI2)
{
/* USER CODE BEGIN SPI2_MspInit 0 */
/* USER CODE END SPI2_MspInit 0 */
/** Initializes the peripherals clock
*/
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SPI2;
PeriphClkInitStruct.Spi123ClockSelection = RCC_SPI123CLKSOURCE_PLL;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
Error_Handler();
}
/* SPI2 clock enable */
__HAL_RCC_SPI2_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOI_CLK_ENABLE();
/**SPI2 GPIO Configuration
PB10 ------> SPI2_SCK
PB15 ------> SPI2_MOSI
PI2 ------> SPI2_MISO
*/
GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;
HAL_GPIO_Init(GPIOI, &GPIO_InitStruct);
/* SPI2 interrupt Init */
HAL_NVIC_SetPriority(SPI2_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(SPI2_IRQn);
/* USER CODE BEGIN SPI2_MspInit 1 */
/* USER CODE END SPI2_MspInit 1 */
}
else if(spiHandle->Instance==SPI3)
{
/* USER CODE BEGIN SPI3_MspInit 0 */
/* USER CODE END SPI3_MspInit 0 */
/** Initializes the peripherals clock
*/
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SPI3;
PeriphClkInitStruct.Spi123ClockSelection = RCC_SPI123CLKSOURCE_PLL;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
Error_Handler();
}
/* SPI3 clock enable */
__HAL_RCC_SPI3_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
/**SPI3 GPIO Configuration
PB2 ------> SPI3_MOSI
PC10 ------> SPI3_SCK
PC11 ------> SPI3_MISO
*/
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF7_SPI3;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF6_SPI3;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/* SPI3 interrupt Init */
HAL_NVIC_SetPriority(SPI3_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(SPI3_IRQn);
/* USER CODE BEGIN SPI3_MspInit 1 */
/* USER CODE END SPI3_MspInit 1 */
}
else if(spiHandle->Instance==SPI4)
{
/* USER CODE BEGIN SPI4_MspInit 0 */
/* USER CODE END SPI4_MspInit 0 */
/** Initializes the peripherals clock
*/
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SPI4;
PeriphClkInitStruct.Spi45ClockSelection = RCC_SPI45CLKSOURCE_D2PCLK1;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
Error_Handler();
}
/* SPI4 clock enable */
__HAL_RCC_SPI4_CLK_ENABLE();
__HAL_RCC_GPIOE_CLK_ENABLE();
/**SPI4 GPIO Configuration
PE2 ------> SPI4_SCK
PE5 ------> SPI4_MISO
PE6 ------> SPI4_MOSI
*/
GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_5|GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;//GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI4;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
/* SPI4 interrupt Init */
HAL_NVIC_SetPriority(SPI4_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(SPI4_IRQn);
/* USER CODE BEGIN SPI4_MspInit 1 */
/* USER CODE END SPI4_MspInit 1 */
}
else if(spiHandle->Instance==SPI5)
{
/* USER CODE BEGIN SPI5_MspInit 0 */
/* USER CODE END SPI5_MspInit 0 */
/** Initializes the peripherals clock
*/
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SPI5;
PeriphClkInitStruct.Spi45ClockSelection = RCC_SPI45CLKSOURCE_D2PCLK1;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
Error_Handler();
}
/* SPI5 clock enable */
__HAL_RCC_SPI5_CLK_ENABLE();
__HAL_RCC_GPIOF_CLK_ENABLE();
/**SPI5 GPIO Configuration
PF7 ------> SPI5_SCK
PF8 ------> SPI5_MISO
PF9 ------> SPI5_MOSI
*/
GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI5;
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
/* SPI5 interrupt Init */
HAL_NVIC_SetPriority(SPI5_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(SPI5_IRQn);
/* USER CODE BEGIN SPI5_MspInit 1 */
/* USER CODE END SPI5_MspInit 1 */
}
else if(spiHandle->Instance==SPI6)
{
/* USER CODE BEGIN SPI6_MspInit 0 */
/* USER CODE END SPI6_MspInit 0 */
/** Initializes the peripherals clock
*/
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SPI6;
PeriphClkInitStruct.Spi6ClockSelection = RCC_SPI6CLKSOURCE_D3PCLK1;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
Error_Handler();
}
/* SPI6 clock enable */
__HAL_RCC_SPI6_CLK_ENABLE();
__HAL_RCC_GPIOG_CLK_ENABLE();
/**SPI6 GPIO Configuration
PG12 ------> SPI6_MISO
PG13 ------> SPI6_SCK
PG14 ------> SPI6_MOSI
*/
GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI6;
HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
/* SPI6 interrupt Init */
HAL_NVIC_SetPriority(SPI6_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(SPI6_IRQn);
/* USER CODE BEGIN SPI6_MspInit 1 */
/* USER CODE END SPI6_MspInit 1 */
}
}
在stm32h7xx_hal_conf.h文件中,打開(kāi)宏定義:
#define HAL_SPI_MODULE_ENABLED
在drv_spi.c文件的spi_config數(shù)組中用到了SPI6_BUS_CONFIG,默認(rèn)工程是沒(méi)有的,需要自己添加,可以參考已有的SPI配置
1.jpg
在spi_config.h文件尾部添加SPI6_BUS_CONFIG
#ifdef BSP_USING_SPI6
#ifndef SPI6_BUS_CONFIG
#define SPI6_BUS_CONFIG
{
.Instance = SPI6,
.bus_name = "spi6",
}
#endif /* SPI6_BUS_CONFIG /
#endif / BSP_USING_SPI6 /
//#ifdef BSP_SPI6_TX_USING_DMA
//#ifndef SPI6_TX_DMA_CONFIG
//#define SPI6_TX_DMA_CONFIG
// {
// .dma_rcc = SPI6_TX_DMA_RCC,
// .Instance = SPI6_TX_DMA_INSTANCE,
// .channel = SPI6_TX_DMA_CHANNEL,
// .dma_irq = SPI6_TX_DMA_IRQ,
// }
//#endif / SPI6_TX_DMA_CONFIG /
//#endif / BSP_SPI6_TX_USING_DMA /
//
//#ifdef BSP_SPI6_RX_USING_DMA
//#ifndef SPI6_RX_DMA_CONFIG
//#define SPI6_RX_DMA_CONFIG
// {
// .dma_rcc = SPI6_RX_DMA_RCC,
// .Instance = SPI6_RX_DMA_INSTANCE,
// .channel = SPI6_RX_DMA_CHANNEL,
// .dma_irq = SPI6_RX_DMA_IRQ,
// }
//#endif / SPI6_RX_DMA_CONFIG /
//#endif / BSP_SPI6_RX_USING_DMA */
在dfs_fs.c文件中,添加文件系統(tǒng)默認(rèn)裝載表:
const struct dfs_mount_tbl mount_table[] =
{
{"sd0", "/", "elm", 0, 0},
{0}
};
在driver目錄下添加drv_spi_tfcard.c文件
測(cè)試
1.jpg
至此完成基于SPI的SD驅(qū)動(dòng)框架。
遺留問(wèn)題
添加SD后,MPU配置會(huì)影響以太網(wǎng)ping的效果,使用下面配置SD卡、以太網(wǎng)均正常
{
MPU_Region_InitTypeDef MPU_InitStruct = {0};
/* Disables the MPU /
HAL_MPU_Disable();
/ * Initializes and configures the Region and the memory to be protected
/
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.BaseAddress = 0x30040000;
MPU_InitStruct.Size = MPU_REGION_SIZE_256B;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/ * Initializes and configures the Region and the memory to be protected
/
MPU_InitStruct.Number = MPU_REGION_NUMBER1;
MPU_InitStruct.BaseAddress = 0x30044000;
MPU_InitStruct.Size = MPU_REGION_SIZE_16KB;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/ Enables the MPU */
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}
使用下面的配置,以太網(wǎng)ping不通
{
MPU_Region_InitTypeDef MPU_InitStruct;
/* Disable the MPU /
HAL_MPU_Disable();
/ Configure the MPU attributes as WT for AXI SRAM /
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_NOT_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_LEVEL0;
MPU_InitStruct.SubRegionDisable = 0X00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
#ifdef BSP_USING_SDRAM
/ Configure the MPU attributes as WT for SDRAM /
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0xC0000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_32MB;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
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);
#endif
#ifdef BSP_USING_ETH
/ Configure the MPU attributes as Device not cacheable
for ETH DMA descriptors and RX Buffers*/
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x30040000;
MPU_InitStruct.Size = MPU_REGION_SIZE_32KB;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER2;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
#endif
/* Configure the MPU attributes as WT for QSPI /
// MPU_InitStruct.Enable = MPU_REGION_ENABLE;
// MPU_InitStruct.BaseAddress = 0x90000000;
// MPU_InitStruct.Size = MPU_REGION_SIZE_8MB;
// MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
// MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
// MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
// MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
// MPU_InitStruct.Number = MPU_REGION_NUMBER3;
// MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
// MPU_InitStruct.SubRegionDisable = 0X00;
// MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
//
// HAL_MPU_ConfigRegion(&MPU_InitStruct);
/ Enable the MPU /
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
/ Enable CACHE */
SCB_EnableICache();
SCB_EnableDCache();
return RT_EOK;
}
3、STM32H743的FDCAN發(fā)送線(xiàn)程卡死的處理方法
芯片型號(hào)STM32H743IIT6,測(cè)試時(shí)發(fā)現(xiàn)如果外面沒(méi)有連接CAN設(shè)備,程序調(diào)用CAN發(fā)送時(shí)會(huì)一直等待發(fā)送反饋,導(dǎo)致相關(guān)線(xiàn)程掛起。
分析發(fā)現(xiàn)是卡在can.c文件的168行_can_int_tx函數(shù):rt_completion_wait(&(tx_tosnd->completion), RT_WAITING_FOREVER);
rt_inline int _can_int_tx(struct rt_can_device *can, const struct rt_can_msg *data, int msgs)
{
int size;
struct rt_can_tx_fifo *tx_fifo;
RT_ASSERT(can != RT_NULL);
size = msgs;
tx_fifo = (struct rt_can_tx_fifo *) can->can_tx;
RT_ASSERT(tx_fifo != RT_NULL);
while (msgs)
{
rt_base_t level;
rt_uint32_t no;
rt_uint32_t result;
struct rt_can_sndbxinx_list tx_tosnd = RT_NULL;
rt_sem_take(&(tx_fifo->sem), RT_WAITING_FOREVER);
level = rt_hw_interrupt_disable();
tx_tosnd = rt_list_entry(tx_fifo->freelist.next, struct rt_can_sndbxinx_list, list);
RT_ASSERT(tx_tosnd != RT_NULL);
rt_list_remove(&tx_tosnd->list);
rt_hw_interrupt_enable(level);
no = ((rt_uint32_t)tx_tosnd - (rt_uint32_t)tx_fifo->buffer) / sizeof(struct rt_can_sndbxinx_list);
tx_tosnd->result = RT_CAN_SND_RESULT_WAIT;
if (can->ops->sendmsg(can, data, no) != RT_EOK)
{
/ send failed. */
level = rt_hw_interrupt_disable();
rt_list_insert_after(&tx_fifo->freelist, &tx_tosnd->list);
rt_hw_interrupt_enable(level);
rt_sem_release(&(tx_fifo->sem));
continue;
}
can->status.sndchange = 1;
rt_completion_wait(&(tx_tosnd->completion), RT_WAITING_FOREVER);
說(shuō)明一直在等待完成信號(hào),而發(fā)送完成信號(hào)的地方在can.c文件的900行rt_hw_can_isr函數(shù):
rt_completion_done(&(tx_fifo->buffer[no].completion));
case RT_CAN_EVENT_TX_DONE:
case RT_CAN_EVENT_TX_FAIL:
{
struct rt_can_tx_fifo *tx_fifo;
rt_uint32_t no;
no = event > > 8;
tx_fifo = (struct rt_can_tx_fifo *) can- >can_tx;
RT_ASSERT(tx_fifo != RT_NULL);
if ((event & 0xff) == RT_CAN_EVENT_TX_DONE)
{
tx_fifo- >buffer[no].result = RT_CAN_SND_RESULT_OK;
}
else
{
tx_fifo- >buffer[no].result = RT_CAN_SND_RESULT_ERR;
}
rt_completion_done(&(tx_fifo- >buffer[no].completion));
break;
}
然后想到如果can總線(xiàn)沒(méi)有其他設(shè)備,CAN發(fā)送報(bào)文應(yīng)該屬于出錯(cuò)的情況,查看drv_fdcan.c文件中關(guān)于幾種中斷的處理,發(fā)現(xiàn)故障后的回調(diào)函數(shù)里沒(méi)有調(diào)用rt_hw_can_isr。
于是參考HAL_FDCAN_TxBufferCompleteCallback函數(shù)的處理方式,對(duì)HAL_FDCAN_ErrorCallback進(jìn)行了如下處理。
void HAL_FDCAN_ErrorCallback(FDCAN_HandleTypeDef *hfdcan)
{
rt_uint32_t tmp_u32Errcount;
rt_uint32_t tmp_u32status;
uint32_t ret = HAL_FDCAN_GetError(hfdcan);
if(hfdcan->Instance == FDCAN1)
{
#ifdef BSP_USING_FDCAN1
//can1
if( (ret & FDCAN_IT_ARB_PROTOCOL_ERROR) &&
(hfdcan->Instance->CCCR & FDCAN_CCCR_INIT_Msk))
{
//hfdcan->Instance->CCCR |= FDCAN_CCCR_CCE_Msk;
hfdcan->Instance->CCCR &= ~FDCAN_CCCR_INIT_Msk;
st_DrvCan1.device.status.errcode = 0xff;
}
else
{
tmp_u32Errcount = st_DrvCan1.fdcanHandle.Instance->ECR;
tmp_u32status = st_DrvCan1.fdcanHandle.Instance->PSR;
st_DrvCan1.device.status.rcverrcnt = (tmp_u32Errcount>>8)&0x000000ff;
st_DrvCan1.device.status.snderrcnt = (tmp_u32Errcount)&0x000000ff;
st_DrvCan1.device.status.lasterrtype = tmp_u32status&0x000000007;
rt_hw_can_isr(&st_DrvCan1.device, RT_CAN_EVENT_TX_FAIL);
}
#endif / BSP_USING_FDCAN1 /
}
else
{
#ifdef BSP_USING_FDCAN2
if( (ret & FDCAN_IT_ARB_PROTOCOL_ERROR) &&
(hfdcan->Instance->CCCR & FDCAN_CCCR_INIT_Msk))
{
//hfdcan->Instance->CCCR |= FDCAN_CCCR_CCE_Msk;
hfdcan->Instance->CCCR &= ~FDCAN_CCCR_INIT_Msk;
st_DrvCan2.device.status.errcode = 0xff;
}
else
{
//can2
tmp_u32Errcount = st_DrvCan2.fdcanHandle.Instance->ECR;
tmp_u32status = st_DrvCan2.fdcanHandle.Instance->PSR;
st_DrvCan2.device.status.rcverrcnt = (tmp_u32Errcount>>8)&0x000000ff;
st_DrvCan2.device.status.snderrcnt = (tmp_u32Errcount)&0x000000ff;
st_DrvCan2.device.status.lasterrtype = tmp_u32status&0x000000007;
rt_hw_can_isr(&st_DrvCan2.device, RT_CAN_EVENT_TX_FAIL);
}
#endif / BSP_USING_FDCAN2 /
}
}
經(jīng)過(guò)測(cè)試發(fā)現(xiàn)即使CAN總線(xiàn)上沒(méi)有別的設(shè)備,調(diào)用發(fā)送函數(shù)也不會(huì)一直等待,而是返回發(fā)送失敗。
4、STM32H723、STM32H743、STM32H750的區(qū)別
STM32H723、STM32H743和STM32H750是STMicroelectronics(意法半導(dǎo)體)推出的三款微控制器產(chǎn)品,它們都屬于STM32H7系列,基于ARM Cortex-M7內(nèi)核,并具備豐富的外設(shè)和高性能特性。以下是它們之間的主要區(qū)別:
處理器頻率:這三款微控制器的處理器頻率有所不同。STM32H723的最大頻率為550 MHz,STM32H743的最大頻率為480 MHz,而STM32H750的最大頻率為480 MHz。因此,STM32H723具有稍高的最大處理器頻率。
存儲(chǔ)器容量:這些微控制器提供不同的閃存和RAM容量選項(xiàng)以適應(yīng)不同的應(yīng)用需求。例如,STM32H723提供高達(dá)1 MB的閃存和564 KB的RAM,STM32H743提供高達(dá)2 MB的閃存和1 MB的RAM,而STM32H750提供128 Kbytes閃存和1MB 的RAM。
封裝類(lèi)型:這些微控制器在封裝類(lèi)型上也有所不同。例如,STM32H723和STM32H743都可提供LQFP、UFBGA、BGA和WLCSP等多種封裝選項(xiàng),而STM32H750主要提供LQFP封裝。
特殊功能:這些微控制器在特殊功能和外設(shè)上也有區(qū)別。例如,STM32H723具備音頻和視頻處理支持,包括多個(gè)I2S接口和視頻解碼器接口;STM32H743提供更多的USB接口選擇,如OTG、Host和Device等;STM32H750則強(qiáng)調(diào)了其低功耗特性和更緊湊的封裝。
5、STM32H743:高性能處理器
??STM32H743是一款高性能處理器,具有強(qiáng)大的處理能力,可滿(mǎn)足各種處理要求。它的特點(diǎn)是:高速運(yùn)行,低功耗,可靠性高,多功能,易于使用,可以用于各種應(yīng)用場(chǎng)景。本文旨在介紹STM32H743的特點(diǎn),并分析其在多種應(yīng)用場(chǎng)景中的優(yōu)勢(shì)。
STM32H743的優(yōu)勢(shì)
??高速運(yùn)行
??STM32H743具有高效率的處理速度,可以滿(mǎn)足各種復(fù)雜的應(yīng)用程序的需求。它的處理器核心為Cortex-M7,主頻高達(dá)400MHz,可以實(shí)現(xiàn)高速運(yùn)行,滿(mǎn)足復(fù)雜的應(yīng)用場(chǎng)景。
??低功耗
??STM32H743的低功耗特性使其可以長(zhǎng)時(shí)間運(yùn)行,而不會(huì)影響系統(tǒng)的性能。它具有多種低功耗模式,可以有效減少系統(tǒng)的功耗。此外,STM32H743還支持多種外設(shè),可以更好地實(shí)現(xiàn)低功耗。
??可靠性高
??STM32H743具有可靠性高的特點(diǎn),它的處理器核心采用了多級(jí)安全技術(shù),可以有效防止惡意攻擊,保護(hù)系統(tǒng)的安全性。此外,STM32H743還支持多種外設(shè),可以更好地實(shí)現(xiàn)系統(tǒng)的可靠性。
??多功能
??STM32H743支持多種外設(shè),可以滿(mǎn)足各種應(yīng)用場(chǎng)景的需求。它支持USB、Ethernet、CAN、I2C、SPI等多種接口,可以滿(mǎn)足不同類(lèi)型的設(shè)備的連接需求。此外,STM32H743還支持多種外設(shè),可以更好地實(shí)現(xiàn)多功能功能。
??易于使用
??STM32H743采用了高效的軟件開(kāi)發(fā)工具,可以更加簡(jiǎn)單、快捷地完成軟件開(kāi)發(fā)。它支持多種開(kāi)發(fā)語(yǔ)言,可以滿(mǎn)足不同類(lèi)型的開(kāi)發(fā)需求。此外,STM32H743還支持各種外設(shè),可以更加便捷地完成軟件開(kāi)發(fā)。
STM32H743的應(yīng)用場(chǎng)景
??STM32H743可以用于各種應(yīng)用場(chǎng)景,其中包括:
??智能家居
??STM32H743可以用于智能家居系統(tǒng),可以實(shí)現(xiàn)家庭設(shè)備的連接、控制和管理。它的高速運(yùn)行和低功耗特性可以滿(mǎn)足智能家居系統(tǒng)的需求,可以更好地實(shí)現(xiàn)家庭智能化。
??自動(dòng)駕駛
??STM32H743可以用于自動(dòng)駕駛汽車(chē),可以實(shí)現(xiàn)汽車(chē)的智能控制。它的高速運(yùn)行和可靠性高的特性可以滿(mǎn)足自動(dòng)駕駛系統(tǒng)的需求,可以更好地實(shí)現(xiàn)汽車(chē)的智能化。
??工業(yè)自動(dòng)化
??STM32H743可以用于工業(yè)自動(dòng)化系統(tǒng),可以實(shí)現(xiàn)多種設(shè)備的智能控制。它的高速運(yùn)行和多功能的特性可以滿(mǎn)足工業(yè)自動(dòng)化系統(tǒng)的需求,可以更好地實(shí)現(xiàn)工業(yè)自動(dòng)化。
總結(jié)
??STM32H743是一款高性能處理器,具有強(qiáng)大的處理能力,可滿(mǎn)足各種處理要求。它的特點(diǎn)是:高速運(yùn)行,低功耗,可靠性高,多功能,易于使用,可以用于各種應(yīng)用場(chǎng)景。它可以用于智能家居、自動(dòng)駕駛和工業(yè)自動(dòng)化等多種應(yīng)用場(chǎng)景,可以更好地實(shí)現(xiàn)智能化。
責(zé)任編輯:David
【免責(zé)聲明】
1、本文內(nèi)容、數(shù)據(jù)、圖表等來(lái)源于網(wǎng)絡(luò)引用或其他公開(kāi)資料,版權(quán)歸屬原作者、原發(fā)表出處。若版權(quán)所有方對(duì)本文的引用持有異議,請(qǐng)聯(lián)系拍明芯城(marketing@iczoom.com),本方將及時(shí)處理。
2、本文的引用僅供讀者交流學(xué)習(xí)使用,不涉及商業(yè)目的。
3、本文內(nèi)容僅代表作者觀點(diǎn),拍明芯城不對(duì)內(nèi)容的準(zhǔn)確性、可靠性或完整性提供明示或暗示的保證。讀者閱讀本文后做出的決定或行為,是基于自主意愿和獨(dú)立判斷做出的,請(qǐng)讀者明確相關(guān)結(jié)果。
4、如需轉(zhuǎn)載本方擁有版權(quán)的文章,請(qǐng)聯(lián)系拍明芯城(marketing@iczoom.com)注明“轉(zhuǎn)載原因”。未經(jīng)允許私自轉(zhuǎn)載拍明芯城將保留追究其法律責(zé)任的權(quán)利。
拍明芯城擁有對(duì)此聲明的最終解釋權(quán)。