SPI读取数据是MOSI怎么一直保持0xFF输出?
最近在做SD卡的程序,使用模拟SPI可以正常读写,但是改成硬件SPI后发现SD卡反馈的数据不对。通过时序对比发现,异常的SD卡读取时序读取前的Dummy信号将MOSI输出为上一次发送的数据了,
比如上一次发送的数据是0x87,那么当进行SPI读取时,它会将MOSI设置为0x87,后面的读取才是
0xFF,这样就导致了连续发送了两次0x87,使得通信异常。
请问有没有办法让SPI读取时保持MOSI为0xFF?
正常的SD卡读取时序:
异常的SD卡读取时序:
端口初始化代码:
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOF_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOE_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOG_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOG, GPIO_PIN_9, GPIO_PIN_RESET);
/*Configure GPIO pin : PA4 */
GPIO_InitStruct.Pin = GPIO_PIN_4;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_AF_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6, GPIO_PIN_SET); //端口不写1会导致一直读入的都是低电平
__HAL_RCC_GPIOC_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/*Configure GPIO pin : PG9 */
GPIO_InitStruct.Pin = GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
/*Configure GPIO pins : PG12 PG13 PG14 PG15 */
GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
}
SPI初始化代码:
/* SPI1 init function */
static void MX_SPI1_Init(void)
{
/* SPI1 parameter configuration*/
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER;
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;//SPI_POLARITY_HIGH;
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;//SPI_PHASE_2EDGE;
hspi1.Init.NSS = SPI_NSS_SOFT;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi1.Init.CRCPolynomial = 10;
if (HAL_SPI_Init(&hspi1) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
SPI发送代码:
HAL_SPI_Transmit(&hspi1, &d, 1, 1000);
SPI接收代码:
HAL_SPI_Receive(&hspi1, &r, 1, 1000);
用发送函数读数据,读时肯定会发,发时可以不读(对读取内容不理会)。 改一下时钟极性和时钟相位试一试 likang1202 发表于 2019-11-19 08:51
改一下时钟极性和时钟相位试一试
还是一样的,输出转输入后的第一次读数还是会把上一次的数据传输到MOSI端口。 toofree 发表于 2019-11-19 09:52
用发送函数读数据,读时肯定会发,发时可以不读(对读取内容不理会)。
硬件SPI也可以这么操作?但是貌似STM32的硬件SPI的读写共用了一个DR寄存器,不知道怎么操作了。 toofree 发表于 2019-11-19 09:52
用发送函数读数据,读时肯定会发,发时可以不读(对读取内容不理会)。
已解决,谢谢!
页:
[1]