使用指针读取SPI Eeprom无效,但不使用指针时有效

时间:2018-08-24 11:38:37

标签: function pointers stm32 spi

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

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

当我尝试使用指针时,它不起作用,这可能是愚蠢的,毫无头脑的初学者错误,但是我很乐意为解决此问题提供一些帮助。

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

//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)。 所以解决一个。应该可以,但是使用指针时该结构为空。

我最感兴趣的是为什么它不起作用以及解决方法,而不是诸如“为什么不这样做呢?我想了解我做错了什么导致这种方法,我相信应该可以。

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

2 个答案:

答案 0 :(得分:1)

  

我不确定为什么会这样吗?

函数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周围发送指针的指针,因此编译器只是假设您知道自己在做什么。因此,您必须非常注意如何使用指针。

答案 1 :(得分:0)

好吧,在尝试解决了大约一天后,我终于发现了错误,它应该不是&Data而是Data,所以它看起来必须像这样:

  if(HAL_SPI_TransmitReceive(&hspi3, (uint8_t*)Read_Cmd, (uint8_t *)Data, (Eeprom_Page_Size +3), 5000) != HAL_OK)
  {
  /* Transfer error in transmission process */
  Error_Handler();
  }

我不确定为什么会这样吗?