你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32 OCTOSPI 读取 ICNA3306 显示屏 ID 失败,求助;

[复制链接]
为巽 提问时间:2025-3-31 17:41 / 未解决

读取到的ID一直是RX:Final ID: 0x000000,求助各位大佬解答

image.pngimage.pngimage.pngimage.png

/* 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 */
image.png
image.png
收藏 评论0 发布时间:2025-3-31 17:41

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版