|
Память (внешняя память), Как устроена память??? |
|
|
|
Sep 4 2007, 11:26
|
Участник

Группа: Участник
Сообщений: 35
Регистрация: 8-08-07
Из: MockBa
Пользователь №: 29 658

|
Помогите разобраться как устроена память:
1. как устроена адресация памяти (т.е. как выставляются адреса для записи, чтения) 2. как записывать, читать данные.
в принципе общее устройство памяти понятно - данные забиваются в конкретные адреса памяти.
хотелось бы понять как прописывать адреса для нескольких записей в память (при чтении).
Вот, например, есть строка n-символов (пусть будет 80 бит), периодически строка меняется (кол-во символов не меняется), т.е каждую строку нужно записывать в свой конкретный адрес. как нужно учитывать это при простановке адреса для записи??
затем надо считывать записанные строки из памяти, как узнать по какому адресу находятся конкретная записанная строка???
Если можно покажите код на Си для реализации данного дела (желательно с пояснениями).
использую компилятор CodeVision, в качестве памяти используется FL25L256, микроконтроллер мега128, соединены по интерфейсу SPI.
Заранее извините за безграммотность по данному вопросу, и заранее всем спасибо!!!
|
|
|
|
|
Sep 4 2007, 14:56
|
Участник

Группа: Участник
Сообщений: 35
Регистрация: 8-08-07
Из: MockBa
Пользователь №: 29 658

|
Цитата(vesago @ Sep 4 2007, 18:48)  Если второе, заводите пару функций типа u8_t Read_EEPROM(u16_t addr, u8_t len, u8_t *buf); u8_t Write_EEPROM(u16_t addr, u8_t len, u8_t *buf); Если несколько одинаковых записей, в качестве addr передаете номер записи, умноженный на размер записи ну и опционально плюс смещение. Более конкретно интересует этот вопрос. Если можно распишите пожалуйста более детально ("Если несколько одинаковых записей, в качестве addr передаете номер записи, умноженный на размер записи ну и опционально плюс смещение"). С памятью никогда не работал, а требуется сделать описанное выше. Так что более подробная инфа по данной теме никогда не помешает. Очень интересует реалиазация процедур на Си.
|
|
|
|
|
Sep 5 2007, 09:48
|
Знающий
   
Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153

