[方案相关] HC32F460 SPI避雷

[复制链接]
125|0
Puchou 发表于 2025-11-6 12:15 | 显示全部楼层 |阅读模式
使用HC32F460JETA 芯片,相同的硬件,相同的引脚,使用官方提供的代码分别生成 使用SPI1和SPI2 中断输出数据。所有代码都一样,只有SPI1和SPI2不同,SPI1正常输出,但SPI2就是没输出。大写的服!
其他都一样,都是用的3.3.0的库,源程序如下:

//SPI2:
/**
*******************************************************************************
* @file  main.c
* @brief Main program.
@verbatim
   Change Logs:
   Date             Author          Notes
   2025-10-24       CDT             First version
@endverbatim
*******************************************************************************
* Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved.
*
* This software component is licensed by XHSC under BSD 3-Clause license
* (the "License"); You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
*                    opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/

/*******************************************************************************
* Include files
******************************************************************************/
#include "main.h"

/*******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/

/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
/*******************************************************************************
* Global variable definitions (declared in header file with 'extern') ******************************************************************************/

/*******************************************************************************
* Local function prototypes ('static')
******************************************************************************/
/* INT_SRC_SPI2_SPRI Callback. */
static void INT_SRC_SPI2_SPRI_IrqCallback(void);
/* INT_SRC_SPI2_SPTI Callback. */
static void INT_SRC_SPI2_SPTI_IrqCallback(void);
/* Configures SPIx. */
static void App_SPIxCfg(void);
/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/

/*******************************************************************************
* Function implementation - global ('extern') and local ('static')
******************************************************************************/
//Clock Config
static void App_ClkCfg(void)
{
    /* Set bus clock div. */
    CLK_SetClockDiv(CLK_BUS_CLK_ALL, (CLK_HCLK_DIV1 | CLK_EXCLK_DIV2 | CLK_PCLK0_DIV1 | CLK_PCLK1_DIV2 | \
                                   CLK_PCLK2_DIV4 | CLK_PCLK3_DIV4 | CLK_PCLK4_DIV2));
    /* sram init include read/write wait cycle setting */
    SRAM_SetWaitCycle(SRAM_SRAM_ALL, SRAM_WAIT_CYCLE1, SRAM_WAIT_CYCLE1);
    SRAM_SetWaitCycle(SRAM_SRAMH, SRAM_WAIT_CYCLE0, SRAM_WAIT_CYCLE0);
    /* flash read wait cycle setting */
    EFM_SetWaitCycle(EFM_WAIT_CYCLE5);
    /* XTAL config */
    stc_clock_xtal_init_t stcXtalInit;
    (void)CLK_XtalStructInit(&stcXtalInit);
    stcXtalInit.u8State = CLK_XTAL_ON;
    stcXtalInit.u8Drv = CLK_XTAL_DRV_HIGH;
    stcXtalInit.u8Mode = CLK_XTAL_MD_OSC;
    stcXtalInit.u8StableTime = CLK_XTAL_STB_2MS;
    (void)CLK_XtalInit(&stcXtalInit);
    /* MPLL config */
    stc_clock_pll_init_t stcMPLLInit;
    (void)CLK_PLLStructInit(&stcMPLLInit);
    stcMPLLInit.PLLCFGR = 0UL;
    stcMPLLInit.PLLCFGR_f.PLLM = (3UL - 1UL);
    stcMPLLInit.PLLCFGR_f.PLLN = (50UL - 1UL);
    stcMPLLInit.PLLCFGR_f.PLLP = (2UL - 1UL);
    stcMPLLInit.PLLCFGR_f.PLLQ = (2UL - 1UL);
    stcMPLLInit.PLLCFGR_f.PLLR = (2UL - 1UL);
    stcMPLLInit.u8PLLState = CLK_PLL_ON;
    stcMPLLInit.PLLCFGR_f.PLLSRC = CLK_PLL_SRC_XTAL;
    (void)CLK_PLLInit(&stcMPLLInit);
    /* 3 cycles for 126MHz ~ 200MHz */
    GPIO_SetReadWaitCycle(GPIO_RD_WAIT3);
    /* Switch driver ability */
    PWC_HighSpeedToHighPerformance();
    /* Set the system clock source */
    CLK_SetSysClockSrc(CLK_SYSCLK_SRC_PLL);
}

