c - 在 stm32MP1 上以 DMA 模式通过 SPI 发送数据
问题描述
我正在尝试在 STM32MP157C-DK2 板上以 DMA 模式通过 SPI 发送数据。目标是将数据从 GPIO_PIN_8 发送到 GPIO_PIN_9 并检查它们是否相同。
我尝试使用 HAL_SPI_TransmitReceive_DMA 函数,但我不确定它是如何工作的。它将发送缓冲区和接收缓冲区作为输入。但是如何告诉我想从引脚 8(MOSI)发送到引脚 9(MISO)的功能。以及如何查看和显示我发送的数据并检查它是否在另一个引脚上正确接收。
我是否必须为发送接收功能提供 GPIOS 地址而不是 TX 和 RX 缓冲区?但是如何告诉函数我要发送的数据。
我将 GPIOS 和 SPI5 配置如下:
#define BUFSIZE 1024
#define GPIOF_OutPut_Data (0x40010028)
#define GPIOF_Input_Data (0x44009000)+(0x30)
enum
{
TRANSFER_WAIT,
TRANSFER_COMPLETE,
TRANSFER_ERROR
};
/* Buffer used for transmission */
uint8_t aTxBuffer[] = "****SPI Message based on DMA ****";
/* Buffer used for reception */
uint8_t aRxBuffer[BUFSIZE];
/* transfer state */
__IO uint32_t wTransferState = TRANSFER_WAIT;
SPI_HandleTypeDef hspi5;
DMA_HandleTypeDef hdma_spi5_tx;
DMA_HandleTypeDef hdma_spi5_rx;
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_IPCC_Init(void);
static void MX_SPI5_Init(void);
static uint16_t Buffercmp(uint8_t *pBuffer1, uint8_t *pBuffer2, uint16_t BufferLength);
int main(void)
{
MX_GPIO_Init();
MX_DMA_Init();
MX_SPI5_Init();
/**SPI5 GPIO Configuration
PH6 ------> SPI5_SCK
PF8 ------> SPI5_MISO
PF9 ------> SPI5_MOSI
*/
GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_8|GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI5;
// From Alternate Function Table from Data-sheet for Port F
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
//Transmit and Receive Data over SPI in DMA Mode
if(HAL_SPI_TransmitReceive_DMA(&hspi5, (uint8_t*)aTxBuffer, (uint8_t *)aRxBuffer, BUFSIZE) != HAL_OK)
{
/* Transfer error in transmission process */
printf("Entered Transmit Receive DMA Mode");
Error_Handler();
}
/*##-2- Wait for the end of the transfer ###################################*/
/* Before starting a new communication transfer, you must wait the callback call
to get the transfer complete confirmation or an error detection.
This code is just waiting till the end of the
transfer, but application may perform other tasks while transfer operation
is ongoing. */
while (wTransferState == TRANSFER_WAIT)
{
}
switch(wTransferState)
{
case TRANSFER_COMPLETE :
/*##-3- Compare the sent and received buffers ##############################*/
if(Buffercmp((uint8_t*)aTxBuffer, (uint8_t*)aRxBuffer, BUFSIZE))
//if buffers are identical, the return value should be 0, otherwise go to Error handler
{
/* Processing Error */
Error_Handler();
}
break;
default :
Error_Handler();
break;
}
}
static void MX_SPI5_Init(void)
{
/* USER CODE BEGIN SPI5_Init 0 */
/* USER CODE END SPI5_Init 0 */
/* USER CODE BEGIN SPI5_Init 1 */
/* USER CODE END SPI5_Init 1 */
/* SPI5 parameter configuration*/
hspi5.Instance = SPI5;
hspi5.Init.Mode = SPI_MODE_MASTER;
hspi5.Init.Direction = SPI_DIRECTION_2LINES;
hspi5.Init.DataSize = SPI_DATASIZE_16BIT;
hspi5.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi5.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi5.Init.NSS = SPI_NSS_SOFT;
hspi5.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64;
hspi5.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi5.Init.TIMode = SPI_TIMODE_DISABLE;
hspi5.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi5.Init.CRCPolynomial = 0x0;
hspi5.Init.NSSPMode = SPI_NSS_PULSE_ENABLE;
hspi5.Init.NSSPolarity = SPI_NSS_POLARITY_LOW;
hspi5.Init.FifoThreshold = SPI_FIFO_THRESHOLD_01DATA;
hspi5.Init.TxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN;
hspi5.Init.RxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN;
hspi5.Init.MasterSSIdleness = SPI_MASTER_SS_IDLENESS_00CYCLE;
hspi5.Init.MasterInterDataIdleness = SPI_MASTER_INTERDATA_IDLENESS_00CYCLE;
hspi5.Init.MasterReceiverAutoSusp = SPI_MASTER_RX_AUTOSUSP_DISABLE;
hspi5.Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_DISABLE;
hspi5.Init.IOSwap = SPI_IO_SWAP_DISABLE;
if (HAL_SPI_Init(&hspi5) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN SPI5_Init 2 */
/* USER CODE END SPI5_Init 2 */
}
void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi)
{
wTransferState = TRANSFER_ERROR;
}
/**
* @brief Compares two buffers.
* @param pBuffer1, pBuffer2: buffers to be compared.
* @param BufferLength: buffer's length
* @retval 0 : pBuffer1 identical to pBuffer2
* >0 : pBuffer1 differs from pBuffer2
*/
static uint16_t Buffercmp(uint8_t* pBuffer1, uint8_t* pBuffer2, uint16_t BufferLength)
{
while (BufferLength--)
{
if((*pBuffer1) != *pBuffer2)
{
return BufferLength;
}
pBuffer1++;
pBuffer2++;
}
return 0;
}
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
printf("No Transfer of Data");
while(1)
{
setvbuf (stdout, NULL, _IONBF, 0);
fprintf(stdout, "LED7 is blinking");
Delay_wait(0x5000000);
HAL_GPIO_TogglePin(GPIOH, GPIO_PIN_7);
}
/* USER CODE END Error_Handler_Debug */
}
解决方案
推荐阅读
- c# - 在 c# 中使用 closedxml 将“X”符号插入单元格
- javascript - React Native Web 导航路线问题
- python - 使用 python 运行需要参数的控制台应用程序
- javascript - 我无法从反应功能组件中删除列表
- c++ - 静态库无法打开包含文件
- excel - “where is not null”不能在mysql工作台中工作
- python - Tensorflow:ODE二阶导数的数值不准确
- flutter - Flutter flutter_form_builder 根据另一个字段填充FormBuilderTextField
- java - 可以不使用java内置数组、列表等将相同类型的对象存储到另一个类吗?
- c - MPI 程序卡在 2 个以上的处理器上