我正在尝试从外部EEPROM写入和读取。有一个起始位 (SB),后跟一个操作码,然后是一个 6 位地址,然后是实际数据。我已将 SB 和操作码组合成一个字节,我可以将其作为开始条件发送。我能够启用、擦除然后写入 EEPROM。我假设这是有效的,因为 HAL 函数返回 HAL_OK 并且我可以在示波器上看到有效波形。
我似乎无法做的是读回数据。对于 READ 操作,我在示波器上看不到任何波形。所需的时钟周期数是奇数,而不是 8 的倍数。我不知道如何发送奇数时钟周期,因为所有数据都是 8、16 或 32 位。在需要 25 或 29 个时钟周期的地方,我似乎发送 32 个,而在所需周期为 9 个的地方,我似乎发送 16 个。我真的希望避免按照该线程中的建议进行位碰撞。
这是主要代码:
int main(void)
{
HAL_Init();
MX_GPIO_Init();
MX_SPI1_Init();
__HAL_SPI_ENABLE(&hspi1);
// pull the CS pin high to select the EEPROM (active HIGH)
HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET);
HAL_Delay(10);
// Enable the EEPROM
enable_status = Enable_EEPROM(&EEPROM_SPI_PORT);
HAL_Delay(10);
// Erase the value at address 0x00
erase_status = Erase_EEPROM(&EEPROM_SPI_PORT, addr);
HAL_Delay(10);
// Write data 0xABCD at addr 0x00
write_status = Write_EEPROM(&EEPROM_SPI_PORT, addr, tx_data);
HAL_Delay(10);
// Disabling the EEPROM (with an EWDS) after a WRITE as described in the datasheet
disable_status = Disable_EEPROM(&EEPROM_SPI_PORT);
HAL_Delay(10);
// Re-enabling it
enable_status = Enable_EEPROM(&EEPROM_SPI_PORT);
HAL_Delay(10);
// Read from the EEPROM. This part isn't working.
read_status = Read_EEPROM(&EEPROM_SPI_PORT, addr, rx_data);
HAL_Delay(10);
// Pull the CS pin low to deselect the chip again.
HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_RESET);
while (1)
{
}
}
SPI 初始化为处理 16 位数据值
SPI_HandleTypeDef hspi1;
/* SPI1 init function */
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_16BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi1.Init.NSS = SPI_NSS_SOFT;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi1.Init.CRCPolynomial = 10;
if (HAL_SPI_Init(&hspi1) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
这些是 EEPROM 功能
#define ERASE 0x07 // erase specific memory location. This is followed by the 8-bit address and then by the 16-bit data.
#define READ 0x06 // read the memory location.
#define WRITE 0x05 // write to the memory location
#define EEPROM_SPI_PORT hspi1
extern SPI_HandleTypeDef EEPROM_SPI_PORT;
//Enable the EEPROM
//Accepts: SPI handle
//Returns: Success or failure of the enable operation
uint8_t Enable_EEPROM (SPI_TypeDef *spi_handle) {
uint16_t ewen = (0x04 << 8) | 0b00110000;
if (HAL_SPI_Transmit(spi_handle, &ewen, 1, HAL_MAX_DELAY) == HAL_OK) return TRUE;
else return FALSE;
}
//Disable the EEPROM
//Accepts: SPI handle
//Returns: Success or failure of the disable operation
uint8_t Disable_EEPROM (SPI_TypeDef *spi_handle) {
uint16_t ewds = (0x04 << 8) | 0b00000000;
if (HAL_SPI_Transmit(spi_handle, &ewds, 1, HAL_MAX_DELAY) == HAL_OK) return TRUE;
else return FALSE;
}
//Read from the EEPROM
//Accepts: SPI handle, memory address and data buffer where the read value will be stored
//Returns: Success or failure of read operation
uint8_t Read_EEPROM (SPI_TypeDef *spi_handle, uint8_t addr, uint16_t data) {
uint16_t write_package;
write_package = (READ << 8 | addr);
// if (HAL_SPI_Transmit(spi_handle, &write_package, 1, HAL_MAX_DELAY) == HAL_OK) {
// HAL_Delay(10);
// if (HAL_SPI_Receive(spi_handle, &data, 1, HAL_MAX_DELAY) == HAL_OK) return TRUE;
// else return FALSE;
// }
if (HAL_SPI_TransmitReceive(spi_handle, &write_package, &data, 1, HAL_MAX_DELAY) == HAL_OK) return TRUE;
else return FALSE;
}
//Write to the EEPROM
//Accepts: SPI handle, memory address and data to be written
//Returns: Success or failure of write operation
uint8_t Write_EEPROM (SPI_TypeDef *spi_handle, uint8_t addr, uint16_t data) {
uint16_t write_package[2];
write_package[0] = (WRITE << 8 | addr);
write_package[1] = data;
if (HAL_SPI_Transmit(spi_handle, write_package, 2, HAL_MAX_DELAY) == HAL_OK) return TRUE;
else return FALSE;
}
//Erase a specific memory address from the EEPROM
//Accepts: SPI handle and the memory address to be erased
//Returns: Success or failure of erase operation
uint8_t Erase_EEPROM (SPI_TypeDef *spi_handle, uint8_t addr) {
uint16_t write_package;
write_package = (ERASE << 8 | addr);
if (HAL_SPI_Transmit(spi_handle, &write_package, 1, HAL_MAX_DELAY) == HAL_OK) return TRUE;
else return FALSE;
}
编辑:我在这里也附上了波形。
使能够
擦除
写