2017-01-20 12 views
1

내가 읽기 작업 데이터 명령에 대한 데이터 시트 주문에 따라 ST EEPROM M95640-WSTM32의 HAL SPI가 전송할 데이터를 포맷하는 올바른 방법은 무엇입니까?

에서/쓰기 데이터를 읽을하려고하는 것은 같은 형식의해야합니다

M95640-W Read operation

먼저 "8 비트 명령어입니다 메모리 어레이에서 읽기 ": 0x03 (B00000011)

두 번째는 16 비트 주소입니다.

하지만이있어 I 명령과 데이터를 보낼 때 :

주소 0001 (B00000001) : M95640 Read from address 0x1

그리고 단지 미러 비트

주소 0x0081를 데이터의 위치를 ​​확인하기를 (B10000001) : M95640 Read from address 0x81


그래서 내 코드에서 오류를 찾을 수 없습니다. 잘못된 방식으로 데이터를 보내는 이유는 무엇입니까? 0x03을 제외한 0x20 명령을 보냅니다. 그것은 를 0x81의 제외 0x01로0x80으로의 제외 0x48 주소를 보낼 수 있습니다. uint16_t -> uint8_t * 유형간에 잘못된 데이터 변환이있는 것 같습니다.

#define EEPROM_SPI hspi1 
#define EEPROM_READ 0x03 // Read from Memory Array 

/** 
    * @brief Reads a block of data from the EEPROM. 
    * @param pBuffer: pointer to the buffer that receives the data read from the EEPROM. 
    * @param ReadAddr: EEPROM's internal address to read from. 
    * @param NumByteToRead: number of bytes to read from the EEPROM. 
    * @retval None 
    */ 
uint8_t sEE_ReadBuffer(uint8_t* pBuffer, uint16_t ReadAddr, uint16_t NumByteToRead) { 
    /*!< Select the EEPROM: Chip Select low */ 
    EEPROM_LED_ON(); 
    EEPROM_CS_LOW(); 

    /*!< Send "Read from Memory" instruction and MSB of WriteAddr */ 
    EEPROM_SendInstruction((uint8_t*)EEPROM_READ, 1); 

    /*!< Send WriteAddr address byte to read from */ 
    EEPROM_SendInstruction((uint8_t*)ReadAddr, 2); 

    if (HAL_SPI_Receive_DMA(&EEPROM_SPI, (uint8_t*)pBuffer, NumByteToRead) != HAL_OK) { 
     Error_Handler(); 
    } 

    /*!< Deselect the EEPROM: Chip Select high */ 
    EEPROM_CS_HIGH(); 
    EEPROM_LED_OFF(); 

    return 0; 
} 

void EEPROM_SendInstruction(uint8_t *instruction, uint8_t size) { 
    while (EEPROM_SPI.State == HAL_SPI_STATE_RESET) { 
     osDelay(1); 
    } 

    if (HAL_SPI_Transmit_DMA(&EEPROM_SPI, (uint8_t*)instruction, (uint16_t)size) != HAL_OK) { 
     Error_Handler(); 
    } 
} 

SPI 초기화 :

static void MX_SPI1_Init(void) { 
    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; 
    hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; 
    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 = 7; 

    if (HAL_SPI_Init(&hspi1) != HAL_OK) { 
     Error_Handler(); 
    } 
} 

UPD1 : 그래서 여기

코드입니다 내가 @Guillaume 미셸 같은 패킷이 말했다 않았고 그것은 일 : M95640 Read from address 0x81 Working way

UPD2 나는에 서사를 발표했다., 데이터 쓰기 및 읽기 기능이 완벽하게 작동합니다. 코드를 검토하고 새로운 기능을 추가 할 수 있도록 도와주십시오.

답변

2

코드를 DMA로 쓰는 것 같지 않으므로 사용하지 마십시오. HAL_SPI_Receive_DMAHAL_SPI_Transmit_DMA 대신 HAL_SPI_ReceiveHAL_SPI_Transmit을 사용해보십시오.

극성과 위상은 괜찮은 것처럼 보이지만 다시 확인하십시오.

EEPROM_SendInstruction 전화가 올바른지 확신 할 수 없습니다. 대신 다음을 시도하십시오.

uint8_t sEE_ReadBuffer(uint8_t* pBuffer, uint16_t ReadAddr, uint16_t NumByteToRead) { 

    uint8_t tmpBuf[2]; 

    /*!< Select the EEPROM: Chip Select low */ 
    EEPROM_LED_ON(); 
    EEPROM_CS_LOW(); 

    /*!< Send "Read from Memory" instruction and MSB of WriteAddr */ 
    tmpBuf[0] = EEPROM_READ; 
    EEPROM_SendInstruction(tmpBuf, 1); 

    /*!< Send WriteAddr address byte to read from */ 
    tmpBuf[0] = (uint8_t)(ReadAddr<<8); 
    tmpBuf[1] = (uint8_t)ReadAddr; 
    EEPROM_SendInstruction(tmpBuf, 2); 

    if (HAL_SPI_Receive_DMA(&EEPROM_SPI, (uint8_t*)pBuffer, NumByteToRead) != HAL_OK) { 
     Error_Handler(); 
    } 

    /*!< Deselect the EEPROM: Chip Select high */ 
    EEPROM_CS_HIGH(); 
    EEPROM_LED_OFF(); 

    return 0; 
} 
+0

예! 나는 이미 똑같이했고 그게 문제를 해결했습니다. 나는 곧 이미지로 질문을 업데이트 할 것이다. 고맙습니다! – Bulkin

+0

아. DMA가 작동하고 있지만 CS 선을 제어하기가 더 어려워서 이제는 꺼야합니다. 인터럽트에서 켜고 끌 필요가 있습니다. 나는 나중에 시험 할 것이다. – Bulkin