|
Работа с внешней памятью |
|
|
|
Feb 28 2011, 14:38
|
Участник

Группа: Участник
Сообщений: 36
Регистрация: 7-04-10
Пользователь №: 56 467

|
Привет всем ГУРУ программирования МК.
Возникла такая проблемка. Есть внешняя память FM25L256. Почитал pdf на эту микросхему, вроде бы все понятно. Решил поработать. Написал алгоритм инициализации микросхемы, функции чтения и записи. Но, при выполнении этих функций, они работают, но результата никакого. Т.е. вроде бы пишет, вроде бы читает, но в массиве одни нули. Подскажите где что не так делаю? Просто уже несколько дней с этим мучаюсь, а результата ноль. Микруха подцеплина через SPI, он настроен корректно, вроде. Вот и чешу в затылке. К тому же я человек в этом деле новый, много не знаю. Прошу, пожалуйста, помогите.
Заранее всем спасибо. С уважением, Александр.
|
|
|
|
2 страниц
1 2 >
|
 |
Ответов
(1 - 24)
|
Mar 1 2011, 10:17
|
Участник

Группа: Участник
Сообщений: 36
Регистрация: 7-04-10
Пользователь №: 56 467

|
У меня тут вот какой вопрос родился. Какие действия в какой последовательности должны проходить. Я, например, делаю так: 1. Chip Select 2. Передача команды на разрешение записи в память 3. Передача команды записи данных 4. Передача адреса, с которого нужно начинать писать 5. Передача данных 6. После передачи сбросить Chip Select.
Естественно до этого происходит настройка SPI всех необходимых портов.
|
|
|
|
|
Mar 1 2011, 10:36
|
Местный
  
Группа: Свой
Сообщений: 480
Регистрация: 21-11-04
Пользователь №: 1 188

|
Цитата(SidAlex @ Mar 1 2011, 14:17)  ...4. Передача адреса, с которого нужно начинать писать... Важен порядок передачи байтов - начинать со старшего. Ну и обязательно дождаться статуса окончания записи. И еще пин разрешеня записи сбросить в "0".
|
|
|
|
|
Mar 1 2011, 10:44
|
Участник

Группа: Участник
Сообщений: 36
Регистрация: 7-04-10
Пользователь №: 56 467

|
Извините пожалуйста, а что значит "...обязательно дождаться статуса окончания записи..." И когда сбрасывать пин разрешения записи?
|
|
|
|
|
Mar 1 2011, 10:45
|
Гуру
     
Группа: Участник
Сообщений: 3 834
Регистрация: 14-06-06
Из: Moscow, Russia
Пользователь №: 18 047

|
Цитата(SidAlex @ Mar 1 2011, 13:17)  У меня тут вот какой вопрос родился. Какие действия в какой последовательности должны проходить. Я, например, делаю так: 1. Chip Select 2. Передача команды на разрешение записи в память 3. Передача команды записи данных 4. Передача адреса, с которого нужно начинать писать 5. Передача данных 6. После передачи сбросить Chip Select. Неправильно. После пункта 2 надо деактивировать CS, а перед пунктом 3 - вновь активировать. Цитата(SidAlex @ Mar 1 2011, 13:44)  Извините пожалуйста, а что значит "...обязательно дождаться статуса окончания записи..." Для рамтроновской памяти это не требуется, запись выполняется мгновенно.
|
|
|
|
|
Mar 1 2011, 10:48
|
Участник

Группа: Участник
Сообщений: 36
Регистрация: 7-04-10
Пользователь №: 56 467

|
А тогда подскажите пожалуйста, нужен ли между этими действиями таймаут или нет???
|
|
|
|
|
Mar 1 2011, 10:55
|
Местный
  
Группа: Свой
Сообщений: 480
Регистрация: 21-11-04
Пользователь №: 1 188

|
[quote name='rx3apf' date='Mar 1 2011, 14:45' post='892940'] Неправильно. После пункта 2 надо деактивировать CS, а перед пунктом 3 - вновь активировать. /quote] Да, конечно, не заметил...  Таймаут вроде не нужен, хватает команд, естественно выполняемых между операциями. А вот без проверки статуса при многостраничной записи не обойтись.
|
|
|
|
|
Mar 1 2011, 11:05
|
Участник

Группа: Участник
Сообщений: 36
Регистрация: 7-04-10
Пользователь №: 56 467