//Port Config
static void App_PortCfg(void)
{
    /* GPIO initialize */
    stc_gpio_init_t stcGpioInit;
    /* PH0 set to XTAL-EXT/XTAL-OUT */
    (void)GPIO_StructInit(&stcGpioInit);
    stcGpioInit.u16PinAttr = PIN_ATTR_ANALOG;
    (void)GPIO_Init(GPIO_PORT_H, GPIO_PIN_00, &stcGpioInit);

    /* PH1 set to XTAL-IN */
    (void)GPIO_StructInit(&stcGpioInit);
    stcGpioInit.u16PinAttr = PIN_ATTR_ANALOG;
    (void)GPIO_Init(GPIO_PORT_H, GPIO_PIN_01, &stcGpioInit);

    /* PB8 set to GPIO-Output */
    (void)GPIO_StructInit(&stcGpioInit);
    stcGpioInit.u16PinDir = PIN_DIR_OUT;
    stcGpioInit.u16PinAttr = PIN_ATTR_DIGITAL;
    (void)GPIO_Init(GPIO_PORT_B, GPIO_PIN_08, &stcGpioInit);

    GPIO_SetFunc(GPIO_PORT_A,GPIO_PIN_00,GPIO_FUNC_46);//SPI2-SS0

    GPIO_SetFunc(GPIO_PORT_A,GPIO_PIN_01,GPIO_FUNC_44);//SPI2-MOSI

    GPIO_SetFunc(GPIO_PORT_A,GPIO_PIN_02,GPIO_FUNC_45);//SPI2-MISO

    GPIO_SetFunc(GPIO_PORT_A,GPIO_PIN_03,GPIO_FUNC_47);//SPI2-SCK

}

//Int Config
static void App_IntCfg(void)
{
    stc_irq_signin_config_t stcIrq;

    /* IRQ sign-in */
    stcIrq.enIntSrc = INT_SRC_SPI2_SPRI;
    stcIrq.enIRQn = INT087_IRQn;
    stcIrq.pfnCallback = &INT_SRC_SPI2_SPRI_IrqCallback;
    (void)INTC_IrqSignIn(&stcIrq);
    /* NVIC config */
    NVIC_ClearPendingIRQ(INT087_IRQn);
    NVIC_SetPriority(INT087_IRQn, DDL_IRQ_PRIO_15);
    NVIC_EnableIRQ(INT087_IRQn);

    /* IRQ sign-in */
    stcIrq.enIntSrc = INT_SRC_SPI2_SPTI;
    stcIrq.enIRQn = INT086_IRQn;
    stcIrq.pfnCallback = &INT_SRC_SPI2_SPTI_IrqCallback;
    (void)INTC_IrqSignIn(&stcIrq);
    /* NVIC config */
    NVIC_ClearPendingIRQ(INT086_IRQn);
    NVIC_SetPriority(INT086_IRQn, DDL_IRQ_PRIO_15);
    NVIC_EnableIRQ(INT086_IRQn);

}

/**
* @brief  Main function of the project
* @param  None
* @retval int32_t return value, if needed
*/
int32_t main(void)
{
    /* Register write unprotected for some required peripherals. */
    LL_PERIPH_WE(LL_PERIPH_ALL);
    //Clock Config
    App_ClkCfg();
    //Port Config
    App_PortCfg();
    //Int Config
    App_IntCfg();
    //SPIx Config
    App_SPIxCfg();
    /* Register write protected for some required peripherals. */
    LL_PERIPH_WP(LL_PERIPH_ALL);
    for (;;) {
                        DDL_DelayMS(1000U);
                        GPIO_TogglePins(GPIO_PORT_B, GPIO_PIN_08);
    }
}
static char u8RxBuf = 0;
/* INT_SRC_SPI2_SPRI Callback. */
static void INT_SRC_SPI2_SPRI_IrqCallback(void)
{
    //add your codes here
                 u8RxBuf = (char)SPI_ReadData(CM_SPI1);
}
/* INT_SRC_SPI2_SPTI Callback. */
static void INT_SRC_SPI2_SPTI_IrqCallback(void)
{
    //add your codes here
        SPI_WriteData(CM_SPI1, 0x5A);
}