|
Цитата(satnettv @ Sep 4 2007, 18:56)  Более конкретно интересует этот вопрос. Если можно распишите пожалуйста более детально ("Если несколько одинаковых записей, в качестве addr передаете номер записи, умноженный на размер записи ну и опционально плюс смещение"). С памятью никогда не работал, а требуется сделать описанное выше. Так что более подробная инфа по данной теме никогда не помешает. Очень интересует реалиазация процедур на Си. Пусть у вас есть структура typedef struct { ///все, что угодно, в том числе ваша строка } TStruct; TStruct a, b, c, d; и вам надо их хранить в памяти начиная с адреса ADDR друг за другом. Тогда адрес первой структуры будет ADDR, второй - ADDR + sizeof(TStruct), n-ой ADDR + sizeof(TStruct) * (n-1). Этот адрес вы и передете вышеуказанным ф-циям. Как реализовать эти ф-ции для вашео типа памяти - надо почитать даташит. Скорее всего, есть некие опкоды записи и чтения, вы сначала передаете опкод, затем адрес, а затем либо пишите либо читаете информацию. Запись может быть более сложная, если стирание происходит секторами; часто запись ограничена 1-й страницей. Но тут вам надо прочитать даташит, и если будут конкретные вопросы - задавайте.
Сообщение отредактировал Непомнящий Евгений - Sep 5 2007, 09:48
|
|
|
|
|
Sep 5 2007, 10:11
|
Участник

Группа: Участник
Сообщений: 35
Регистрация: 8-08-07
Из: MockBa
Пользователь №: 29 658

|
Цитата(Непомнящий Евгений @ Sep 5 2007, 13:48)  Пусть у вас есть структура typedef struct { ///все, что угодно, в том числе ваша строка } TStruct; TStruct a, b, c, d; и вам надо их хранить в памяти начиная с адреса ADDR друг за другом. Тогда адрес первой структуры будет ADDR, второй - ADDR + sizeof(TStruct), n-ой ADDR + sizeof(TStruct) * (n-1). Этот адрес вы и передете вышеуказанным ф-циям. Как реализовать эти ф-ции для вашео типа памяти - надо почитать даташит. Скорее всего, есть некие опкоды записи и чтения, вы сначала передаете опкод, затем адрес, а затем либо пишите либо читаете информацию. Запись может быть более сложная, если стирание происходит секторами; часто запись ограничена 1-й страницей. Но тут вам надо прочитать даташит, и если будут конкретные вопросы - задавайте. Со структорой не совсем понятно как-то (если можно распишите на примере). По поводу оп-кодов для памяти все изучил, смысл общий понятен. У меня задача состоит в следующем: написать 2 процедуры чтения и записи в память (т.е. в какой-то момент формируются строки по n-символов, далее их нужно записывать в память, как-то считать кол-во строк записанных в память, а затем в какой-то момент времени считать все строки из памяти). Вот в принципе что мне надо. Если вас не затруднит не могли бы ли вы расписать этот процесс по подробнее. а еще интересует процесс упаовки данных (т.е. какое-то примитивное сжатие данных) перед тем как посылать в память.
|
|
|
|
|
Sep 5 2007, 14:29
|
Участник

Группа: Участник
Сообщений: 35
Регистрация: 8-08-07
Из: MockBa
Пользователь №: 29 658

|
Цитата(satnettv @ Sep 5 2007, 14:11)  Со структорой не совсем понятно как-то (если можно распишите на примере). По поводу оп-кодов для памяти все изучил, смысл общий понятен. У меня задача состоит в следующем: написать 2 процедуры чтения и записи в память (т.е. в какой-то момент формируются строки по n-символов, далее их нужно записывать в память, как-то считать кол-во строк записанных в память, а затем в какой-то момент времени считать все строки из памяти). Вот в принципе что мне надо. Если вас не затруднит не могли бы ли вы расписать этот процесс по подробнее. а еще интересует процесс упаовки данных (т.е. какое-то примитивное сжатие данных) перед тем как посылать в память. #include <mega128.h> #include <stdio.h> #include <spi.h> #include <delay.h> #define WREN 0x06 //Set Write Enable Latch #define WRDI 0x04 //Write Disable #define RDSR 0x05 //Read Status Register #define WRSR 0x01 //Write Status Register #define READ 0x03 //Read Memory Data #define WRITE 0x02 //Write Memory Data #define Ready 1; #define SPIF 0x80 //Флаг прерывания по SPI #define Zapis 80 //размер строки #define Dop 30 // смещение char Zap[128] //запись из памяти char nmbzap=0; //количество записей в памяти char TOP_ADDR=256; unsigned char temp = 0x80; // SPI interrupt service routine interrupt [SPI_STC] void spi_isr(void) { unsigned char data; data=SPDR; } /* проверка занятости интерфейса SPI*/ char ReadySPI(void) { return (SPSR>>7); // 1 - ready } /* чтение из памяти одного или нескольких байт */ /* Чтение записи*/ char ReadSPI(int address) { if ((address) <= TOP_ADDR) { if (SPSR & temp) // проверка занятости интерфейса SPI { SPCR = 0x00; //запрет прерывания по SPI SPDR = READ; //передать оп-код READ return SPDR; } } } /* Запись */ char WriteSPI(int mesto, char Dzap) { if (start_add <= TOP_ADDR) { if (SPSR & temp) // проверка занятости интерфейса SPI { SPDR = WREN; // оп-код подготовки записи SPDR = WRITE; // оп-код записи SPAR = nmbzap*Zapis+Dop; // адрес (номер записи, ус\множенный на размер записи + смещение) SPDR = Dzap; // данные nmbzap++; // счетчик записей в памяти } } } /*передача данных из памяти дальше*/ if ( 1==1 ) //если есть коннект { if (nmbzap!=0) //есть записи в памяти? { for(i=0; i<nmbzap; i++) // считываем сохраненные записи из памяти { Zap[i] = ReadSPI(i*Zapis+Dop); // i-я строка из памяти } nmbzap=0; } } /******************************/ вот пример моего кода, объясните, что я делаю не так.
|
|
|
|
|
Sep 5 2007, 14:36
|
Участник

Группа: Участник
Сообщений: 35
Регистрация: 8-08-07
Из: MockBa
Пользователь №: 29 658

|
Делаю для себя, микроконтроллер mega128, внешняя памятьFL25L256, соединены по SPI, программирую в CodeVision
#include <mega128.h> #include <stdio.h> #include <spi.h> #include <delay.h>
#define WREN 0x06 //Set Write Enable Latch #define WRDI 0x04 //Write Disable #define RDSR 0x05 //Read Status Register #define WRSR 0x01 //Write Status Register #define READ 0x03 //Read Memory Data #define WRITE 0x02 //Write Memory Data #define Ready 1; #define SPIF 0x80 //Флаг прерывания по SPI #define Zapis 80 //размер строки #define Dop 30 // смещение
char Zap[128] //запись из памяти char nmbzap=0; //количество записей в памяти
char TOP_ADDR=256; unsigned char temp = 0x80;
// SPI interrupt service routine interrupt [SPI_STC] void spi_isr(void) { unsigned char data; data=SPDR; }
/* проверка занятости интерфейса SPI*/
char ReadySPI(void) { return (SPSR>>7); // 1 - ready }
/* чтение из памяти одного или нескольких байт */
/* Чтение записи*/ char ReadSPI(int address)
{
if ((address) <= TOP_ADDR) { if (SPSR & temp) // проверка занятости интерфейса SPI { SPCR = 0x00; //запрет прерывания по SPI SPDR = READ; //передать оп-код READ return SPDR; } } }
/* Запись */ char WriteSPI(int mesto, char Dzap) { if (start_add <= TOP_ADDR) { if (SPSR & temp) // проверка занятости интерфейса SPI { SPDR = WREN; // оп-код подготовки записи SPDR = WRITE; // оп-код записи SPAR = nmbzap*Zapis+Dop; // адрес (номер записи, ус\множенный на размер записи + смещение) SPDR = Dzap; // данные nmbzap++; // счетчик записей в памяти } } }
/*передача данных из памяти дальше*/
if ( 1==1 ) //если есть коннект { if (nmbzap!=0) //есть записи в памяти? { for(i=0; i<nmbzap; i++) // считываем сохраненные записи из памяти { Zap[i] = ReadSPI(i*Zapis+Dop); // i-я строка из памяти } nmbzap=0; } } /******************************/
вот пример моего кода, объясните, что я делаю не так. я никак не могу понять как правильно выставлять адрес для заполнения памяти, а также как правильно организовать счетчик записи нескольких строк в память (т.е. я на каком-то этапе делаю несколько записей (строки по 80 символов) в память, считаю сколько строк я записал, а затем по какой-то команде мне нужно считать эти строки из памяти). Ну вот как мне это сделать?????
|
|
|
|
|
Sep 5 2007, 15:05
|
Знающий
   
Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153

|
Все  Цитата(satnettv @ Sep 5 2007, 18:29)  // SPI interrupt service routine interrupt [SPI_STC] void spi_isr(void) { unsigned char data; data=SPDR; } Зачем вам прерывание, если вы его не используете? Цитата /* Чтение записи*/ char ReadSPI(int address)
{ if ((address) <= TOP_ADDR) { if (SPSR & temp) // проверка занятости интерфейса SPI { SPCR = 0x00; //запрет прерывания по SPI SPDR = READ; //передать оп-код READ return SPDR; } } } По-моему, должно быть примерно так: Код /* Чтение записи*/ char ReadSPI(int address)
{ if ((address) <= TOP_ADDR) { SPDR = READ; //передать оп-код READ while (!ReadySPI()); SPDR = address; // это если адрес однобайтовый. Иначе см даташит while (!ReadySPI()); return SPDR; } return 0; } Эта процедура считывает 1 байт. Разумнее считывать сразу несколько байт в буфер. Примерно так: Код /* Чтение записи*/ void ReadSPIToBuf(int address, char *buf, int length) { if ((address) <= TOP_ADDR) { SPDR = READ; //передать оп-код READ while (!ReadySPI()); SPDR = address; // это если адрес однобайтовый. Иначе см даташит while (!ReadySPI()); while (length--) { *buf++ = SPDR; while (!ReadySPI()); } } } Запись переделайте в том-же духе. Надо посмотреть аташит, сколько длится запись. Возможно придется считывать статусный регистр памяти и анализировать... Насчет структур - примерно так: Код typedef struct { char str[10]; }TStruct; TStruct a;
ReadSPIToBuf(0, (char*)&a, sizeof(TStruct));
|
|
|
|
|
Sep 6 2007, 11:45
|
Участник

Группа: Участник
Сообщений: 35
Регистрация: 8-08-07
Из: MockBa
Пользователь №: 29 658

|
Цитата(satnettv @ Sep 4 2007, 15:26)  Помогите разобраться как устроена память:
1. как устроена адресация памяти (т.е. как выставляются адреса для записи, чтения) 2. как записывать, читать данные.
в принципе общее устройство памяти понятно - данные забиваются в конкретные адреса памяти.
хотелось бы понять как прописывать адреса для нескольких записей в память (при чтении).
Вот, например, есть строка n-символов (пусть будет 80 бит), периодически строка меняется (кол-во символов не меняется), т.е каждую строку нужно записывать в свой конкретный адрес. как нужно учитывать это при простановке адреса для записи??
затем надо считывать записанные строки из памяти, как узнать по какому адресу находятся конкретная записанная строка??? Если можно покажите код на Си для реализации данного дела (желательно с пояснениями).
использую компилятор CodeVision, в качестве памяти используется FL25L256, микроконтроллер мега128, соединены по интерфейсу SPI. Заранее извините за безграммотность по данному вопросу, и заранее всем спасибо!!! даташит на память - http://www.compel.ru/images/catalog/552/FM...56comm_r2.2.pdfпостараюсь объяснить задачу: имеется контроллер мега 128 и память вышеуказанная, соединены по SPI, программирую на CodeVision. требуется написать процедуры чтения и записи, для того чтобы выполнялось следующее: контроллер формирует строку - некую последовательность символов (допустим 80 символов), затем если выполнятеся условие, к примеру 1, он отсылает эту строку дальше и так далее. если же условие 1 не выолняется, то контроллер должен записать эту строку во внешнюю память. далее проверяется условие 1 по приходу следующей строки, если опять не выполняется условие 1, то записываем еще одну строку в память и так далее (при этом нужен какой-то счетчик, чтобы знать сколько записано строк в память). При выполнении условия 1, контроллер должен проверить наличие сохраннех строк в памяти, если есть то отослать их дальше, при этом следует обнулить счетчик записей в память. ну вот, примерно я объяснил, что требуется, может что-то не понятно?
|
|
|
|
|
Sep 6 2007, 11:46
|
Участник

Группа: Участник
Сообщений: 35
Регистрация: 8-08-07
Из: MockBa
Пользователь №: 29 658

|
Цитата(satnettv @ Sep 5 2007, 18:36)  Делаю для себя, микроконтроллер mega128, внешняя памятьFL25L256, соединены по SPI, программирую в CodeVision
#include <mega128.h> #include <stdio.h> #include <spi.h> #include <delay.h>
#define WREN 0x06 //Set Write Enable Latch #define WRDI 0x04 //Write Disable #define RDSR 0x05 //Read Status Register #define WRSR 0x01 //Write Status Register #define READ 0x03 //Read Memory Data #define WRITE 0x02 //Write Memory Data #define Ready 1; #define SPIF 0x80 //Флаг прерывания по SPI #define Zapis 80 //размер строки #define Dop 30 // смещение
char Zap[128] //запись из памяти char nmbzap=0; //количество записей в памяти
char TOP_ADDR=256; unsigned char temp = 0x80;
// SPI interrupt service routine interrupt [SPI_STC] void spi_isr(void) { unsigned char data; data=SPDR; } /* проверка занятости интерфейса SPI*/
char ReadySPI(void) { return (SPSR>>7); // 1 - ready }
/* чтение из памяти одного или нескольких байт */
/* Чтение записи*/ char ReadSPI(int address)
{
if ((address) <= TOP_ADDR) { if (SPSR & temp) // проверка занятости интерфейса SPI { SPCR = 0x00; //запрет прерывания по SPI SPDR = READ; //передать оп-код READ return SPDR; } } } /* Запись */ char WriteSPI(int mesto, char Dzap) { if (start_add <= TOP_ADDR) { if (SPSR & temp) // проверка занятости интерфейса SPI { SPDR = WREN; // оп-код подготовки записи SPDR = WRITE; // оп-код записи SPAR = nmbzap*Zapis+Dop; // адрес (номер записи, ус\множенный на размер записи + смещение) SPDR = Dzap; // данные nmbzap++; // счетчик записей в памяти } } } /*передача данных из памяти дальше*/
if ( 1==1 ) //если есть коннект { if (nmbzap!=0) //есть записи в памяти? { for(i=0; i<nmbzap; i++) // считываем сохраненные записи из памяти { Zap[i] = ReadSPI(i*Zapis+Dop); // i-я строка из памяти } nmbzap=0; } } /******************************/ вот пример моего кода, объясните, что я делаю не так. я никак не могу понять как правильно выставлять адрес для заполнения памяти, а также как правильно организовать счетчик записи нескольких строк в память (т.е. я на каком-то этапе делаю несколько записей (строки по 80 символов) в память, считаю сколько строк я записал, а затем по какой-то команде мне нужно считать эти строки из памяти). Ну вот как мне это сделать????? даташит на память - http://www.compel.ru/images/catalog/552/FM...56comm_r2.2.pdfпостараюсь объяснить задачу: имеется контроллер мега 128 и память вышеуказанная, соединены по SPI, программирую на CodeVision. требуется написать процедуры чтения и записи, для того чтобы выполнялось следующее: контроллер формирует строку - некую последовательность символов (допустим 80 символов), затем если выполнятеся условие, к примеру 1, он отсылает эту строку дальше и так далее. если же условие 1 не выолняется, то контроллер должен записать эту строку во внешнюю память. далее проверяется условие 1 по приходу следующей строки, если опять не выполняется условие 1, то записываем еще одну строку в память и так далее (при этом нужен какой-то счетчик, чтобы знать сколько записано строк в память). При выполнении условия 1, контроллер должен проверить наличие сохраннех строк в памяти, если есть то отослать их дальше, при этом следует обнулить счетчик записей в память. ну вот, примерно я объяснил, что требуется, может что-то не понятно?
|
|
|
|
|
Sep 6 2007, 12:21
|
Участник

Группа: Участник
Сообщений: 35
Регистрация: 8-08-07
Из: MockBa
Пользователь №: 29 658

|
даташит на память - http://www.compel.ru/images/catalog/552/FM...56comm_r2.2.pdfпостараюсь объяснить задачу: имеется контроллер мега 128 и память вышеуказанная, соединены по SPI, программирую на CodeVision. требуется написать процедуры чтения и записи, для того чтобы выполнялось следующее: контроллер формирует строку - некую последовательность символов (допустим 80 символов), затем если выполнятеся условие, к примеру 1, он отсылает эту строку дальше и так далее. если же условие 1 не выолняется, то контроллер должен записать эту строку во внешнюю память. далее проверяется условие 1 по приходу следующей строки, если опять не выполняется условие 1, то записываем еще одну строку в память и так далее (при этом нужен какой-то счетчик, чтобы знать сколько записано строк в память). При выполнении условия 1, контроллер должен проверить наличие сохраннех строк в памяти, если есть то отослать их дальше, при этом следует обнулить счетчик записей в память. ну вот, примерно я объяснил, что требуется, может что-то не понятно?
|
|
|
|
|
Sep 6 2007, 12:33
|
Группа: Новичок
Сообщений: 10
Регистрация: 3-04-07
Пользователь №: 26 733

|
Цитата(satnettv @ Sep 6 2007, 15:21)  даташит на память - http://www.compel.ru/images/catalog/552/FM...56comm_r2.2.pdfпостараюсь объяснить задачу: имеется контроллер мега 128 и память вышеуказанная, соединены по SPI, программирую на CodeVision. требуется написать процедуры чтения и записи, для того чтобы выполнялось следующее: контроллер формирует строку - некую последовательность символов (допустим 80 символов), затем если выполнятеся условие, к примеру 1, он отсылает эту строку дальше и так далее. если же условие 1 не выолняется, то контроллер должен записать эту строку во внешнюю память. далее проверяется условие 1 по приходу следующей строки, если опять не выполняется условие 1, то записываем еще одну строку в память и так далее (при этом нужен какой-то счетчик, чтобы знать сколько записано строк в память). При выполнении условия 1, контроллер должен проверить наличие сохраннех строк в памяти, если есть то отослать их дальше, при этом следует обнулить счетчик записей в память. ну вот, примерно я объяснил, что требуется, может что-то не понятно? кольцевой буфер делай, если размер строки фиксирован. если нет - фиксируй его по бОльшему размеру.
|
|
|
|
|
Sep 7 2007, 06:31
|
Знающий
   
Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153

|
Уважаемый satnettv! Насколько я понимаю, вы полный новичок в программировании МК, поэтому у вас ничего не работает  и ваши вопросы настолько общие и невнятные, что ответом на них может стать только сишный код, который выполняет то, что вы хотите  . Лично я не работал с вашей моделью памяти и мне лень лезть в ее даташит и разбираться в особенностях операций. Возможно, кто-то работал и любезно поделится с вами исходниками. Но пока этого не произошло - мой вам совет - разбейте свою большую задачу на несколько очень маленьких подзадач. Например: 1. Прочитать статус из памяти 2. Прочитать ID-номер (если такая возможность есть в вашей памяти) 3. Прочитать 1 байт 4. Записать 1 байт 5. Прочитать много байт 6 ... и т.д. Затем попытайтесь сами выполнить каждый пункт, и когда (если) у вас что-то не получится, спрашивайте, задавая конкретный вопрос и приводя небольшой кусочек своего кода. Тогда, как мне кажется, вы быстрее получите помощь...
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|