|
Чтение и запись во внешнюю память. |
|
|
|
Jun 25 2015, 05:43
|
Профессионал
    
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075

|
Это функции чтения/записи. Код void SPIEEPROM_WriteInt(uint32_t addr, uint32_t *ival) { SPIEEPROM_Write(addr,sizeof(uint32_t),(uint8_t*) ival); }
uint32_t SPIEEPROM_ReadInt(uint32_t addr) { uint32_t value; SPIEEPROM_Read(addr, sizeof(uint32_t), (uint8_t*)&value); return value; }
void SPIEEPROM_WriteFloat(uint32_t addr, float *fval) { SPIEEPROM_Write(addr,sizeof(float),(uint8_t*) fval); }
float SPIEEPROM_ReadFloat(uint32_t addr) { float value; SPIEEPROM_Read(addr, sizeof(float), (uint8_t*)&value); return value; } А так я тестирую. Код uint32_t adr; if(argument1 == NULL) UART_SendString(UART0,msg_misarg); else { adr = atoi(argument1); if(argument2 == NULL) //read operation { #ifdef SPI_INT uint32_t ival = SPIEEPROM_ReadInt(adr); UART_SendInt(UART0,ival); #endif #ifdef SPI_FLOAT float fval = SPIEEPROM_ReadFloat(adr); UART_SendFloat(UART0,fval,2); #endif } else //write operation { #ifdef SPI_INT uint32_t ival = atoi(argument2); SPIEEPROM_WriteInt(adr, &ival); #endif #ifdef SPI_FLOAT float fval = atof(argument2); SPIEEPROM_WriteFloat(adr, &fval); #endif } } float пишется-читается прекрасно. а вот с uint32_t непонятное явление - пишет (или читает?) неправильно. вот например запись - чтение 100 - 255 300 - 511 1000 - 1023 Сижу второй день над проблемой не могу понять где собака порылась.
Сообщение отредактировал Jenya7 - Jun 25 2015, 05:44
|
|
|
|
2 страниц
1 2 >
|
 |
Ответов
(1 - 14)
|
Jun 25 2015, 05:52
|
Местный
  
Группа: Участник
Сообщений: 326
Регистрация: 30-05-06
Пользователь №: 17 602

|
Цитата(Jenya7 @ Jun 25 2015, 08:43)  SPIEEPROM_Write(addr,sizeof(uint32_t),(uint8_t*) ival); А это что за чудо?
|
|
|
|
|
Jun 25 2015, 06:26
|
Профессионал
    
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075

|
Цитата(mcheb @ Jun 25 2015, 11:52)  А это что за чудо? сделал так SPIEEPROM_Write(addr, 4, (uint8_t*) ival); не помогло
|
|
|
|
|
Jun 25 2015, 08:55
|
Профессионал
    
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075

|
Цитата(mempfis_ @ Jun 25 2015, 14:29)  Может для ускорения решения проблемы приведёте код базовых функций чтения/записи из/в eeprom, функций отправки int/float в uart, назовёте тип eeprom и конкретные адреса по которым происходит запись/чтение? Без этих данных мало чем можно помочь. Ещё можно указать что за IAR и проверить размер стека программы. это функции Код void SPIEEPROM_Write(uint32_t address, uint32_t lenght, uint8_t *buffer) { // Note!!!Every write operation demands a write enable!!! SPI2_CSlow(); SPI_SendByte(USART2,SPIEEPROM_CMD_WREN); SPI2_CShigh();
// start write SPI2_CSlow(); // send write command SPI_SendByte(USART2,SPIEEPROM_CMD_WRITE); // send address SPI_SendByte(USART2,address>>8); SPI_SendByte(USART2,address&0x00FF); while(lenght--) { // send data to be written SPI_SendByte(USART2,*buffer++); } // stop write SPI2_CShigh(); }
void SPIEEPROM_Read(uint32_t address, uint32_t lenght, uint8_t *buffer) { if(lenght>PAGE_SIZE) return; uint32_t data; // start read SPI2_CSlow(); // send command SPI_SendByte(USART2,SPIEEPROM_CMD_READ); // send address SPI_SendByte(USART2,address>>8); SPI_SendByte(USART2,address&0x00FF); // read contents of memory address while(lenght--) { data = SPI_TransferByte(USART2,0x00); *buffer++ = data; } // stop read SPI2_CShigh(); } IAR V7.2. size_cstack__ = 0x400; память CAT25256 вопрос почему float пишется-читается правильно а uint32_t нет.
Сообщение отредактировал Jenya7 - Jun 25 2015, 08:52
|
|
|
|
|
Jun 25 2015, 09:40
|
Профессионал
    
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075

|
Цитата(mempfis_ @ Jun 25 2015, 15:10)  По структуре функций - при чтении похоже всё нормально. А вот при записи не хватает ожидания завершения записи - контроля бита 0 (маска 0x01 в статус-регистре) сразу после SPI2_CShigh();. Любое обращение к памяти во время записи может сбить запись. Также я не увидел контроля пересечения границы страницы при записи данных. Если Вы вдруг захотите записать 4 байта начиная с адреса скажем 61 (мене чем за 4 байта до границы страницы) то получите сюрприз при чтении. SPI_SendByte(USART2,SPIEEPROM_CMD_READ); отправляет байт в SPI и паралельно в UART? SPI_TransferByte(USART2,0x00); - читает байт из SPI и паралельно отправляет байт в UART? спасибо за замечания. исправлю. однако это не объясняет проблему. я думал что для этой памяти не важно пересечение границы страницы. но я писал в разные адреса 10, 20,100. я пишу-читаю с терминала, после записи проходит достаточно времени. у меня USART2 настроен как SPI.
|
|
|
|
|
Jun 25 2015, 10:11
|

Профессионал
    
Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409

|
Цитата(Jenya7 @ Jun 25 2015, 12:40)  я думал что для этой памяти не важно пересечение границы страницы. но я писал в разные адреса 10, 20,100. я пишу-читаю с терминала, после записи проходит достаточно времени. у меня USART2 настроен как SPI. Пересечение границы очень важно и его нельзя упускать из виду. Также важно отследить завершение записи. Стоит также проконтролировать осциллографом запись в работающем и неработающем вариантах. Может быть там несанкционированные дёргания CS или искаженные символы при передаче адреса/данных. Не пробовали софтовый SPI прикрутить? Может быть проблемы с аппаратным? CODE //------------------------------------------- unsigned char SPIWriteChar(unsigned char cmd) { unsigned char i; unsigned char recv; recv = 0; for(i=0; i<8; i++) { if((cmd&0x80) != 0) { SPI_PORT_SET = MOSI; } else { SPI_PORT_CLR = MOSI; } SPI_PORT_SET = SCK; recv<<=1; if((SPI_PIN & MISO) != 0) { recv|=0x01; } SPI_PORT_CLR = SCK; cmd<<=1; } return recv; } //-------------------------------------------
|
|
|
|
|
Jun 25 2015, 10:17
|
Профессионал
    
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075

|
Цитата(mempfis_ @ Jun 25 2015, 16:11)  Пересечение границы очень важно и его нельзя упускать из виду. Также важно отследить завершение записи. Стоит также проконтролировать осциллографом запись в работающем и неработающем вариантах. Может быть там несанкционированные дёргания CS или искаженные символы при передаче адреса/данных. Не пробовали софтовый SPI прикрутить? Может быть проблемы с аппаратным? CODE //------------------------------------------- unsigned char SPIWriteChar(unsigned char cmd) { unsigned char i; unsigned char recv; recv = 0; for(i=0; i<8; i++) { if((cmd&0x80) != 0) { SPI_PORT_SET = MOSI; } else { SPI_PORT_CLR = MOSI; } SPI_PORT_SET = SCK; recv<<=1; if((SPI_PIN & MISO) != 0) { recv|=0x01; } SPI_PORT_CLR = SCK; cmd<<=1; } return recv; } //------------------------------------------- я смотрел и осциллографом и Logic Analizer все красиво. кстати а какой алгоритм проверки пересечения границы страницы? если я пишу uint32_t и следующая запись приходится на адрес 62 то что я перескакиваю на адрес 64? а при чтении как я учитываю это?
|
|
|
|
|
Jun 25 2015, 10:32
|

Профессионал
    
Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409

|
Цитата я смотрел и осциллографом и Logic Analizer все красиво. т.е. хотите сказать что адрес и данные корректные - что хотите записать то и видите на осциллографе? Цитата кстати а какой алгоритм проверки пересечения границы страницы? если я пишу uint32_t и следующая запись приходится на адрес 62 то что я перескакиваю на адрес 64? а при чтении как я учитываю это? Мне приходилось записывать блоки данных такой длины, что они вписывались в страницу без остатка. Если данные не влезают на текущую страницу, то надо вычислять сколько осталось до конца страницы, записывать столько байт, сколько влезет на текущую старницу, остаток дописывать на следующую страницу. Напр. адрес 446, пишем 4 байта. 446/64 = 6, 446%64 = 62. 64-62 = 2 - столько влезет на текущую страницу. Т.о. с адреса 446 Вы запишите 2 байта, а с адреса 448 ещё 2 байта. А вот читать Вы можете непрерывно требуемое кол-во байт с любого адреса.
|
|
|
|
|
Jun 25 2015, 10:58
|
Профессионал
    
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075

|
Цитата(mempfis_ @ Jun 25 2015, 16:32)  т.е. хотите сказать что адрес и данные корректные - что хотите записать то и видите на осциллографе?
Мне приходилось записывать блоки данных такой длины, что они вписывались в страницу без остатка. Если данные не влезают на текущую страницу, то надо вычислять сколько осталось до конца страницы, записывать столько байт, сколько влезет на текущую старницу, остаток дописывать на следующую страницу. Напр. адрес 446, пишем 4 байта. 446/64 = 6, 446%64 = 62. 64-62 = 2 - столько влезет на текущую страницу. Т.о. с адреса 446 Вы запишите 2 байта, а с адреса 448 ещё 2 байта. А вот читать Вы можете непрерывно требуемое кол-во байт с любого адреса. нет. данные неправильные но сигналы красивые. пока проблему решил так - просто делаю кастинг с float на uint32_t но это конечно ужасно. спасибо за алгоритм,попробую реализовать у меня точно данные залезут за границу.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|