//SPIx Config
static void App_SPIxCfg(void)
{
    stc_spi_init_t stcSpiInit;
    stc_spi_delay_t stcSpiDelay;

    /* Enable SPI2 clock */
    FCG_Fcg1PeriphClockCmd(FCG1_PERIPH_SPI2, ENABLE);
    /************************* Configure SPI2***************************/
    SPI_StructInit(&stcSpiInit);
    stcSpiInit.u32WireMode = SPI_4_WIRE;
    stcSpiInit.u32TransMode = SPI_FULL_DUPLEX;
    stcSpiInit.u32MasterSlave = SPI_MASTER;
    stcSpiInit.u32Parity = SPI_PARITY_INVD;
    stcSpiInit.u32SpiMode = SPI_MD_1;
    stcSpiInit.u32BaudRatePrescaler = SPI_BR_CLK_DIV256;
    stcSpiInit.u32DataBits = SPI_DATA_SIZE_8BIT;
    stcSpiInit.u32FirstBit = SPI_FIRST_MSB;
    stcSpiInit.u32SuspendMode = SPI_COM_SUSP_FUNC_OFF;
    stcSpiInit.u32FrameLevel = SPI_1_FRAME;
    (void)SPI_Init(CM_SPI2, &stcSpiInit);

    SPI_DelayStructInit(&stcSpiDelay);
    stcSpiDelay.u32IntervalDelay = SPI_INTERVAL_TIME_1SCK;
    stcSpiDelay.u32ReleaseDelay = SPI_RELEASE_TIME_1SCK;
    stcSpiDelay.u32SetupDelay = SPI_SETUP_TIME_1SCK;
    (void)SPI_DelayTimeConfig(CM_SPI2, &stcSpiDelay);

    /* SPI loopback function configuration */
    SPI_LoopbackModeConfig(CM_SPI2, SPI_LOOPBACK_INVD);
    /* SPI parity check error self diagnosis configuration */
    SPI_ParityCheckCmd(CM_SPI2, DISABLE);
    /* SPI valid SS signal configuration */
    SPI_SSPinSelect(CM_SPI2, SPI_PIN_SS0);
    /* SPI SS signal valid level configuration */
    SPI_SSValidLevelConfig(CM_SPI2, SPI_PIN_SS0, DISABLE);
    /* Enable interrupt function*/
    SPI_IntCmd(CM_SPI2, SPI_INT_RX_BUF_FULL | SPI_INT_TX_BUF_EMPTY, ENABLE);
    /* Enable SPI2 */
    SPI_Cmd(CM_SPI2, ENABLE);
}

/**
* @}
*/

/**
* @}
*/

/*******************************************************************************
* EOF (not truncated)
******************************************************************************/





SPI1源代码:

SPI1
/**
*******************************************************************************
* @file  hc32_ll_utility.c
* @brief This file provides utility functions for DDL.
@verbatim
   Change Logs:
   Date             Author          Notes
   2022-03-31       CDT             First version
   2022-06-30       CDT             Support re-target printf for IAR EW version 9 or later
   2023-06-30       CDT             Modify register USART DR to USART TDR
                                    Prohibit DDL_DelayMS and DDL_DelayUS functions from being optimized
@endverbatim
*******************************************************************************
* Copyright (C) 2022-2023, Xiaohua Semiconductor Co., Ltd. All rights reserved.
*
* This software component is licensed by XHSC under BSD 3-Clause license
* (the "License"); You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
*                    opensource.org/licenses/BSD-3-Clause
*
*******************************************************************************
*/

