读取到的ID一直是RX:Final ID: 0x000000,求助各位大佬解答
   
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file octospi.c
* @brief This file provides code for the configuration
* of the OCTOSPI instances.
******************************************************************************
* @attention
*
* Copyright (c) 2025 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "octospi.h"
#include "usart.h"
#include <inttypes.h> // 添加头文件以支持PRIx32
#include <stdio.h>
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
OSPI_HandleTypeDef hospi1;
DMA_HandleTypeDef handle_GPDMA1_Channel0;
/* OCTOSPI1 init function */
void MX_OCTOSPI1_Init(void)
{
/* USER CODE BEGIN OCTOSPI1_Init 0 */
/* USER CODE END OCTOSPI1_Init 0 */
OSPIM_CfgTypeDef sOspiManagerCfg = {0};
HAL_OSPI_DLYB_CfgTypeDef HAL_OSPI_DLYB_Cfg_Struct = {0};
/* USER CODE BEGIN OCTOSPI1_Init 1 */
/* USER CODE END OCTOSPI1_Init 1 */
hospi1.Instance = OCTOSPI1; // 指定使用的OCTOSPI外设实例为OCTOSPI1
hospi1.Init.FifoThreshold = 4; // 设置FIFO阈值为4字节。当FIFO中数据达到或超过4字节时,可能会触发中断或DMA请求(取决于配置)。
hospi1.Init.DualQuad = HAL_OSPI_DUALQUAD_DISABLE; // 禁用双线/四线模式。当前配置为单线SPI通信。
hospi1.Init.MemoryType = HAL_OSPI_MEMTYPE_MICRON; // 设置连接的存储器类型为Micron。对于命令模式下的显示驱动IC,这个设置可能不是关键,可以考虑改为HAL_OSPI_MEMTYPE_UNKNOWN。
hospi1.Init.DeviceSize = 24; // 设置设备大小为24位,这通常对应于地址线的数量。我们的读写操作使用24位地址。
hospi1.Init.ChipSelectHighTime = 4; // 设置片选信号CSX保持高电平的最小时间为4个时钟周期,用于区分不同的传输。
hospi1.Init.FreeRunningClock = HAL_OSPI_FREERUNCLK_DISABLE; // 禁用自由运行的时钟模式。通常在存储器映射模式下使用。
hospi1.Init.ClockMode = HAL_OSPI_CLOCK_MODE_0; // 设置SPI时钟模式为模式0 (CPOL=0, CPHA=0)。
hospi1.Init.WrapSize = HAL_OSPI_WRAP_NOT_SUPPORTED; // 禁用Wrap模式,该模式用于在连续传输中自动换行地址。
hospi1.Init.ClockPrescaler = 8; // 设置时钟预分频值为8。系统时钟(160MHz)将除以(8+1)得到OCTOSPI时钟频率 (约17.78 MHz)。
hospi1.Init.SampleShifting = HAL_OSPI_SAMPLE_SHIFTING_NONE; // 设置采样时移为无。对于SPI模式0,数据通常在时钟上升沿被采样。
hospi1.Init.DelayHoldQuarterCycle = HAL_OSPI_DHQC_DISABLE; // 禁用延迟保持四分之一周期。
hospi1.Init.ChipSelectBoundary = 0; // 设置片选边界,用于在突发传输中保持片选信号有效。
hospi1.Init.DelayBlockBypass = HAL_OSPI_DELAY_BLOCK_BYPASSED; // 旁路延迟块B。
hospi1.Init.MaxTran = 0;
hospi1.Init.Refresh = 0;
if (HAL_OSPI_Init(&hospi1) != HAL_OK)
{
Error_Handler();
}
sOspiManagerCfg.ClkPort = 1;
sOspiManagerCfg.NCSPort = 1;
sOspiManagerCfg.IOLowPort = HAL_OSPIM_IOPORT_1_LOW;
if (HAL_OSPIM_Config(&hospi1, &sOspiManagerCfg, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
Error_Handler();
}
HAL_OSPI_DLYB_Cfg_Struct.Units = 0;
HAL_OSPI_DLYB_Cfg_Struct.PhaseSel = 0;
if (HAL_OSPI_DLYB_SetConfig(&hospi1, &HAL_OSPI_DLYB_Cfg_Struct) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN OCTOSPI1_Init 2 */
/* USER CODE END OCTOSPI1_Init 2 */
}
void HAL_OSPI_MspInit(OSPI_HandleTypeDef *ospiHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
if (ospiHandle->Instance == OCTOSPI1)
{
/* USER CODE BEGIN OCTOSPI1_MspInit 0 */
/* USER CODE END OCTOSPI1_MspInit 0 */
/** Initializes the peripherals clock */
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_OSPI;
PeriphClkInit.OspiClockSelection = RCC_OSPICLKSOURCE_SYSCLK;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
/* OCTOSPI1 clock enable */
__HAL_RCC_OSPIM_CLK_ENABLE();
__HAL_RCC_OSPI1_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/** OCTOSPI1 GPIO Configuration
* PA3 ------> OCTOSPIM_P1_CLK
* PA4 ------> OCTOSPIM_P1_NCS
* PA6 ------> OCTOSPIM_P1_IO3
* PA7 ------> OCTOSPIM_P1_IO2
* PB0 ------> OCTOSPIM_P1_IO1
* PB1 ------> OCTOSPIM_P1_IO0
*/
GPIO_InitStruct.Pin = GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF10_OCTOSPI1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_4;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF3_OCTOSPI1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF10_OCTOSPI1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF10_OCTOSPI1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* OCTOSPI1 DMA Init */
/* GPDMA1_REQUEST_OCTOSPI1 Init */
/* USER CODE BEGIN OCTOSPI1_MspInit 1 */
/* USER CODE END OCTOSPI1_MspInit 1 */
}
}
// 写操作
HAL_StatusTypeDef LCD_SendCommandWithWrite(uint8_t cmd)
{
OSPI_RegularCmdTypeDef sCommand = {0};
sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; // 设置操作类型为通用配置
sCommand.Instruction = cmd; // 使用传入的命令作为指令
sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE; // 设置指令模式为单线模式
sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS; // 设置指令大小为 8 位
sCommand.AddressMode = HAL_OSPI_ADDRESS_NONE; // 禁用地址模式,不发送地址
sCommand.AddressSize = HAL_OSPI_ADDRESS_NONE; // 禁用地址大小
sCommand.Address = 0; // 地址设置为 0(禁用地址时无效)
sCommand.DataMode = HAL_OSPI_DATA_NONE; // 明确表示不发送数据
sCommand.DummyCycles = 0; // 时钟周期
sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; // 每次发送指令
if (HAL_OSPI_Command(&hospi1, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
return HAL_ERROR;
}
return HAL_OK;
}
HAL_StatusTypeDef LCD_SendCommandWithRead(uint8_t cmd, uint8_t *pData, uint8_t size)
{
OSPI_RegularCmdTypeDef sCommand = {0};
sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG; // 设置操作类型为通用配置,用于发送指令
sCommand.Instruction = 0x03; // 使用传入的 cmd 参数作为指令
sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE; // 设置指令模式为单线模式,通过 SIO0 引脚发送指令
sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS; // 设置指令大小为 8 位
sCommand.AddressMode = HAL_OSPI_ADDRESS_24_BITS; // 地址模式:24位
sCommand.AddressSize = HAL_OSPI_ADDRESS_24_BITS;
sCommand.Address = (0x00 << 16) | (cmd << 8) | (0x00);
sCommand.DataMode = HAL_OSPI_DATA_1_LINE; // 明确表示此操作不发送数据
sCommand.DummyCycles = 4; // 时钟周期
sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD; // 每次发送指令
sCommand.NbData = size; // 要读取的数据字节数
if (HAL_OSPI_Command(&hospi1, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
return HAL_ERROR;
}
if (HAL_OSPI_Receive(&hospi1, pData, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
return HAL_ERROR;
}
return HAL_OK;
}
void LCD_Init(OSPI_HandleTypeDef *hospi)
{
// 硬件复位
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_RESET);
HAL_Delay(100);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_SET);
HAL_Delay(10);
// 选择单线模式
LCD_SendCommandWithWrite(LCD_CMD_RESET_SINGLE);
HAL_Delay(10);
uint32_t lcdID = LCD_ReadID(hospi);
printf("Final ID: 0x%06X\r\n", lcdID);
}
uint32_t LCD_ReadID(OSPI_HandleTypeDef *hospi)
{
uint8_t idBuffer[3] = {0};
if (LCD_SendCommandWithRead(0x04, idBuffer, 3) != HAL_OK)
{
return HAL_ERROR;
}
return (idBuffer[0] << 16) | (idBuffer[1] << 8) | idBuffer[2];
}
/* USER CODE END 1 */
|