1
完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
/**************************************************************************//**
* @file main.c * @version V2.0 * $Revision: 6 $ * $Date: 14/08/05 11:13a $ * @brief * Demonstrate how to communicate with an off-chip SPI slave device with Dual I/O mode and FIFO mode. * This sample code needs to work with SPI_SlaveDualIOMode sample code. * @note * Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved. * ******************************************************************************/ #include #include "NUC123.h" #define TEST_COUNT 16 uint32_t g_au32SourceData[TEST_COUNT]; uint32_t g_au32DestinationData[TEST_COUNT]; volatile uint32_t g_u32TxDataCount; volatile uint32_t g_u32RxDataCount; /* Function prototype declaration */ void SYS_Init(void); void SPI_Init(void); /* ------------- */ /* Main function */ /* ------------- */ int main(void) { uint32_t u32DataCount; /* Unlock protected registers */ SYS_UnlockReg(); /* Init System, IP clock and multi-function I/O */ SYS_Init(); /* Lock protected registers */ SYS_LockReg(); /* Configure UART0: 115200, 8-bit word, no parity bit, 1 stop bit. */ UART_Open(UART0, 115200); /* Init SPI */ SPI_Init(); printf("\n\n"); printf("+--------------------------------------------------------+\n"); printf("| SPI Master Mode Sample Code |\n"); printf("+--------------------------------------------------------+\n"); printf("\n"); printf("Configure SPI0 as a master.\n"); printf("Bit length of a transaction: 32\n"); printf("The I/O connection for SPI0:\n"); printf(" SPI0_SS0 (PC.0)\n SPI0_CLK (PC.1)\n"); printf(" SPI0_MISO0 (PC.2)\n SPI0_MOSI0 (PC.3)\n\n"); printf("SPI controller will enable Dual I/O mode and FIFO mode, then transfer %d data to a off-chip slave device.\n", TEST_COUNT); printf("Afterward the SPI controller will receive %d data from the off-chip slave device.\n", TEST_COUNT); printf("After the transfer is done, the %d received data will be printed out.\n", TEST_COUNT); printf("The SPI master configuration is ready.\n"); for(u32DataCount = 0; u32DataCount < TEST_COUNT; u32DataCount++) { /* Write the initial value to source buffer */ g_au32SourceData[u32DataCount] = 0x00550000 + u32DataCount; /* Clear destination buffer */ g_au32DestinationData[u32DataCount] = 0; } printf("Before starting the data transfer, make sure the slave device is ready.\n"); printf("Press any key to start the Dual I/O output transfer."); getchar(); printf("\n"); /* Enable Dual I/O output mode */ SPI_ENABLE_DUAL_OUTPUT_MODE(SPI0); /* Enable FIFO mode, set TX FIFO threshold, enable TX FIFO threshold interrupt and RX FIFO time-out interrupt */ SPI_EnableFIFO(SPI0, 2, 2); SPI_EnableInt(SPI0, SPI_FIFO_TX_INT_MASK | SPI_FIFO_TIMEOUT_INT_MASK); g_u32TxDataCount = 0; g_u32RxDataCount = 0; NVIC_EnableIRQ(SPI0_IRQn); /* Wait for transfer done */ while(g_u32RxDataCount < TEST_COUNT); /* Enable Dual I/O input mode */ SPI_ENABLE_DUAL_INPUT_MODE(SPI0); printf("Dual I/O output transfer is done. Before starting the Dual I/O input transfer, make sure the slave device is ready.\n"); printf("Press any key to start the Dual I/O input transfer."); getchar(); printf("\n"); g_u32TxDataCount = 0; g_u32RxDataCount = 0; SPI_EnableInt(SPI0, SPI_FIFO_TX_INT_MASK | SPI_FIFO_TIMEOUT_INT_MASK); /* Wait for transfer done */ while(g_u32RxDataCount < TEST_COUNT); /* Print the received data */ printf("Received data:\n"); for(u32DataCount = 0; u32DataCount < TEST_COUNT; u32DataCount++) { printf("%d:\t0x%X\n", u32DataCount, g_au32DestinationData[u32DataCount]); } /* Disable TX FIFO threshold interrupt and RX FIFO time-out interrupt */ SPI_DisableInt(SPI0, SPI_FIFO_TX_INT_MASK | SPI_FIFO_TIMEOUT_INT_MASK); NVIC_DisableIRQ(SPI0_IRQn); printf("\n\nExit SPI driver sample code.\n"); /* Disable SPI0 peripheral clock */ SPI_Close(SPI0); while(1); } void SYS_Init(void) { /*---------------------------------------------------------------------------------------------------------*/ /* Init System Clock */ /*---------------------------------------------------------------------------------------------------------*/ /* Enable XT1_OUT (PF0) and XT1_IN (PF1) */ SYS->GPF_MFP |= SYS_GPF_MFP_PF0_XT1_OUT | SYS_GPF_MFP_PF1_XT1_IN; /* Enable external 12MHz XTAL */ CLK_EnableXtalRC(CLK_PWRCON_XTL12M_EN_Msk); /* Waiting for clock ready */ CLK_WaitClockReady(CLK_CLKSTATUS_XTL12M_STB_Msk); /* Switch HCLK clock source to HXT and HCLK source divide 1 */ CLK_SetHCLK(CLK_CLKSEL0_HCLK_S_HXT, CLK_CLKDIV_HCLK(1)); /* Select HXT as the clock source of UART0 */ CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART_S_HXT, CLK_CLKDIV_UART(1)); /* Select HCLK as the clock source of SPI0 */ CLK_SetModuleClock(SPI0_MODULE, CLK_CLKSEL1_SPI0_S_HCLK, MODULE_NoMsk); /* Enable UART peripheral clock */ CLK_EnableModuleClock(UART0_MODULE); /* Enable SPI0 peripheral clock */ CLK_EnableModuleClock(SPI0_MODULE); /* Update System Core Clock */ /* User can use SystemCoreClockUpdate() to calculate PllClock, SystemCoreClock and CyclesPerUs automatically. */ SystemCoreClockUpdate(); /*---------------------------------------------------------------------------------------------------------*/ /* Init I/O Multi-function */ /*---------------------------------------------------------------------------------------------------------*/ /* Set PB multi-function pins for UART0 RXD and TXD */ SYS->GPB_MFP = SYS_GPB_MFP_PB0_UART0_RXD | SYS_GPB_MFP_PB1_UART0_TXD; /* Setup SPI0 multi-function pins */ SYS->GPC_MFP = SYS_GPC_MFP_PC0_SPI0_SS0 | SYS_GPC_MFP_PC1_SPI0_CLK | SYS_GPC_MFP_PC2_SPI0_MISO0 | SYS_GPC_MFP_PC3_SPI0_MOSI0; SYS->ALT_MFP = SYS_ALT_MFP_PC0_SPI0_SS0 | SYS_ALT_MFP_PC1_SPI0_CLK | SYS_ALT_MFP_PC2_SPI0_MISO0 | SYS_ALT_MFP_PC3_SPI0_MOSI0; } void SPI_Init(void) { /*---------------------------------------------------------------------------------------------------------*/ /* Init SPI */ /*---------------------------------------------------------------------------------------------------------*/ /* Configure SPI0 as a master, clock idle low, 32-bit transaction, drive output on falling clock edge and latch input on rising edge. */ /* Set IP clock divider. SPI clock rate = 2 MHz */ SPI_Open(SPI0, SPI_MASTER, SPI_MODE_0, 32, 2000000); /* Enable the automatic hardware slave select function. Select the SPI0_SS0 pin and configure as low-active. */ SPI_EnableAutoSS(SPI0, SPI_SS0, SPI_SS_ACTIVE_LOW); } void SPI0_IRQHandler(void) { /* Check RX EMPTY flag */ while(SPI_GET_RX_FIFO_EMPTY_FLAG(SPI0) == 0) { /* Read RX FIFO */ g_au32DestinationData[g_u32RxDataCount++] = SPI_READ_RX0(SPI0); } /* Check TX FULL flag and TX data count */ while((SPI_GET_TX_FIFO_FULL_FLAG(SPI0) == 0) && (g_u32TxDataCount < TEST_COUNT)) { /* Write to TX FIFO */ SPI_WRITE_TX0(SPI0, g_au32SourceData[g_u32TxDataCount++]); } if(g_u32TxDataCount >= TEST_COUNT) SPI_DisableInt(SPI0, SPI_FIFO_TX_INT_MASK); /* Disable TX FIFO threshold interrupt */ /* Check the RX FIFO time-out interrupt flag */ if(SPI_GetIntFlag(SPI0, SPI_FIFO_TIMEOUT_INT_MASK)) { /* If RX FIFO is not empty, read RX FIFO. */ while(SPI_GET_RX_FIFO_EMPTY_FLAG(SPI0) == 0) g_au32DestinationData[g_u32RxDataCount++] = SPI_READ_RX0(SPI0); } } /*** (C) COPYRIGHT 2014 Nuvoton Technology Corp. ***/ /**************************************************************************//** * @file main.c * @version V2.0 * $Revision: 6 $ * $Date: 14/08/05 11:13a $ * @brief * Demonstrate how to communicate with an off-chip SPI master device with Dual I/O mode and FIFO mode. * This sample code needs to work with SPI_MasterDualIOMode sample code. * @note * Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved. * ******************************************************************************/ #include #include "NUC123.h" #define TEST_COUNT 16 uint32_t g_au32SourceData[TEST_COUNT]; uint32_t g_au32DestinationData[TEST_COUNT]; volatile uint32_t g_u32TxDataCount; volatile uint32_t g_u32RxDataCount; /* Function prototype declaration */ void SYS_Init(void); void SPI_Init(void); /* ------------- */ /* Main function */ /* ------------- */ int main(void) { volatile uint32_t u32TxDataCount, u32RxDataCount; /* Unlock protected registers */ SYS_UnlockReg(); /* Init System, IP clock and multi-function I/O */ SYS_Init(); /* Lock protected registers */ SYS_LockReg(); /* Configure UART0: 115200, 8-bit word, no parity bit, 1 stop bit. */ UART_Open(UART0, 115200); /* Init SPI */ SPI_Init(); /* Enable Dual I/O input mode */ SPI_ENABLE_DUAL_INPUT_MODE(SPI0); /* Enable FIFO mode and set FIFO threshold. */ SPI_EnableFIFO(SPI0, 2, 2); printf("\n\n"); printf("+-----------------------------------------------------+\n"); printf("| SPI Slave Mode Sample Code |\n"); printf("+-----------------------------------------------------+\n"); printf("\n"); printf("Configure SPI0 as a slave.\n"); printf("Bit length of a transaction: 32\n"); printf("The I/O connection for SPI0:\n"); printf(" SPI0_SS0 (PC.0)\n SPI0_CLK (PC.1)\n"); printf(" SPI0_MISO0 (PC.2)\n SPI0_MOSI0 (PC.3)\n\n"); printf("SPI controller will enable Dual I/O mode and FIFO mode.\n"); printf("In the first stage, the SPI controller will receive %d data from a off-chip master device.\n", TEST_COUNT); printf("After the transfer is done, the %d received data will be printed out.\n", TEST_COUNT); printf("In the second stage, the SPI controller will transfer %d data to the off-chip master device.\n", TEST_COUNT); for(u32TxDataCount = 0; u32TxDataCount < TEST_COUNT; u32TxDataCount++) { /* Write the initial value to source buffer */ g_au32SourceData[u32TxDataCount] = 0x00AA0000 + u32TxDataCount; /* Clear destination buffer */ g_au32DestinationData[u32TxDataCount] = 0; } u32RxDataCount = 0; printf("< Stage 1 >\n"); printf("Press any key to start the Dual I/O input transfer if the master device configuration is ready."); getchar(); printf("\n"); /* Access RX FIFO */ while(u32RxDataCount < TEST_COUNT) { /* Check RX EMPTY flag */ if(SPI_GET_RX_FIFO_EMPTY_FLAG(SPI0) == 0) g_au32DestinationData[u32RxDataCount++] = SPI_READ_RX0(SPI0); /* Read RX FIFO */ } /* Print the received data */ printf("Received data:\n"); for(u32RxDataCount = 0; u32RxDataCount < TEST_COUNT; u32RxDataCount++) { printf("%d:\t0x%X\n", u32RxDataCount, g_au32DestinationData[u32RxDataCount]); } /* Enable Dual I/O output mode */ SPI_ENABLE_DUAL_OUTPUT_MODE(SPI0); u32TxDataCount = 0; u32RxDataCount = 0; printf("< Stage 2 >\n"); printf("Enable Dual I/O output mode. Slave is ready to transfer.\n"); /* Access TX and RX FIFO */ while(u32RxDataCount < TEST_COUNT) { /* Check TX FULL flag and TX data count */ if((SPI_GET_TX_FIFO_FULL_FLAG(SPI0) == 0) && (u32TxDataCount < TEST_COUNT)) SPI_WRITE_TX0(SPI0, g_au32SourceData[u32TxDataCount++]); /* Write to TX FIFO */ /* Check RX EMPTY flag */ if(SPI_GET_RX_FIFO_EMPTY_FLAG(SPI0) == 0) g_au32DestinationData[u32RxDataCount++] = SPI_READ_RX0(SPI0); /* Read RX FIFO */ } printf("\n\nExit SPI driver sample code.\n"); /* Disable SPI0 peripheral clock */ SPI_Close(SPI0); while(1); } void SYS_Init(void) { /*---------------------------------------------------------------------------------------------------------*/ /* Init System Clock */ /*---------------------------------------------------------------------------------------------------------*/ /* Enable XT1_OUT (PF0) and XT1_IN (PF1) */ SYS->GPF_MFP |= SYS_GPF_MFP_PF0_XT1_OUT | SYS_GPF_MFP_PF1_XT1_IN; /* Enable external 12 MHz XTAL */ CLK_EnableXtalRC(CLK_PWRCON_XTL12M_EN_Msk); /* Waiting for clock ready */ CLK_WaitClockReady(CLK_CLKSTATUS_XTL12M_STB_Msk); /* Switch HCLK clock source to HXT and HCLK source divide 1 */ CLK_SetHCLK(CLK_CLKSEL0_HCLK_S_HXT, CLK_CLKDIV_HCLK(1)); /* Select HXT as the clock source of UART0 */ CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART_S_HXT, CLK_CLKDIV_UART(1)); /* Select HCLK as the clock source of SPI0 */ CLK_SetModuleClock(SPI0_MODULE, CLK_CLKSEL1_SPI0_S_HCLK, MODULE_NoMsk); /* Enable UART peripheral clock */ CLK_EnableModuleClock(UART0_MODULE); /* Enable SPI0 peripheral clock */ CLK_EnableModuleClock(SPI0_MODULE); /* Update System Core Clock */ /* User can use SystemCoreClockUpdate() to calculate PllClock, SystemCoreClock and CyclesPerUs automatically. */ SystemCoreClockUpdate(); /*---------------------------------------------------------------------------------------------------------*/ /* Init I/O Multi-function */ /*---------------------------------------------------------------------------------------------------------*/ /* Set PB multi-function pins for UART0 RXD and TXD */ SYS->GPB_MFP = SYS_GPB_MFP_PB0_UART0_RXD | SYS_GPB_MFP_PB1_UART0_TXD; /* Setup SPI0 multi-function pins */ SYS->GPC_MFP = SYS_GPC_MFP_PC0_SPI0_SS0 | SYS_GPC_MFP_PC1_SPI0_CLK | SYS_GPC_MFP_PC2_SPI0_MISO0 | SYS_GPC_MFP_PC3_SPI0_MOSI0; SYS->ALT_MFP = SYS_ALT_MFP_PC0_SPI0_SS0 | SYS_ALT_MFP_PC1_SPI0_CLK | SYS_ALT_MFP_PC2_SPI0_MISO0 | SYS_ALT_MFP_PC3_SPI0_MOSI0; } void SPI_Init(void) { /*---------------------------------------------------------------------------------------------------------*/ /* Init SPI */ /*---------------------------------------------------------------------------------------------------------*/ /* Configure SPI0 as a slave, clock idle low, 32-bit transaction, drive output on falling clock edge and latch input on rising edge. */ /* Configure SPI0 as a low level active device. SPI peripheral clock rate is equal to system clock rate. */ SPI_Open(SPI0, SPI_SLAVE, SPI_MODE_0, 32, NULL); } /*** (C) COPYRIGHT 2014 Nuvoton Technology Corp. ***/ |
|
相关推荐
1个回答
|
|
ote: Dual I/O mode can significantly improve the reading and writing speed of SPI Flash, but it requires the SPI Flash to support Dual I/O mode.
To use Dual I/O mode, the SPI interface needs to be configured to use two data lines for sending and receiving data. The following steps can be followed to enable Dual I/O mode on an STM32 microcontroller: 1. Initialize the SPI interface in Dual I/O mode by setting the "Data Size" as "Half-Word" and the "Clock Phase" as "Second Edge." This can be done by modifying the SPI_InitTypeDef structure and calling the HAL_SPI_Init() function. 2. Enable Dual I/O mode on the SPI Flash chip by sending the appropriate command over the SPI interface. The command and its syntax may vary depending on the SPI Flash chip being used. Refer to the SPI Flash datasheet for details. 3. After enabling Dual I/O mode, the SPI Read/Write commands need to be modified to use Dual I/O mode. This can be done by replacing the standard SPI commands (such as "SPI_ReadByte()" and "SPI_WriteByte()") with Dual I/O compatible commands (such as "DualIO_ReadHalfWord()" and "DualIO_WriteHalfWord()"). 4. Use the HAL_SPI_TransmitReceive_DMA() function instead of the standard HAL_SPI_TransmitReceive() function, as it allows data transfer using the FIFO mode. This can improve the data transfer rate significantly. 5. Finally, the SPI interface needs to be optimized by adjusting the SPI clock frequency and other parameters according to the SPI Flash chip specifications. With these steps, the SPI Flash can be accessed using Dual I/O and FIFO mode, which improves the data transfer rate compared to standard SPI mode. |
|
|
|
只有小组成员才能发言,加入小组>>
793 浏览 0 评论
1152 浏览 1 评论
2528 浏览 5 评论
2861 浏览 9 评论
移植了freeRTOS到STMf103之后显示没有定义的原因?
2711 浏览 6 评论
keil5中manage run-time environment怎么是灰色,不可以操作吗?
1073浏览 3评论
195浏览 2评论
457浏览 2评论
370浏览 2评论
M0518 PWM的电压输出只有2V左右,没有3.3V是怎么回事?
455浏览 1评论
小黑屋| 手机版| Archiver| 德赢Vwin官网 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-23 03:53 , Processed in 1.032629 second(s), Total 78, Slave 59 queries .
Powered by 德赢Vwin官网 网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
德赢Vwin官网 观察
版权所有 © 湖南华秋数字科技有限公司
德赢Vwin官网 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号