/*******************************************************************************
* Include files
******************************************************************************/
#include "hc32_ll_utility.h"

/**
* @addtogroup LL_Driver
* @{
*/

/**
* @defgroup LL_UTILITY UTILITY
* @brief DDL Utility Driver
* @{
*/

#if (LL_UTILITY_ENABLE == DDL_ON)

/*******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/

/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/

/*******************************************************************************
* Global variable definitions (declared in header file with 'extern')
******************************************************************************/

/*******************************************************************************
* Local function prototypes ('static')
******************************************************************************/

/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/
/**
* @defgroup UTILITY_Local_Variables UTILITY Local Variables
* @{
*/

static uint32_t m_u32TickStep = 0UL;
static __IO uint32_t m_u32TickCount = 0UL;

#if (LL_PRINT_ENABLE == DDL_ON)
static void *m_pvPrintDevice = NULL;
static uint32_t m_u32PrintTimeout = 0UL;
#endif

/**
* @}
*/

/*******************************************************************************
* Function implementation - global ('extern') and local ('static')
******************************************************************************/

/**
* @defgroup UTILITY_Local_Functions UTILITY Local Functions
* @{
*/
#if (LL_PRINT_ENABLE == DDL_ON)

/**
* @brief  Set print device.
* @param  [in] pvPrintDevice           Pointer to print device
* @retval None
*/
__STATIC_INLINE void LL_SetPrintDevice(void *pvPrintDevice)
{
    m_pvPrintDevice = pvPrintDevice;
}

/**
* @brief  Get print device.
* @param  None
* @retval Pointer to print device
*/
__STATIC_INLINE void *LL_GetPrintDevice(void)
{
    return m_pvPrintDevice;
}

/**
* @brief  Set print timeout.
* @param  [in] u32Timeout              Print timeout value
* @retval None
*/
__STATIC_INLINE void LL_SetPrintTimeout(uint32_t u32Timeout)
{
    m_u32PrintTimeout = u32Timeout;
}

/**
* @brief  Get print timeout.
* @param  None
* @retval Print timeout value
*/
__STATIC_INLINE uint32_t LL_GetPrintTimeout(void)
{
    return m_u32PrintTimeout;
}
#endif /* LL_PRINT_ENABLE */

/**
* @}
*/

/**
* @defgroup UTILITY_Global_Functions UTILITY Global Functions
* @{
*/

/**
* @brief Delay function, delay ms approximately
* @param [in] u32Count                   ms
* @retval None
*/
#if defined (__CC_ARM)  /*!< ARM Compiler */
#pragma push
#pragma O0
#endif
__NO_OPTIMIZE void DDL_DelayMS(uint32_t u32Count)
{
    __IO uint32_t i;
    const uint32_t u32Cyc = (HCLK_VALUE + 10000UL - 1UL) / 10000UL;

    while (u32Count-- > 0UL) {
        i = u32Cyc;
        while (i-- > 0UL) {
        }
    }
}

/**
* @brief Delay function, delay us approximately
* @param [in] u32Count                   us
* @retval None
*/
__NO_OPTIMIZE void DDL_DelayUS(uint32_t u32Count)
{
    __IO uint32_t i;
    const uint32_t u32Cyc = (HCLK_VALUE + 10000000UL - 1UL) / 10000000UL;

    while (u32Count-- > 0UL) {
        i = u32Cyc;
        while (i-- > 0UL) {
        }
    }
}
#if defined (__CC_ARM)  /*!< ARM Compiler */
#pragma pop
#endif

