- /*!
- * [url=home.php?mod=space&uid=288409]@file[/url] main.c
- *
- * [url=home.php?mod=space&uid=247401]@brief[/url] Main program body
- *
- * [url=home.php?mod=space&uid=895143]@version[/url] V1.0.3
- *
- * [url=home.php?mod=space&uid=212281]@date[/url] 2022-09-20
- *
- * @attention
- *
- * Copyright (C) 2020-2022 Geehy Semiconductor
- *
- * You may not use this file except in compliance with the
- * GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
- *
- * The program is only for reference, which is distributed in the hope
- * that it will be useful and instructional for customers to develop
- * their software. Unless required by applicable law or agreed to in
- * writing, the program is distributed on an "AS IS" BASIS, WITHOUT
- * ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
- * See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
- * and limitations under the License.
- */
- /* Includes */
- #include "Board.h"
- #include "stdio.h"
- #include "apm32f0xx_gpio.h"
- #include "apm32f0xx_misc.h"
- #include "apm32f0xx_eint.h"
- #include "apm32f0xx_spi.h"
- /** @addtogroup Examples
- @{
- */
- /** @addtogroup SPI_TwoBoards_Master
- @{
- */
- /** @defgroup SPI_TwoBoards_Master_Macros Macros
- @{
- */
- /* printf function configs to USART2 */
- #define DEBUG_USART USART2
- /* Buffsize */
- #define BuffSize 56
- /**@} end of group SPI_TwoBoards_Master_Macros */
- /** @defgroup SPI_TwoBoards_Master_Enumerations Enumerations
- @{
- */
- /**@} end of group SPI_TwoBoards_Master_Enumerations */
- /** @defgroup SPI_TwoBoards_Master_Structures Structures
- @{
- */
- /**@} end of group SPI_TwoBoards_Master_Structures */
- /** @defgroup SPI_TwoBoards_Master_Variables Variables
- @{
- */
- /* SPI TX Buffer*/
- uint8_t SPI_Buffer_TX[BuffSize] =
- {
- 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0X07,
- 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0X07,
- 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0X07,
- 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0X07,
- 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0X07,
- 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0X07,
- 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0X07,
- 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0X07,
- };
- /**@} end of group SPI_TwoBoards_Master_Variables */
- /** @defgroup SPI_TwoBoards_Master_Functions Functions
- @{
- */
- /* Delay */
- void Delay(uint16_t count);
- /* SPI Init */
- void APM_MINI_SPIInit(void);
- /* Buffer Compare*/
- BOOL BufferCompare(uint8_t* buf1, uint8_t* buf2, uint8_t size);
- /*!
- * @brief Main program
- *
- * @param None
- *
- * @retval None
- *
- * @note
- */
- int main(void)
- {
- /* index of TxData*/
- volatile uint8_t TxIdx = 0;
- /* index of RxData*/
- volatile uint8_t RxIdx = 0;
- /* SPI Receive Buffer*/
- uint8_t SPI_Buffer_RX[BuffSize] = {0x00};
- APM_MINI_LEDInit(LED2);
- APM_MINI_LEDInit(LED3);
- APM_MINI_COMInit(COM2);
- APM_MINI_SPIInit();
- printf("I am Master\r\n");
- /* Low Down NSS for communication*/
- GPIO_ClearBit(GPIOA, GPIO_PIN_8);
- while (TxIdx < BuffSize)
- {
- while (SPI_ReadStatusFlag(SPI2, SPI_FLAG_TXBE) == RESET);
- SPI_I2S_TxData16(SPI2, SPI_Buffer_TX[TxIdx++]);
- while (SPI_ReadStatusFlag(SPI2, SPI_FLAG_RXBNE) == RESET);
- SPI_Buffer_RX[RxIdx++] = SPI_I2S_RxData16(SPI2);
- }
- for (int i = 0; i < BuffSize; i++)
- {
- if (i % 7 == 0)
- {
- printf("\r\n");
- }
- printf(" %02x ,", SPI_Buffer_RX[i]);
- }
- /* Set NSS high for close communication*/
- GPIO_SetBit(GPIOA, GPIO_PIN_8);
- /* Compare Buffer*/
- if (BufferCompare(SPI_Buffer_TX, SPI_Buffer_RX, BuffSize) == TRUE)
- {
- APM_MINI_LEDOn(LED2);
- }
- for (;;)
- {
- Delay(0x5f5f);
- APM_MINI_LEDToggle(LED3);
- }
- }
- /*!
- * @brief SPI Init
- *
- * @param None
- *
- * @retval None
- *
- * @note
- */
- void APM_MINI_SPIInit(void)
- {
- GPIO_Config_T gpioConfig;
- SPI_Config_T spiConfig;
- /* Enable related clock*/
- RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_SPI2);
- RCM_EnableAHBPeriphClock(RCM_AHB_PERIPH_GPIOA|RCM_AHB_PERIPH_GPIOB);
- RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_SYSCFG);
- /* Config alter function*/
- // GPIO_ConfigPinAF(GPIOA, GPIO_PIN_SOURCE_5, GPIO_AF_PIN0);
- // GPIO_ConfigPinAF(GPIOA, GPIO_PIN_SOURCE_6, GPIO_AF_PIN0);
- // GPIO_ConfigPinAF(GPIOA, GPIO_PIN_SOURCE_7, GPIO_AF_PIN0);
-
- GPIO_ConfigPinAF(GPIOB, GPIO_PIN_SOURCE_13, GPIO_AF_PIN0);
- GPIO_ConfigPinAF(GPIOB, GPIO_PIN_SOURCE_14, GPIO_AF_PIN0);
- GPIO_ConfigPinAF(GPIOB, GPIO_PIN_SOURCE_15, GPIO_AF_PIN0);
-
- /* config PIN_13->SCK , PIN_15->MOSI*/
- gpioConfig.pin = GPIO_PIN_13 | GPIO_PIN_15;
- gpioConfig.mode = GPIO_MODE_AF;
- gpioConfig.outtype = GPIO_OUT_TYPE_PP;
- gpioConfig.speed = GPIO_SPEED_50MHz;
- gpioConfig.pupd = GPIO_PUPD_PU;
- GPIO_Config(GPIOB, &gpioConfig);
- /* config PIN_8->NSS*/
- gpioConfig.pin = GPIO_PIN_8;
- gpioConfig.outtype = GPIO_OUT_TYPE_PP;
- gpioConfig.speed = GPIO_SPEED_50MHz;
- gpioConfig.pupd = GPIO_PUPD_PU;
- gpioConfig.mode = GPIO_MODE_OUT;
- GPIO_Config(GPIOA, &gpioConfig);
- GPIO_SetBit(GPIOA, GPIO_PIN_8);
- /* config PIN_14 MISO*/
- gpioConfig.pin = GPIO_PIN_14;
- gpioConfig.mode = GPIO_MODE_AF;
- gpioConfig.pupd = GPIO_PUPD_PU;
- gpioConfig.speed = GPIO_SPEED_50MHz;
- GPIO_Config(GPIOB, &gpioConfig);
- /* SPI RESET*/
- SPI_Reset(SPI2);
- SPI_ConfigStructInit(&spiConfig);
- /* SPI configuration*/
- /* Set Clock polarity is Low, but Slave is High*/
- spiConfig.polarity = SPI_CLKPOL_LOW;
- /* select master mode*/
- spiConfig.mode = SPI_MODE_MASTER;
- /* SPI Clock Phase is 1EDGE, but Slave is 1EDGE*/
- spiConfig.phase = SPI_CLKPHA_1EDGE;
- /* Enable Software slave control */
- spiConfig.slaveSelect = SPI_SSC_ENABLE;
- /* Set SPI BaudRate divider*/
- spiConfig.baudrateDiv = SPI_BAUDRATE_DIV_256;
- /* SPI data length*/
- spiConfig.length = SPI_DATA_LENGTH_16B;
- /* Set internal slave*/
- SPI_EnableInternalSlave(SPI2);
- SPI_Config(SPI2, &spiConfig);
- SPI_ConfigFIFOThreshold(SPI2, SPI_RXFIFO_QUARTER);
- SPI_Enable(SPI2);
- }
- /*!
- * @brief Delay
- *
- * @param None
- *
- * @retval None
- *
- * @note
- */
- void Delay(uint16_t count)
- {
- volatile uint32_t delay = count;
- while (delay--);
- }
- /*!
- * @brief Compares two buffers
- *
- * @param buf1: First buffer to be compared
- *
- * @param buf1: Second buffer to be compared
- *
- * @param size: Buffer size
- *
- * @retval Return TRUE if buf1 = buf2. If not then return FALSE
- *
- * @note
- */
- BOOL BufferCompare(uint8_t* buf1, uint8_t* buf2, uint8_t size)
- {
- uint8_t i;
- for (i = 0; i < size; i++)
- {
- if (buf1[i] != buf2[i])
- {
- return FALSE;
- }
- }
- return TRUE;
- }
- #if defined (__CC_ARM) || defined (__ICCARM__) || (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))
- /*!
- * @brief Redirect C Library function printf to serial port.
- * After Redirection, you can use printf function.
- *
- * @param ch: The characters that need to be send.
- *
- * @param *f: pointer to a FILE that can recording all information
- * needed to control a stream
- *
- * @retval The characters that need to be send.
- *
- * @note
- */
- int fputc(int ch, FILE* f)
- {
- /* send a byte of data to the serial port */
- USART_TxData(DEBUG_USART, (uint8_t)ch);
- /* wait for the data to be send */
- while (USART_ReadStatusFlag(DEBUG_USART, USART_FLAG_TXBE) == RESET);
- return (ch);
- }
- #elif defined (__GNUC__)
- /*!
- * @brief Redirect C Library function printf to serial port.
- * After Redirection, you can use printf function.
- *
- * @param ch: The characters that need to be send.
- *
- * @retval The characters that need to be send.
- *
- * @note
- */
- int __io_putchar(int ch)
- {
- /* send a byte of data to the serial port */
- USART_TxData(DEBUG_USART, ch);
- /* wait for the data to be send */
- while (USART_ReadStatusFlag(DEBUG_USART, USART_FLAG_TXBE) == RESET);
- return ch;
- }
- /*!
- * @brief Redirect C Library function printf to serial port.
- * After Redirection, you can use printf function.
- *
- * @param file: Meaningless in this function.
- *
- * @param *ptr: Buffer pointer for data to be sent.
- *
- * @param len: Length of data to be sent.
- *
- * @retval The characters that need to be send.
- *
- * @note
- */
- int _write(int file, char* ptr, int len)
- {
- int i;
- for (i = 0; i < len; i++)
- {
- __io_putchar(*ptr++);
- }
- return len;
- }
- #else
- #warning Not supported compiler type
- #endif
- /**@} end of group SPI_TwoBoards_Master_Functions */
- /**@} end of group SPI_TwoBoards_Master */
- /**@} end of group Examples */
仿真情况:
逻辑分析仪抓取情况:
你可以看看你的代码是否有需要改动的地方,建议你在debug窗口查看一下SPI2的寄存器,若初始化成功,SPI2的寄存器应该是相应的内容。
如何查看外设寄存器值:
SPI2初始化前:
SPI2初始化后:
同样的可以检查SPI相关GPIO和RCM的相关寄存器是否设置正确,设置正确时再检查硬件设计是否有误。