|
И еще тогда вопрос, а как читать? Порядок действий тот же или нет?
|
|
|
|
|
Mar 1 2011, 11:09
|
Местный
  
Группа: Свой
Сообщений: 480
Регистрация: 21-11-04
Пользователь №: 1 188

|
Цитата(SidAlex @ Mar 1 2011, 15:05)  И еще тогда вопрос, а как читать? Порядок действий тот же или нет? Тот же. Только CS дважды дергать не надо.
|
|
|
|
|
Mar 1 2011, 11:13
|
Участник

Группа: Участник
Сообщений: 36
Регистрация: 7-04-10
Пользователь №: 56 467

|
т.е. 1. Chip Select 2. Передача команды на разрешение чтения 4. Передача адреса, с которого нужно начинать читать 5. Чтение данных 6. После всего сбросить Chip Select.
Правильно???
|
|
|
|
|
Mar 1 2011, 11:29
|
Местный
  
Группа: Свой
Сообщений: 480
Регистрация: 21-11-04
Пользователь №: 1 188

|
Цитата(rx3apf @ Mar 1 2011, 15:18)  Для рамтроновской памяти - не нужно, запись выполняется мгновенно, и бит готовности всегда равен нулю. Посмотрел сейчас даташит - действительно, Вы правы. Я пользовал Numonyx, а там совсем даже не ноль...
|
|
|
|
|
Mar 1 2011, 11:44
|
Участник

Группа: Участник
Сообщений: 36
Регистрация: 7-04-10
Пользователь №: 56 467

