GW1NSR-4C硬核MCU的硬件SPI问题
在官方库的基础上使用硬件spi时发现,在发送和接收数据时,片选线无法正常拉高拉低。但在测试时发现下面这段代码在地址为0x01时片选线一直为低电平,在0x00或者其他值的时候一直为高电平。
SPI_Select_Slave(0x00); //Select SPI slave
于是将这段代码作为片选线的控制语句,手动拉高拉低。代码如下
uint8_t at86rf215_read_single( uint16_t addr ) { SPI_Select_Slave(0x01); if(~SPI_GetToeStatus() && SPI_GetTrdyStatus() == 1) { SPI_WriteData( ( addr >> 8 ) & 0x3f ); SPI_WriteData( ( addr & 0xff ) ); } uint8_t data= SPI_ReadData(); SPI_Select_Slave(0x00);
return data; } uint8_t at86rf215_write_single( uint16_t addr, uint8_t val ) { SPI_Select_Slave(0x01); if(~SPI_GetToeStatus() && SPI_GetTrdyStatus() == 1) { SPI_WriteData( 0x80 | ( ( addr >> 8 ) & 0x3f ) ); SPI_WriteData( ( addr & 0xff ) ); SPI_WriteData( val ); } SPI_Select_Slave(0x00);
return 0; }
官方库代码
/* ****************************************************************************************** * @file gw1ns4c_spi.c * @author GowinSemiconductor * @device Gowin_EMPU(GW1NS-4C) * @brief This file contains all the functions prototypes for the SPI firmware library. ****************************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include "gw1ns4c_spi.h" /** @addtogroup GW1NS4C_StdPeriph_Driver * @{ */ /** @defgroup SPI * @brief SPI driver modules * @{ */ /** @defgroup SPI_Private_TypesDefinitions * @{ */ /** * @} */ /** @defgroup SPI_Private_Macros * @{ */ /** * @} */ /** @defgroup SPI_Private_Variables * @{ */ /** * @} */ /** @defgroup SPI_Private_FunctionPrototypes * @{ */ /** * @} */ /** @defgroup SPI_Private_Functions * @{ */ /** * @param SPI_InitTypeDef Pointer * @return none * @brief Initializes SPI */ void SPI_Init(SPI_InitTypeDef* SPI_InitStruct) { uint32_t new_ctrl = 0; SPI->CTRL = 0; SPI->STATUS = 0; /* Set Direction */ if(SPI_InitStruct->DIRECTION == 1) { new_ctrl |= SPI_CR_DIRECTION; } /*Set Phase*/ if(SPI_InitStruct->PHASE == 1) { new_ctrl |= SPI_CR_PHASE; } /*Set Polarity*/ if(SPI_InitStruct->POLARITY == 1) { new_ctrl |= SPI_CR_POLARITY; } /*Set ClkSel*/ new_ctrl |= (SPI_InitStruct->CLKSEL << SPI_CR_CLKSEL_Pos); SPI->CTRL = new_ctrl; } /** * @param none * @return none * @brief Sets Direction */ void SPI_SetDirection(void) { SPI->CTRL |= SPI_CR_DIRECTION; } /** * @param none * @return none * @brief Clears Direction */ void SPI_ClrDirection(void) { SPI->CTRL &= ~SPI_CR_DIRECTION; } /** * @param none * @return uint32_t * @brief Returns Direction */ uint32_t SPI_GetDirection(void) { return ((SPI->CTRL&SPI_CR_DIRECTION)==SPI_CR_DIRECTION); } /** * @param none * @return none * @brief Sets Phase */ void SPI_SetPhase(void) { SPI->CTRL |= SPI_CR_PHASE; } /** * @param none * @return none * @brief Clears Phase */ void SPI_ClrPhase(void) { SPI->CTRL &= ~SPI_CR_PHASE; } /** * @param none * @return uint32_t * @brief Returns Phase */ uint32_t SPI_GetPhase(void) { return ((SPI->CTRL&SPI_CR_PHASE)==SPI_CR_PHASE); } /** * @param none * @return none * @brief Sets Polarity */ void SPI_SetPolarity(void) { SPI->CTRL |= SPI_CR_POLARITY; } /** * @param none * @return none * @brief Clears Polarity */ void SPI_ClrPolarity(void) { SPI->CTRL &= ~SPI_CR_POLARITY; } /** * @param none * @return uint32_t * @brief Returns Polarity */ uint32_t SPI_GetPolarity(void) { return ((SPI->CTRL&SPI_CR_POLARITY)==SPI_CR_POLARITY); } /** * @param uint32_t * @return none * @brief Set ClkSel */ void SPI_SetClkSel(uint32_t clksel) { SPI->CTRL &= ~SPI_CR_CLKSEL; SPI->CTRL |= ((clksel&SPI_CR_CLKSEL_Mask)<<SPI_CR_CLKSEL_Pos); } /** * @param none * @return uint32_t * @brief Returns ClkSel */ uint32_t SPI_GetClkSel(void) { return ((SPI->CTRL >>SPI_CR_CLKSEL_Pos)&SPI_CR_CLKSEL_Mask); } /** * @param none * @return FlagStatus * @brief Reads transmit overrun error status */ FlagStatus SPI_GetToeStatus(void) { return (FlagStatus)((SPI->STATUS&SPI_STATUS_TOE)==SPI_STATUS_TOE); } /** * @param none * @return FlagStatus * @brief Returns receive overrun error status */ FlagStatus SPI_GetRoeStatus(void) { return (FlagStatus)((SPI->STATUS&SPI_STATUS_ROE)==SPI_STATUS_ROE); } /** * @param none * @return FlagStatus * @brief Returns transmitting status */ FlagStatus SPI_GetTmtStatus(void) { return (FlagStatus)((SPI->STATUS&SPI_STATUS_TMT)==SPI_STATUS_TMT); } /** * @param none * @return FlagStatus * @brief Return transmit ready status */ FlagStatus SPI_GetTrdyStatus(void) { return (FlagStatus)((SPI->STATUS & SPI_STATUS_TRDY) == SPI_STATUS_TRDY); } /** * @param none * @return FlagStatus * @brief Returns receive ready status */ FlagStatus SPI_GetRrdyStatus(void) { return (FlagStatus)((SPI->STATUS&SPI_STATUS_RRDY)==SPI_STATUS_RRDY); } /** * @param none * @return FlagStatus * @brief Returns error Status */ FlagStatus SPI_GetErrStatus(void) { return (FlagStatus)((SPI->STATUS&SPI_STATUS_ERR)==SPI_STATUS_ERR); } /** * @param none * @return none * @brief Clears transmit overrun error status */ void SPI_ClrToeStatus(void) { SPI->STATUS |= SPI_STATUS_TOE; } /** * @param none * @return none * @brief Clears receive overrun error status */ void SPI_ClrRoeStatus(void) { SPI->STATUS |= SPI_STATUS_ROE; } /** * @param none * @return none * @brief Clears error status */ void SPI_ClrErrStatus(void) { SPI->STATUS |= SPI_STATUS_ERR; } /** * @param uint8_t cmd * @return uint8_t * @brief Reads and writes byte data */ uint8_t SPI_ReadWriteByte(uint8_t cmd) { uint32_t master_rx_data; while (!(SPI->STATUS & (1UL << 5))); SPI->WDATA = cmd; while (!(SPI->STATUS & (1UL << 6))); master_rx_data = SPI->RDATA; return master_rx_data & 0xff; } /** * @param uint8_t data * @return none * @brief Writes Data */ void SPI_WriteData(uint8_t data) { SPI_ReadWriteByte(data); } /** * @param none * @return uint8_t * @brief Reads Data */ uint8_t SPI_ReadData(void) { return (SPI_ReadWriteByte(0xFF)); } /** * @param uint32_t slave address * @return none * @brief Select Slave */ void SPI_Select_Slave(uint32_t Slave_address) { SPI->SSMASK = Slave_address; } /** * @} */ /** * @} */ /** * @} */ /************************GowinSemiconductor******END OF FILE*******************/

浙公网安备 33010602011771号