我正在尝试为STM32F407 MCU编写SPI驱动程序,并使用此驱动程序将数据发送到Arduino。
以下是将数据发送到Arduino的应用程序的一部分。(STM32F4用作主人,使用硬件从管理。(
int main (void)
{
/*initilize green led on PD12*/
green_led_init();
/*Initialize user button on PA0*/
user_button_init();
/*Initilize SPI2 on PB15:PB12*/
SPI2_GPIO_pin_init();
SPI2_init();
SPI_NSS_pin_ctr(SPI2,ENABLE);
char *dataPtr = "HelloWorld";
uint8_t dataLength = strlen(dataPtr);
while(1){
if(user_button_read()){
green_led_on();
SPI_periph_ctr(SPI2,ENABLE);
/*send to Arduino size of data to receive. then send the data*/
SPI_send_data(SPI2,&dataLength,1);
SPI_send_data(SPI2,(uint8_t*)dataPtr,dataLength);
/*check whether SPI2 is still busy. if not, disable SPI2*/
while(SPI_busy_check(SPI2));
SPI_periph_ctr(SPI2,DISABLE);
}else{
green_led_off();
}
}
这是用于发送数据的API
void SPI_send_data (SPI_TypeDef *SPIxPtr, uint8_t *txBufferPtr, uint32_t Length)
{
uint8_t temp = 0;
while(Length){
/* wait until tx buffer is empty*/
while(!SPIxPtr->SR & SPI_SR_TXE);
if(!(SPIxPtr->CR1 & SPI_CR1_DFF)){
/*8 bit data frame*/
SPIxPtr->DR = *txBufferPtr;
txBufferPtr++;
Length--;
}else{
/*16 bit data frame*/
SPIxPtr->DR = *((uint16_t*)txBufferPtr);
txBufferPtr+=2;
Length-=2;
}
}
}
当我尝试编写数据以DR寄存器时,DR寄存器的值保持0xff,而SR寄存器位中的RXNE位保持在设置中(请按照此链接以获取图像https://i.stack.imgur.com/UONX9.JPG(。由于此应用程序仅将数据发送到Arduino,并且由于发送了数据,因此我相信TXE位应该很清楚,而不是设置RXNE。
我仍然无法弄清楚为什么会发生上述情况。任何帮助或建议都将不胜感激。
在使用SPI时,请保持SPI上调试器,我强烈建议不要这样做,因为调试器将继续阅读DR注册表以更新IDE中的GUI,然后将其弄乱状态范围。
即使不使用ST的HAL库,您也可以随时将其用作参考
HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)
{
...........
while (hspi->TxXferCount > 0U)
{
/* Wait until TXE flag is set to send data */
if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE))
{
*((__IO uint8_t*)&hspi->Instance->DR) = (*pData);
pData += sizeof(uint8_t);
hspi->TxXferCount--;
}
else
{
/* Timeout management */
if((Timeout == 0U) || ((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick()-tickstart) >= Timeout)))
{
errorcode = HAL_TIMEOUT;
goto error;
}
}
}
...........
/* Wait until TXE flag */
if(SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_TXE, SET, Timeout, tickstart) != HAL_OK)
{
errorcode = HAL_TIMEOUT;
goto error;
}
/* Check Busy flag */
if(SPI_CheckFlag_BSY(hspi, Timeout, tickstart) != HAL_OK)
{
errorcode = HAL_ERROR;
hspi->ErrorCode = HAL_SPI_ERROR_FLAG;
goto error;
}
/* Clear overrun flag in 2 Lines communication mode because received is not read */
if(hspi->Init.Direction == SPI_DIRECTION_2LINES)
{
__HAL_SPI_CLEAR_OVRFLAG(hspi);
}
...........
}