|
Ребята ничего не понимаю, вроде написано все как говорите, но ничего не происходит. Точнее запись вроде есть, а вот прочитать не могу. Где что не так? Функции записи чтения прилагаю:
void WriteFM25L256(unsigned int adress, char *mass, int nbyte) { unsigned int a; // OFF_HOLD_FRAM(); //продолжить передачу данных из FRAM // OFF_WP_FRAM(); //отключить защиту записи CS_FRAM(); //чип-селект для FRAM
while (!(IFG1 & UTXIFG0));//провека готовности ТХ-буфера U0TXBUF = WREN_FM25L; //разрешение записи в FM25L256 while(!(U0TCTL & TXEPT)); // __no_operation(); // __no_operation(); // __no_operation(); // __no_operation(); OFF_CS_FRAM(); //сброс чипселекта FRAM CS_FRAM(); //чип-селект для FRAM while (!(IFG1 & UTXIFG0));//провека готовности ТХ-буфера U0TXBUF = WRITE_FM25L; //разрешение записи в FM25L256 while(!(U0TCTL & TXEPT)); while (!(IFG1 & UTXIFG0));//провека готовности ТХ-буфера U0TXBUF = adress >> 8; //запись старшего байта адреса while(!(U0TCTL & TXEPT)); while (!(IFG1 & UTXIFG0));//провека готовности ТХ-буфера U0TXBUF = adress; //запись младшего байта адреса while(!(U0TCTL & TXEPT)); for(a = 0; a < nbyte; a++) { // while (!(IFG1 & UTXIFG0)); //провека готовности ТХ-буфера // U0TXBUF = mass[a] >> 8; //передать старший байт элемента массива while (!(IFG1 & UTXIFG0)); //провека готовности ТХ-буфера U0TXBUF = mass[a]; //передать младший байт элемента массива while(!(U0TCTL & TXEPT)); }; // while(!(U0TCTL & TXEPT)); //пусты ли регистры TX // WP_FRAM(); //включить защиту записи OFF_CS_FRAM(); //сброс чипселекта FRAM }
void ReadFM25L256(unsigned int adress, char *mass, int nbyte) { unsigned int a; CS_FRAM(); //чип-селект для FRAM
while (!(IFG1 & UTXIFG0));//провека готовности ТХ-буфера U0TXBUF = READ_FM25L; //команда //разрешение чтения из FM25L256 while(!(U0TCTL & TXEPT)); while (!(IFG1 & UTXIFG0)); //провека готовности ТХ-буфера U0TXBUF = adress >> 8; //запись старшего байта адреса while(!(U0TCTL & TXEPT)); while (!(IFG1 & UTXIFG0)); //провека готовности ТХ-буфера U0TXBUF = adress; //запись младшего байта адреса while(!(U0TCTL & TXEPT)); for(a = 0; a < nbyte; a++) { while (!(IFG1 & UTXIFG0)); //ожидание готовности TX-буфера U0TXBUF = 0x40; //тактирование FRAM while(!(U0TCTL & TXEPT)); while (!(IFG1 & URXIFG0)); //ожидание готовности RХ-буфера mass[a] = U0RXBUF; //считывание из RX-буфера в массив страшего байта while(!(U0TCTL & TXEPT)); } //while(!(U0TCTL & TXEPT)); //пусты ли регистры TX OFF_CS_FRAM(); //сброс чипселекта FRAM }/* конец определения ------------------------------------------------------------------*/
|
|
|
|
|
Mar 1 2011, 13:01
|
Участник

Группа: Участник
Сообщений: 36
Регистрация: 7-04-10
Пользователь №: 56 467

|
Вот переделал, вставил, чтобы читать было удобнее Код void WriteFM25L256(unsigned int adress, char *mass, int nbyte) { unsigned int a;
// OFF_HOLD_FRAM(); //продолжить передачу данных из FRAM // OFF_WP_FRAM(); //отключить защиту записи CS_FRAM(); //чип-селект для FRAM
while (!(IFG1 & UTXIFG0));//провека готовности ТХ-буфера U0TXBUF = WREN_FM25L; //разрешение записи в FM25L256 while(!(U0TCTL & TXEPT)); // __no_operation(); // __no_operation(); // __no_operation(); // __no_operation(); OFF_CS_FRAM(); //сброс чипселекта FRAM CS_FRAM(); //чип-селект для FRAM while (!(IFG1 & UTXIFG0));//провека готовности ТХ-буфера U0TXBUF = WRITE_FM25L; //разрешение записи в FM25L256 while(!(U0TCTL & TXEPT)); while (!(IFG1 & UTXIFG0));//провека готовности ТХ-буфера U0TXBUF = adress >> 8; //запись старшего байта адреса while(!(U0TCTL & TXEPT)); while (!(IFG1 & UTXIFG0));//провека готовности ТХ-буфера U0TXBUF = adress; //запись младшего байта адреса while(!(U0TCTL & TXEPT)); for(a = 0; a < nbyte; a++) { // while (!(IFG1 & UTXIFG0)); //провека готовности ТХ-буфера // U0TXBUF = mass[a] >> 8; //передать старший байт элемента массива while (!(IFG1 & UTXIFG0)); //провека готовности ТХ-буфера U0TXBUF = mass[a]; //передать младший байт элемента массива while(!(U0TCTL & TXEPT)); }; // while(!(U0TCTL & TXEPT)); //пусты ли регистры TX // WP_FRAM(); //включить защиту записи OFF_CS_FRAM(); //сброс чипселекта FRAM }
void ReadFM25L256(unsigned int adress, char *mass, int nbyte) { unsigned int a; CS_FRAM(); //чип-селект для FRAM
while (!(IFG1 & UTXIFG0));//провека готовности ТХ-буфера U0TXBUF = READ_FM25L; //команда //разрешение чтения из FM25L256 while(!(U0TCTL & TXEPT)); while (!(IFG1 & UTXIFG0)); //провека готовности ТХ-буфера U0TXBUF = adress >> 8; //запись старшего байта адреса while(!(U0TCTL & TXEPT)); while (!(IFG1 & UTXIFG0)); //провека готовности ТХ-буфера U0TXBUF = adress; //запись младшего байта адреса while(!(U0TCTL & TXEPT)); for(a = 0; a < nbyte; a++) { while (!(IFG1 & UTXIFG0)); //ожидание готовности TX-буфера U0TXBUF = 0x40; //тактирование FRAM while(!(U0TCTL & TXEPT)); while (!(IFG1 & URXIFG0)); //ожидание готовности RХ-буфера mass[a] = U0RXBUF; //считывание из RX-буфера в массив страшего байта while(!(U0TCTL & TXEPT)); } //while(!(U0TCTL & TXEPT)); //пусты ли регистры TX OFF_CS_FRAM(); //сброс чипселекта FRAM }/* конец определения ------------------------------------------------------------------*/
|
|
|
|
|
Mar 1 2011, 13:48
|
Местный
  
Группа: Свой
Сообщений: 480
Регистрация: 21-11-04
Пользователь №: 1 188

|
Если с пинами (W и HOLD) все в порядке, то замечание только одно: CODE void WriteFM25L256(unsigned int adress, char *mass, int nbyte) { unsigned int a;
CS_FRAM(); //чип-селект для FRAM while (!(IFG1 & UTXIFG0));//провека готовности ТХ-буфера U0TXBUF = WREN_FM25L; //разрешение записи в FM25L256 while(!(U0TCTL & TXEPT)); // __no_operation(); // __no_operation(); // __no_operation(); // __no_operation(); OFF_CS_FRAM(); //сброс чипселекта FRAM // ------- необходим таймаут хотя-бы на один такт SPI ------------ CS_FRAM(); //чип-селект для FRAM while (!(IFG1 & UTXIFG0));//провека готовности ТХ-буфера U0TXBUF = WRITE_FM25L; //разрешение записи в FM25L256 while(!(U0TCTL & TXEPT)); while (!(IFG1 & UTXIFG0));//провека готовности ТХ-буфера U0TXBUF = adress >> 8; //запись старшего байта адреса while(!(U0TCTL & TXEPT)); while (!(IFG1 & UTXIFG0));//провека готовности ТХ-буфера U0TXBUF = adress; //запись младшего байта адреса while(!(U0TCTL & TXEPT)); for(a = 0; a < nbyte; a++) { while (!(IFG1 & UTXIFG0)); //провека готовности ТХ-буфера U0TXBUF = mass[a]; //передать младший байт элемента массива while(!(U0TCTL & TXEPT)); }; OFF_CS_FRAM(); //сброс чипселекта FRAM }
|
|
|
|
|
Mar 1 2011, 14:03
|
Участник

Группа: Участник
Сообщений: 36
Регистрация: 7-04-10
Пользователь №: 56 467

|
Еще раз прошу прощения, но что значит WP и HOLD в порядке? Они должны быть установлены в каком то положении??? Они у меня подняты в единицу.
|
|
|
|
|
Mar 1 2011, 14:16
|
Местный
  
Группа: Свой
Сообщений: 480
Регистрация: 21-11-04
Пользователь №: 1 188

|
Цитата(SidAlex @ Mar 1 2011, 18:03)  Еще раз прошу прощения, но что значит WP и HOLD в порядке? Они должны быть установлены в каком то положении??? Они у меня подняты в единицу. Это нормально.
|
|
|
|
|
Mar 2 2011, 07:10
|
Участник

Группа: Участник
Сообщений: 36
Регистрация: 7-04-10
Пользователь №: 56 467

|
В общем не работает. Слать в микруху я данные шлю - это я вижу на осциллографе, а читать ничего не читаю. Скажите, пожалуйста, как должны быть установлены WP и HOLD. Вообще, если смотреть в мануал, то получается, что WP - это аппаратная защита от записи. Или я ошибаюсь? Про HOLD тоже вроде понятно, что если ноль, то все будет игнорироваться. А можно еще подсказать настройки SPI? Я вот так настраиваю: Код switch(UsartNumber) { case 0: U0CTL |= SWRST; U0CTL |= MM + SYNC + CHAR; //Master, SPI, 8-bit Data; U0TCTL |= STC + SSEL0 + SSEL1; U0BR0 = 0x02; U0BR1 = 0x00; U0MCTL = 0x00; ME1 |= USPIE0; U0CTL &= ~SWRST; break; case 1: U1CTL |= SWRST; U1CTL |= SYNC + CHAR; //Slave, SPI, 8-bit Data; U1TCTL |= STC + CKPH; U1BR0 = 0x02; U1BR1 = 0x00; U1MCTL = 0x00; ME2 |= USPIE1; U1CTL &= ~SWRST; break; default: break; }
|
|
|
|
|
Mar 2 2011, 10:18
|
Участник

Группа: Участник
Сообщений: 36
Регистрация: 7-04-10
Пользователь №: 56 467

|
микроконтроллер MSP430F1611IPM
|
|
|
|
|
Mar 2 2011, 11:05
|
Местный
  
Группа: Свой
Сообщений: 480
Регистрация: 21-11-04
Пользователь №: 1 188

|
Цитата(SidAlex @ Mar 2 2011, 14:18)  микроконтроллер MSP430F1611IPM Вряд-ли смогу помочь - лет шесть с ними не работал...
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|