使用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
|
|