/**
* @brief This function Initializes the interrupt frequency of the SysTick.
* @param [in] u32Freq                  SysTick interrupt frequency (1 to 1000).
* @retval int32_t:
*           - LL_OK: SysTick Initializes succeed
*           - LL_ERR: SysTick Initializes failed
*/
__WEAKDEF int32_t SysTick_Init(uint32_t u32Freq)
{
    int32_t i32Ret = LL_ERR;

    if ((0UL != u32Freq) && (u32Freq <= 1000UL)) {
        m_u32TickStep = 1000UL / u32Freq;
        /* Configure the SysTick interrupt */
        if (0UL == SysTick_Config(HCLK_VALUE / u32Freq)) {
            i32Ret = LL_OK;
        }
    }

    return i32Ret;
}

/**
* @brief This function provides minimum delay (in milliseconds).
* @param [in] u32Delay                 Delay specifies the delay time.
* @retval None
*/
__WEAKDEF void SysTick_Delay(uint32_t u32Delay)
{
    const uint32_t tickStart = SysTick_GetTick();
    uint32_t tickEnd = u32Delay;
    uint32_t tickMax;

    if (m_u32TickStep != 0UL) {
        tickMax = 0xFFFFFFFFUL / m_u32TickStep * m_u32TickStep;
        /* Add a freq to guarantee minimum wait */
        if ((u32Delay >= tickMax) || ((tickMax - u32Delay) < m_u32TickStep)) {
            tickEnd = tickMax;
        }
        while ((SysTick_GetTick() - tickStart) < tickEnd) {
        }
    }
}

/**
* @brief This function is called to increment a global variable "u32TickCount".
* @NOTE  This variable is incremented in SysTick ISR.
* @param None
* @retval None
*/
__WEAKDEF void SysTick_IncTick(void)
{
    m_u32TickCount += m_u32TickStep;
}

/**
* @brief Provides a tick value in millisecond.
* @param None
* @retval Tick value
*/
__WEAKDEF uint32_t SysTick_GetTick(void)
{
    return m_u32TickCount;
}

/**
* @brief Suspend SysTick increment.
* @param None
* @retval None
*/
__WEAKDEF void SysTick_Suspend(void)
{
    /* Disable SysTick Interrupt */
    SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk;
}

/**
* @brief Resume SysTick increment.
* @param None
* @retval None
*/
__WEAKDEF void SysTick_Resume(void)
{
    /* Enable SysTick Interrupt */
    SysTick->CTRL  |= SysTick_CTRL_TICKINT_Msk;
}

#ifdef __DEBUG
/**
* @brief DDL assert error handle function
* @param [in] file                     Point to the current assert the wrong file.
* @param [in] line                     Point line assert the wrong file in the current.
* @retval None
*/
__WEAKDEF void DDL_AssertHandler(const char *file, int line)
{
    /* Users can re-implement this function to print information */
    DDL_Printf("Wrong parameters value: file %s on line %d\r\n", file, line);

    for (;;) {
    }
}
#endif /* __DEBUG */

#if (LL_PRINT_ENABLE == DDL_ON)

#if (defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)) || \
    (defined (__ICCARM__) && (__VER__ < 9000000)) || (defined (__CC_ARM))
/**
* @brief  Re-target fputc function.
* @param  [in] ch
* @param  [in] f
* @retval int32_t
*/
int32_t fputc(int32_t ch, FILE *f)
{
    (void)f;  /* Prevent unused argument compilation warning */

    return (LL_OK == DDL_ConsoleOutputChar((char)ch)) ? ch : -1;
}

#elif (defined (__ICCARM__) && (__VER__ >= 9000000))
#include <LowLevelIOInterface.h>
#pragma module_name = "?__write"
size_t __dwrite(int handle, const unsigned char *buffer, size_t size)
{
    size_t nChars = 0;
    size_t i;

    if (buffer == NULL) {
        /*
         * This means that we should flush internal buffers.  Since we
         * don't we just return.  (Remember, "handle" == -1 means that all
         * handles should be flushed.)
         */
        return 0;
    }

    /* This template only writes to "standard out" and "standard err",
     * for all other file handles it returns failure. */
    if (handle != _LLIO_STDOUT && handle != _LLIO_STDERR) {
        return _LLIO_ERROR;
    }

    for (i = 0; i < size; i++) {
        if (DDL_ConsoleOutputChar((char)buffer) < 0) {
            return _LLIO_ERROR;
        }

        ++nChars;
    }

    return nChars;
}

