реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Чтение и запись во внешнюю память.
Jenya7
сообщение Jun 25 2015, 05:43
Сообщение #1


Профессионал
*****

Группа: Участник
Сообщений: 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
Go to the top of the page
 
+Quote Post
mcheb
сообщение Jun 25 2015, 05:52
Сообщение #2


Местный
***

Группа: Участник
Сообщений: 326
Регистрация: 30-05-06
Пользователь №: 17 602



Цитата(Jenya7 @ Jun 25 2015, 08:43) *
SPIEEPROM_Write(addr,sizeof(uint32_t),(uint8_t*) ival);

А это что за чудо?
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Jun 25 2015, 06:26
Сообщение #3


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(mcheb @ Jun 25 2015, 11:52) *
А это что за чудо?

сделал так
SPIEEPROM_Write(addr, 4, (uint8_t*) ival);
не помогло

Go to the top of the page
 
+Quote Post
mempfis_
сообщение Jun 25 2015, 07:29
Сообщение #4


Профессионал
*****

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



Цитата(Jenya7 @ Jun 25 2015, 09:26) *
сделал так SPIEEPROM_Write(addr, 4, (uint8_t*) ival); не помогло


Никто не может догадаться какой код у функции SPIEEPROM_Write(). Если у вас там serial eeprom то там важно знать адрес и размер блока данных.
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Jun 25 2015, 07:41
Сообщение #5


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(mempfis_ @ Jun 25 2015, 13:29) *
Никто не может догадаться какой код у функции SPIEEPROM_Write(). Если у вас там serial eeprom то там важно знать адрес и размер блока данных.

но float то пишется и читается значит SPIEEPROM_Write() работает корректно.
Go to the top of the page
 
+Quote Post
mempfis_
сообщение Jun 25 2015, 07:55
Сообщение #6


Профессионал
*****

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



Цитата(Jenya7 @ Jun 25 2015, 10:41) *
но float то пишется и читается значит SPIEEPROM_Write() работает корректно.


ОК. А в UART_SendInt(UART0,ival); нет ошибок?
Какой тип eeprom используется и по каким адресам пишется int и float?
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Jun 25 2015, 08:18
Сообщение #7


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(mempfis_ @ Jun 25 2015, 13:55) *
ОК. А в UART_SendInt(UART0,ival); нет ошибок?
Какой тип eeprom используется и по каким адресам пишется int и float?

я ставлю break point до UART_SendInt(UART0,ival);
пишу в один и тот же адрес. пробовал разные адреса. IAR сошел с ума? интерпретирует uint32_t неправильно?
Go to the top of the page
 
+Quote Post
mempfis_
сообщение Jun 25 2015, 08:29
Сообщение #8


Профессионал
*****

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



Цитата(Jenya7 @ Jun 25 2015, 11:18) *
я ставлю break point до UART_SendInt(UART0,ival);
пишу в один и тот же адрес. пробовал разные адреса. IAR сошел с ума? интерпретирует uint32_t неправильно?


Может для ускорения решения проблемы приведёте код базовых функций чтения/записи из/в eeprom, функций отправки int/float в uart, назовёте тип eeprom и конкретные адреса по которым происходит запись/чтение? Без этих данных мало чем можно помочь.
Ещё можно указать что за IAR и проверить размер стека программы.


Go to the top of the page
 
+Quote Post
Jenya7
сообщение Jun 25 2015, 08:55
Сообщение #9


Профессионал
*****

Группа: Участник
Сообщений: 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
Go to the top of the page
 
+Quote Post
mempfis_
сообщение Jun 25 2015, 09:10
Сообщение #10


Профессионал
*****

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



Цитата(Jenya7 @ Jun 25 2015, 11:55) *
IAR V7.2.
size_cstack__ = 0x400;
память CAT25256
вопрос почему float пишется-читается правильно а uint32_t нет.


По структуре функций - при чтении похоже всё нормально. А вот при записи не хватает ожидания завершения записи - контроля бита 0 (маска 0x01 в статус-регистре) сразу после SPI2_CShigh();. Любое обращение к памяти во время записи может сбить запись. Также я не увидел контроля пересечения границы страницы при записи данных. Если Вы вдруг захотите записать 4 байта начиная с адреса скажем 61 (мене чем за 4 байта до границы страницы) то получите сюрприз при чтении.
SPI_SendByte(USART2,SPIEEPROM_CMD_READ); отправляет байт в SPI и паралельно в UART?
SPI_TransferByte(USART2,0x00); - читает байт из SPI и паралельно отправляет байт в UART?
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Jun 25 2015, 09:40
Сообщение #11


Профессионал
*****

Группа: Участник
Сообщений: 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.
Go to the top of the page
 
+Quote Post
mempfis_
сообщение Jun 25 2015, 10:11
Сообщение #12


Профессионал
*****

Группа: Свой
Сообщений: 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;
}
//-------------------------------------------


Go to the top of the page
 
+Quote Post
Jenya7
сообщение Jun 25 2015, 10:17
Сообщение #13


Профессионал
*****

Группа: Участник
Сообщений: 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? а при чтении как я учитываю это?
Go to the top of the page
 
+Quote Post
mempfis_
сообщение Jun 25 2015, 10:32
Сообщение #14


Профессионал
*****

Группа: Свой
Сообщений: 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 байта.
А вот читать Вы можете непрерывно требуемое кол-во байт с любого адреса.
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Jun 25 2015, 10:58
Сообщение #15


Профессионал
*****

Группа: Участник
Сообщений: 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 но это конечно ужасно.
спасибо за алгоритм,попробую реализовать у меня точно данные залезут за границу.
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 20th July 2025 - 05:48
Рейтинг@Mail.ru


Страница сгенерированна за 0.01501 секунд с 7
ELECTRONIX ©2004-2016