This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
工具与软件:
我正在 TM4C1294NCPDT MCU 和 MX25L51245G 闪存之间使用 SSI 通信、但我无法正确读取连续写入的数据。 如何检索不包含垃圾字符或空字符的数据? 当我尝试写入连续数据然后逐行读取它时、我会收到以下日志:
正在写入数据1...
写入数据0x000000:{ATE-EVENT:354033090105,688,110、ALARM、EVENT、NORMAL、ACTIVE、PRIMARY、1,001,2019-07-13T08:24:14+00:00、Common Fire Alarm}
写入数据0x000075:
数据写入0x000000:{ATE-EVENT:354033090105,688,110、ALARM、EVENT、NORMAL、ACTIVE、PRIMARY、1,001,2019-07-13T08:24:14+00:00、Common Fire Alarm}
正在写入数据2...
写入数据0x000077:{"ATE-EVENT":"354033090105,688,950、报警、事件、正常、活动、辅助、1025、02019-07-13T09:08:35+00:00、SIM 故障"}
写入数据0x0000EB:
数据写入0x000077:{"ATE-EVENT":"354033090105,688,950、报警、事件、正常、活动、辅助、1025、02019-07-13T09:08:35+00:00、SIM 故障"}
正在写入数据3...
写入数据0x0000ED:{"ATE-EVENT":"354033090105,688,774、状态、事件、正常、活动、辅助、114、02019-07-13T09:08:57+00:00、低信号"}
写入数据0x000161:
写入数据0x0000ED:{"ATE-EVENT":"354033090105,688,774、状态、事件、正常、活动、辅助、114、02019-07-13T09:08:57+00:00、低信号"}
正在读取所有存储的数据...
行:3 0! 4$(0(354 30 001 %6 ($ a`` a d`dd$ dcbl`` a 0$,0 !0) 1000008(07)0000 (
行:2美元)、普通火警器
线路:{"ATE-EVENT":"354033090105,688,950、alarm、event、normal、active、secondary、1025,02019-07-13T09:08:35+00:00、SIM failure"}
行:
您好!
我不明白你的日志是什么意思。 谁打印这些日志? 您是否正在使用一些定制的 SPI 闪存库? 您从哪里获得库?
您好!
我将 FreeRTOS 用于 TM4C129 MCU。我使用了 #include "driverlib/ssi.h" 、 未使用其他自定义库。 我正在尝试在中写入和读取数据 MX25L51245G 闪存 驱动器芯片。 日志是通过 UART 读取的、我在上面向您分享了该 UART。 我能够通过命令写入数据 MX25_CMD_WREN (0x06)。 这可能会带来问题。
您能否共享代码?
我仍然不清楚您是如何写入和读取 SPI 闪存以及如何通过 UART 输出日志。
什么是 MX25_CMD_WREN? 我怎么知道这个函数在做什么? 这必须是您自己的函数、当然不是 TivaWare SDK 函数。
好的、这里有 "driverlib/ssi.h" 、 创建了 用于闪存写入的函数、
void EEPROM_PageWrite(uint32_t address, char *data, uint32_t length)
{
uint32_t i;
// Send Write Enable command
EEPROM_WriteEnable();
// Begin write operation
EEPROM_CS_LOW();
// Send Page Program command
SSIDataPut(SSI3_BASE, MX25_CMD_PP);
while (SSIBusy(SSI3_BASE));
// Send address (24-bit address, MSB first)
SSIDataPut(SSI3_BASE, (address >> 16) & 0xFF);
while (SSIBusy(SSI3_BASE));
SSIDataPut(SSI3_BASE, (address >> 8) & 0xFF);
while (SSIBusy(SSI3_BASE));
SSIDataPut(SSI3_BASE, address & 0xFF);
while (SSIBusy(SSI3_BASE));
// Write data
for (i = 0; i < length; i++)
{
SSIDataPut(SSI3_BASE, data[i]);
while (SSIBusy(SSI3_BASE));
}
// End write operation
EEPROM_CS_HIGH();
// Log the write operation
snprintf(log_buffer, sizeof(log_buffer), "Written data 0x%06X: %.*s\r\n", address, length, data);
UART2Write(log_buffer, strlen(log_buffer));
// Wait for the EEPROM to complete the write operation
SysCtlDelay(1000);
}
来自以下函数、面临数据读取问题。 此外、我提到过的日志会从 SPI 芯片中读取并存储在 log_buffer 中。
void EEPROM_ReadAllData(uint32_t start_address, uint32_t max_length)
{
char read_buffer[PAGE_SIZE] = {0};
char line_buffer[PAGE_SIZE] = {0};
uint32_t current_address = start_address;
uint32_t bytes_read = 0;
uint32_t line_index = 0;
while (bytes_read < max_length)
{
// Read a page of data
memset(read_buffer, 0, PAGE_SIZE);
EEPROM_Read(current_address / PAGE_SIZE, read_buffer, PAGE_SIZE);
int i;
// Process the read buffer line by line
for (i = 0; i < PAGE_SIZE; i++)
{
if (read_buffer[i] == '\0' || read_buffer[i] == '\r' || read_buffer[i] == '\n')
{
// End of line or data
if (line_index > 0)
{
line_buffer[line_index] = '\0';
snprintf(log_buffer, sizeof(log_buffer), "Line: %s\r\n", line_buffer);
UART2Write(log_buffer, strlen(log_buffer));
line_index = 0;
}
}
else
{
line_buffer[line_index++] = read_buffer[i];
}
}
current_address += PAGE_SIZE;
bytes_read += PAGE_SIZE;
}
}
这里、提及的 MX25_CMD_PP (0x02)、 MX25_CMD_WREN (0x06) WRITE_ENABLE 具有这些命令、可以为闪存芯片上的相应函数启用地址 MX25L51245G。 将 PAGE_SIZE 设置为264。 对于闪存读取、
void EEPROM_Read(uint32_t page, char *buffer, uint32_t length)
{
uint32_t address = page * PAGE_SIZE;
uint32_t i, rx_data, dummy;
EEPROM_CS_LOW();
// Send Fast Read command
SSIDataPut(SSI3_BASE, MX25_CMD_FAST_READ);
while (SSIBusy(SSI3_BASE));
// Send address (24-bit address, MSB first)
SSIDataPut(SSI3_BASE, (address >> 16) & 0xFF);
while (SSIBusy(SSI3_BASE));
SSIDataPut(SSI3_BASE, (address >> 8) & 0xFF);
while (SSIBusy(SSI3_BASE));
SSIDataPut(SSI3_BASE, address & 0xFF);
while (SSIBusy(SSI3_BASE));
// Send dummy byte (required for Fast Read)
SSIDataPut(SSI3_BASE, 0xFF);
while (SSIBusy(SSI3_BASE));
// Clear RX FIFO
while (SSIDataGetNonBlocking(SSI3_BASE, &dummy));
// Read data
for (i = 0; i < length; i++)
{
SSIDataPut(SSI3_BASE, 0xFF); // Dummy byte to clock out data
while (SSIBusy(SSI3_BASE));
SSIDataGet(SSI3_BASE, &rx_data);
buffer[i] = (char)(rx_data & 0xFF);
}
// Null terminate the buffer
buffer[length] = '\0';
EEPROM_CS_HIGH();
}
您好!
Unknown 说:但我无法正确读取连续写入的数据。 [报价]抱歉、我真的不知道您为什么阅读到意外数据。 您说您无法读取连续写入的数据。 我有几个问题。
-如果你只是做一个简单的写入,然后读,而不是连续的写入? 你能让它正常工作吗? 这是为了确定问题是与连续写入有关、还是与仅写入一次或不经常有关。
-你的日志字符串似乎很长。 您能否做一个实验来写入简单和简短的数据? 您是否能够读回短数据? 这是为了确定问题是否与字符串的长度有关。
-我还建议您使用逻辑分析仪来查看 SPI 总线并查看写入和读取了什么数据? 这将极大地帮助调试问题。
1)我看不到页面(256字节)边界的任何让步。 您对0xEB 的写入似乎打包并覆盖了0x00。 [请参阅数据表"(11)页面程序(PP)"说明]。 尝试(正如 Charles 所建议的)一次写和读回一个。
2) SysCtlDelay(1000); Are you fairly certain this is longer than Tpp=5ms (max)? It looks rather short.
是的、在读取连续数据之前、我尝试只写入一个数据并读取一个数据。 对于该情况、我可以读取数据、但存在问题、即写入3到5数据然后读取整个数据时。 对于我的情况、首先我需要存储一些数据集、然后我要读取这些数据。 所以,我尝试这样做。
您好!
将浏览提到的页面一次。 是的、在 SysCtlDelay 中它太短。 我将其设置为 SysCtlDelay (10000000)。 在这里、我能够获得一个写入数据。 读取时出现问题后立即开始计算。
您好!
我没有听到你的声音。 我现在将结束该主题。 如果您有任何更新、您可以回写此帖子、并且状态将更改为"已打开"。