#elif defined ( __GNUC__ ) && !defined (__CC_ARM)
/**
* @brief  Re-target _write function.
* @param  [in] fd
* @param  [in] data
* @param  [in] size
* @retval int32_t
*/
int32_t _write(int fd, char data[], int32_t size)
{
    int32_t i = -1;

    if (NULL != data) {
        (void)fd;  /* Prevent unused argument compilation warning */

        for (i = 0; i < size; i++) {
            if (LL_OK != DDL_ConsoleOutputChar(data)) {
                break;
            }
        }
    }

    return i ? i : -1;
}
#endif

/**
* @brief  Initialize printf function
* @param  [in] vpDevice                Pointer to print device
* @param  [in] u32Param                Print device parameter
* @param  [in] pfnPreinit              The function pointer for initializing clock, port, print device etc.
* @retval int32_t:
*           - LL_OK:                   Initialize successfully.
*           - LL_ERR:                  The callback function pfnPreinit occurs error.
*           - LL_ERR_INVD_PARAM:       The pointer pfnPreinit is NULL.
*/
int32_t LL_PrintfInit(void *vpDevice, uint32_t u32Param, int32_t (*pfnPreinit)(void *vpDevice, uint32_t u32Param))
{
    int32_t i32Ret = LL_ERR_INVD_PARAM;

    if (NULL != pfnPreinit) {
        i32Ret = pfnPreinit(vpDevice, u32Param);   /* The callback function initialize clock, port, print device etc */
        if (LL_OK == i32Ret) {
            LL_SetPrintDevice(vpDevice);
            LL_SetPrintTimeout((u32Param == 0UL) ? 0UL : (HCLK_VALUE / u32Param));
        } else {
            i32Ret = LL_ERR;
            DDL_ASSERT(i32Ret == LL_OK);           /* Initialize unsuccessfully */
        }
    }

    return i32Ret;
}

/**
* @brief  Transmit character.
* @param  [in] cData                   The character for transmitting
* @retval int32_t:
*           - LL_OK:                   Transmit successfully.
*           - LL_ERR_TIMEOUT:          Transmit timeout.
*           - LL_ERR_INVD_PARAM:       The print device is invalid.
*/
__WEAKDEF int32_t DDL_ConsoleOutputChar(char cData)
{
    uint32_t u32TxEmpty = 0UL;
    __IO uint32_t u32TmpCount = 0UL;
    int32_t i32Ret = LL_ERR_INVD_PARAM;
    uint32_t u32Timeout = LL_GetPrintTimeout();
    CM_USART_TypeDef *USARTx = (CM_USART_TypeDef *)LL_GetPrintDevice();

    if (NULL != USARTx) {
        /* Wait TX data register empty */
        while ((u32TmpCount <= u32Timeout) && (0UL == u32TxEmpty)) {
            u32TxEmpty = READ_REG32_BIT(USARTx->SR, USART_SR_TXE);
            u32TmpCount++;
        }

        if (0UL != u32TxEmpty) {
            WRITE_REG16(USARTx->TDR, (uint16_t)cData);
            i32Ret = LL_OK;
        } else {
            i32Ret = LL_ERR_TIMEOUT;
        }
    }

    return i32Ret;
}

#endif /* LL_PRINT_ENABLE */

/**
* @}
*/

#endif /* LL_UTILITY_ENABLE */

/**
* @}
*/

/**
* @}
*/

/*******************************************************************************
* EOF (not truncated)
******************************************************************************/



有没有大佬遇到过或者能查出来问题的?
————————————————
版权声明:本文为CSDN博主「happy__yun」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/happy__yun/article/details/153821211

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

本版积分规则

97

主题

300

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部