首页 > 解决方案 > 使用指针读取 SPI EEprom 不起作用,但在不使用指针时起作用

问题描述

我是编程新手,我正在尝试从 SPI Eeprom 读取页面(64 字节),并且在读取数组 [67](3 个传输字节以通过 SPI + 64 字节数据开始读取过程)时它可以工作。

我正在使用 IAR Workbench 在 STM32L475 上工作。

当我尝试使用指针时它不起作用,这可能是一个愚蠢的初学者错误,但我感谢一些帮助解决这个问题。

我正在使用这样的联合(我知道我在浪费内存,但对于测试来说是这样的):

//Production Data union
union Production_Data_union
  {
  struct 
    {
    uint8_t Dummy_Array[3];
    char Xxxx_Sn[16];
    char Yyyy_Sn[16];
    char Prod_Date[8];
    char Firmware_Ver[8];
    };
  uint8_t Eeprom_Page0_Buffer[67]; 
  };  

union Production_Data_union Prod_Data;

uint8_t *Eeprom_Page0_Ptr;

uint8_t Read_Cmd[3] = {0x03, 0x00, 0x00};
uint8_t Buff[67]; 
uint8_t Eeprom_Page_Size = 64;  

void Eeprom_Page_Read(uint8_t *Data, uint8_t Page_No);  

我的主要看起来像这样:

Eeprom_Page0_Ptr = (uint8_t*)&Prod_Data.Eeprom_Page0_Buffer;
Eeprom_Page_Read(Eeprom_Page0_Ptr, 0);

EEprom_Page_Read 函数:

void Eeprom_Page_Read(uint8_t *Data, uint8_t Page_No)
{  
  uint16_t Address;
  Address = Page_No * Eeprom_Page_Size;
  Read_Cmd[2] = Address & 0xFF;
  Read_Cmd[1] = (Address >> 8) & 0xFF;
  //Send READ command to Eeprom

  HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);

  if(HAL_SPI_TransmitReceive(&hspi3, (uint8_t*)Read_Cmd, (uint8_t *)&Data,     (Eeprom_Page_Size +3), 5000) != HAL_OK)
   {
            Error_Handler();
  }

  printf("Prod_Data:\n - Xxxx SN %s\n - Yyyy SN %s\n - Prod date %s - Firmware %s\n - Cmd - %d - %d -         %d\n", 
               Prod_Data.Xxxx_Sn, 
               Prod_Data.Yyyy_Sn, 
               Prod_Data.Prod_Date,
               Prod_Data.Firmware_Ver,
               Read_Cmd[0],
               Read_Cmd[1],
               Read_Cmd[2]);

//Wait for SPI transfer to complete
  while (HAL_SPI_GetState(&hspi3) != HAL_SPI_STATE_READY)
  {
  } 
    HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);

    Read_E2prom = 0;
  }

我知道 Eeprom 的内容没问题,如果我在 HAL_SPI_TransmitReceive(...) 调用中将“&Data”替换为“Buff”(Array[67]),我可以读取它。

指针值是结构的起始地址(0x20000090)。所以寻址 aso 应该没问题,但使用指针时结构为空。

我最感兴趣的是为什么这不起作用和解决这个问题,而不是像“你为什么不这样做,我想知道我做错了什么,因为这种方法,我相信,应该管用。

请记住,我是编程新手,所以请解释“傻瓜”。

标签: functionpointersstm32spi

解决方案


我不确定为什么会这样?

该函数HAL_SPI_TransmitReceive需要一个指针来知道在哪里存储它接收到的数据。它本质上想要一个放置字节的地址。在你的情况下,根据线

void Eeprom_Page_Read(uint8_t *Data, uint8_t Page_No){...}

Data已经是一个指针,因为它用. 表示*。这意味着这Data是一个指向某个uint8_t数字/数组的指针。那是您希望 SPI 写入的地方。

当您添加时,&您基本上为 SPI 提供了指向您要写入的指针的指针。所以 SPI 将接收到的数据写入指针上,而不是指针指向的位置?

如果这没有意义,那么再问我一次。这是一件很难解释的事情。

更新:

据我了解,不是指针而是数组?

编译器仅将其视为指针。在您的情况下,指针恰好指向一个数组,但它可能指向内存中的任何地方(几乎)。我恳请您考虑的是指向数组 ( *ptr==array[0]) 的第一个元素的指针,而不是数组。

它是否以某种方式隐含,所以编译器知道我想要做什么,所以它只是接受并正确编译?

我不确定编译器是否应该编译成功。但你不应该依赖它。这种情况经常发生,人们可以在 ( ) 周围发送指针指针**ptr,因此编译器只会假设您知道自己在做什么。因此,您必须非常注意如何使用指针。


推荐阅读