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

 
 
4 страниц V   1 2 3 > »   
Reply to this topicStart new topic
> Кто работал с памятью at45db161d или в принципе с at45dbxxxd, пожалуйста подскажите, Проблемы с at45db161d и их решение
lomtev
сообщение Sep 23 2007, 07:48
Сообщение #1


Участник
*

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



Так вот, ситуация такая. Использовал примеры программ из аппноутов, переписал коды команд на те которые советуют в даташите. Перепроверил и в других источниках типа занятие 7 с сайт 123avr. Функции написаны правильно. Сначала стираю память, потом пишу в нее значения до 176, тобишь записываю 176 байт. Потом читаю память и сохраняю данные в массив, после вывожу массив на экран (в выводе символов ошибок нет точно), выводятся исключительно значения 255, в рядок так 255 255 255 и т.д. Впихивал вывод значений в разные места программы с выводом разных переменных - вроде все работает. да и в противном случае вывело первоначальное значение массива а это 0. Забавная еще вещь наблюдается, программа написана изначально была для 28 ногово чипа, а я использую 8 ногий так что приходится читать занятость из регистра стуса строчкой типа while (!(SPSR & temp));, я думал что ошибка в ожидании и добавил строчку SPDR = STATUS_REGISTER;, но потом удалил, покуда изменений не произошло.
Так теперь зараза не хочет работать без этой строчки, хотя раньше работала так же криво как и сейчас.
И еще при стирании биты выставляются как я понял в значение 255.
Кто-нибудь сталкивался или работал с данным чипом? В тупике. предположений нет вообще. Если кто хочет помочь и нуждается в наглядной демонстрации кода, то я выложу.
Go to the top of the page
 
+Quote Post
sensor_ua
сообщение Sep 23 2007, 08:11
Сообщение #2


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

Группа: Свой
Сообщений: 1 266
Регистрация: 22-04-05
Из: Киев
Пользователь №: 4 387



Похоже, чтение регистра статуса неправильное. Покажи. Вероятно отправляешь не 0xD7+1 байт, а только 0xD7 и сразу читаешь содержимое регистра SPI;)


--------------------
aka Vit
Go to the top of the page
 
+Quote Post
lomtev
сообщение Sep 23 2007, 10:07
Сообщение #3


Участник
*

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



Цитата(sensor_ua @ Sep 23 2007, 12:11) *
Похоже, чтение регистра статуса неправильное. Покажи. Вероятно отправляешь не 0xD7+1 байт, а только 0xD7 и сразу читаешь содержимое регистра SPI;)

Кажится и в правду. Сложно без BUSY. Сам код:

#define BUFFER_1_WRITE 0x84 // запись буфера 1
#define BUFFER_2_WRITE 0x87 // запись буфера 2
#define BUFFER_1_READ 0xD4 // чтение буфера 1
#define BUFFER_2_READ 0xD6 // чтение буфера 2
#define STATUS_REGISTER 0xD7 // регистр состояния
#define BLOCK_ERASE 0x50 // очистка 512 страниц

void flash_write(unsigned char flash_data)
{
static unsigned int buffer_counter;
// Хранит позицию в буфере для записи следующего байта

static unsigned int page_counter; // Номер страницы в памяти

unsigned char temp = 0x80; //Проверка 7 бита в регистре статуса

// interrupt выключениеd, SPI port включениеd, master mode, MSB first, SPI mode 3, Fcl/4
SPCR = 0x5C; // включили SPI


// Если установлен флаг "new_data" - то обнулим счетчики
if(new_data) // страниц и буферов
{
buffer_counter = 0; // писАть в начало буфера
page_counter = 0; // писАть в нулевую страницу
new_data = 0; // сбросить "new_data" флаг
}

//Вот здесь вопрос - из даташита как я понял надо писать до chip_select
SPDR = STATUS_REGISTER; //Вот тут как раз тема с не важным байтом
while (!(SPSR & temp)); // ждем пока память освободится
//Вот тут как раз тема с не важным байтом
PORTB &= ~DF_CHIP_SELECT; // включение DataFlash

SPDR = BUFFER_1_WRITE;
while (!(SPSR & temp)); // ожидание завершения передачи
SPDR = 0x00; // не важно
while (!(SPSR & temp)); // ожидание завершения передачи
SPDR = (char)(buffer_counter>>8); // не важно
while (!(SPSR & temp)); // ожидание завершения передачи
SPDR = (char)buffer_counter; // buffer address
while (!(SPSR & temp)); // ожидание завершения передачи
SPDR = (char)flash_data; //write data into SPI Data Register
while (!(SPSR & temp)); // ожидание завершения передачи

PORTB |= DF_CHIP_SELECT; // выключение DataFlash

last_byte_position_buffer = buffer_counter;
// сохранили в какую ячейку буфера был записан последн. байт
buffer_counter++;
// Хранит позицию в буфере для записи байта
}


void flash_read(){

unsigned int page_counter = 0;
unsigned int buffer_counter = 0;
unsigned char temp = 0x80;

SPCR = 0x5C; //Включили SPI
PORTB &= ~DF_CHIP_SELECT; // включаем DataFlash

/* Закоментировано, покуда записываю только 176 байт, даже страницу буфера не заполняю, поэтому решил просто записать-прочитать из буфера. Было предположение что функция стирания выставляет 0xFF, а я этой командой пишу это все в буфер из страницы памяти и получаю все байты 0xFF, закоментиорвал но результата не дало. Вот.

SPDR = MM_PAGE_TO_B1_XFER; // передаём страницу в буфер 1
while (!(SPSR & temp)); // ожидаем завершения передачи
SPDR = (char)(page_counter >> 6);
while (!(SPSR & temp)); // ожидаем завершения передачи
SPDR = (char)(page_counter << 2);
while (!(SPSR & temp)); // ожидаем завершения передачи
SPDR = 0x00; //не имеющий значения байт
while (!(SPSR & temp)); // ожидаем завершения передачи
*/
//Начинается отсюда

SPDR = BUFFER_1_READ; // читаем из буфера 1
while (!(SPSR & temp)); // ожидаем завершения передачи
SPDR = 0x00; // не имеющего значения байт
while (!(SPSR & temp)); // ожидаем завершения передачи
SPDR = 0x00; // запись не имеющего значения байта
while (!(SPSR & temp)); // ожидаем завершения передачи
SPDR = 0x00; // начать с адреса 0 буфера
while (!(SPSR & temp)); // ожидаем завершения передачи
SPDR = 0x00; // запись не имеющего значения байта
while (!(SPSR & temp)); // ожидаем завершения передачи
for (buffer_counter =0; buffer_counter < 176; buffer_counter++)
{
SPDR = 0xFF;
// записываем фиктивное значение в начало сдвигового регистра

while (!(SPSR & temp)); // ожидаем завершения передачи

bt_word[buffer_counter] = (int)SPDR;
// воспроизводим данные из сдвигового регистра
}
PORTB |= DF_CHIP_SELECT; // выключение DataFlash
}

Есть предположение что кривые темы с битами адреса, со всякими смещениями битов влево вправо. Надо будет проработать четко по даташиту. Вот вопрос адрес пишется с BF9 до BF0 или наоборот, тобишь единица должна накидываться начиная со старшего или младшего бита?

Сообщение отредактировал lomtev - Sep 23 2007, 10:08
Go to the top of the page
 
+Quote Post
sensor_ua
сообщение Sep 23 2007, 10:40
Сообщение #4


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

Группа: Свой
Сообщений: 1 266
Регистрация: 22-04-05
Из: Киев
Пользователь №: 4 387



Цитата
я понял надо писать до chip_select

Неправильно понял. Для ЛЮБОЙ КОМАНДЫ сначала активировать /CS, потом выдать opcode, потом, если надо (а со Status Register надо), выдать чем-попало (кроме случая записи) сколько нужно байт (при чтении статуса аж один, при чтении множества байт - многоwink.gif), потом деактивировать /CS


--------------------
aka Vit
Go to the top of the page
 
+Quote Post
lomtev
сообщение Sep 23 2007, 10:59
Сообщение #5


Участник
*

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



Цитата(sensor_ua @ Sep 23 2007, 14:40) *
Неправильно понял. Для ЛЮБОЙ КОМАНДЫ сначала активировать /CS, потом выдать opcode, потом, если надо (а со Status Register надо), выдать чем-попало (кроме случая записи) сколько нужно байт (при чтении статуса аж один, при чтении множества байт - многоwink.gif), потом деактивировать /CS

Тугодум я наверное, но вот эту строчку ен понял -
выдать чем-попало (кроме случая записи) сколько нужно байт (при чтении статуса аж один, при чтении множества байт - много) -
Это про эту строчку? - SPDR = 0x00;
while (!(SPSR & temp));

Как я понял в правильном варианте должно быть так

flash_write()
{
PORTB &= ~DF_CHIP_SELECT; // включение DataFlash

SPDR = STATUS_REGISTER;
while (!(SPSR & temp));
SPDR = 0x00; // не важно
while (!(SPSR & temp));
PORTB |= DF_CHIP_SELECT; // выключение DataFlash

PORTB &= ~DF_CHIP_SELECT; // включение DataFlash
SPDR = BUFFER_1_WRITE;
и т.д.
}

Я прав?


Переправил код как показано выше. Работает, но результат тот же, выводит только 0xFF.
Все же вероятней косяк в адресации.
Go to the top of the page
 
+Quote Post
sensor_ua
сообщение Sep 23 2007, 11:07
Сообщение #6


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

Группа: Свой
Сообщений: 1 266
Регистрация: 22-04-05
Из: Киев
Пользователь №: 4 387



Цитата
SPDR = STATUS_REGISTER;
while (!(SPSR & temp));
SPDR = 0x00; // не важно
while (!(SPSR & temp));

вааще ожидание готовности делается не так, а примерно так
Код
do{
  PORTB &= ~DF_CHIP_SELECT; // включение DataFlash
  /* Start transmission */
  SPDR = STATUS_REGISTER;
  /* Wait for byte transmission complete */
  while(!(SPSR & (1<<SPIF)))
  SPDR = 0x00; // не важно
  /* Wait for byte transmission complete */
  while(!(SPSR & (1<<SPIF)))
  tmp =SPDR; //читаем, чего же там в регистре статуса
  PORTB |= DF_CHIP_SELECT; // выключение DataFlash
}while (!(tmp&(1<<nBUSY)));


--------------------
aka Vit
Go to the top of the page
 
+Quote Post
lomtev
сообщение Sep 23 2007, 18:24
Сообщение #7


Участник
*

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



Написал аналог предложенного выше цикла... вот что получилось:

temp = 0x80 //Сверяется старший бит

do{
PORTB &= ~DF_CHIP_SELECT; // включение DataFlash

SPDR = STATUS_REGISTER;
while (!(SPSR & temp));
SPDR = 0x00; // не важно
while (!(SPSR & temp));
tmp= SPDR;

PORTB |= DF_CHIP_SELECT; // выключение DataFlash
}while (!(tmp & temp));

Выводит все те же 0xFF, попытался записать только один первый байт, тобишь после отправки opcode
BUFFER_1_WRITE; идет три байта нулей, последний из которых отвечает за адрес байта, следовательно он будет первым, потом байт данных.
Хоть бы хер. 0xFF да и только.
Может есть у кого-нить рабочий исходник? Желательно на Си. причем под CodeVisionAVR, но и под WinAVR тож разбирусь. Буду очень благодарен
Go to the top of the page
 
+Quote Post
sensor_ua
сообщение Sep 23 2007, 18:40
Сообщение #8


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

Группа: Свой
Сообщений: 1 266
Регистрация: 22-04-05
Из: Киев
Пользователь №: 4 387



Ну а остальные команды обрамить CS?
Вот примерчик с AVRFreaks
Прикрепленные файлы
Прикрепленный файл  STK500_Dataflash_Routines.zip ( 27.05 килобайт ) Кол-во скачиваний: 137
 


--------------------
aka Vit
Go to the top of the page
 
+Quote Post
lomtev
сообщение Sep 23 2007, 18:51
Сообщение #9


Участник
*

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



Цитата(sensor_ua @ Sep 23 2007, 22:40) *
Ну а остальные команды обрамить CS?
Вот примерчик с AVRFreaks

ДА вроде все обралено если тема идет про DF_CHIP_SELECT. Пример сейчас изучу.
Go to the top of the page
 
+Quote Post
lomtev
сообщение Sep 23 2007, 20:02
Сообщение #10


Участник
*

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



Цитата(lomtev @ Sep 23 2007, 22:51) *
ДА вроде все обралено если тема идет про DF_CHIP_SELECT. Пример сейчас изучу.

Посмотрел я пример. Отличия которые я нашел.
Первое - В функции проверки статуса они перед началом включают и выключают CS, потом снова включают и пошел opcode. - Исправил у себя. Хрен. Так же 255.
Второе - они в сдвиговый регистр при чтение памяти записывают фиктивное значение 0x00, а у меня записывалось 0xFF. -Исправил у себя. Хрен. Так же 255.

Еще заметка. Они используют проверку статуса только когда пишут либо буфер в страницу, либо из страницы в буфер. При записи и чтении данных из буфера проверку занятости они не делают. Я думаю покуда работа со страницами занимает порядочно времени, а SRAM работает как реактивный. В своей проге я читал - писал только буфер. Хотя забавно, что при удалении проверки занятости перестает работать вообще.

Сообщение отредактировал lomtev - Sep 23 2007, 20:06
Go to the top of the page
 
+Quote Post
sensor_ua
сообщение Sep 23 2007, 20:05
Сообщение #11


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

Группа: Свой
Сообщений: 1 266
Регистрация: 22-04-05
Из: Киев
Пользователь №: 4 387



Чтение/запись буфера не требуют проверки статуса на BUSY. Только операции стирания/записи во FLASH.
Цитата
они перед началом включают и выключают CS, потом снова включают

Это такой стиль. Немного, ИМХО, некорректный. Но имеет "право на жисть". Главное, что непосредственно перед операцией CS из 1 переходит в 0, а после - наоборот.
Курите пример - он фунциклирующий


--------------------
aka Vit
Go to the top of the page
 
+Quote Post
lomtev
сообщение Sep 23 2007, 20:05
Сообщение #12


Участник
*

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



Я уже начал искать совершенно тупые варианты и назрел вопрос:

Я смотрел по даташиту на память и процессор распиновки и спаял так:

память - проц
SO - SO
SI - SI

Может надо было?:

память - проц
SO - SI
SI - SO


Инициализация SPI

DDRB = 0xB5; // SPI Port initialisation 1011 0101

// SCK SO SI CS RDY/BSY
// PB7 PB6 PB5 PB4 PB3 PB2 PB1 PB0
// Настройка выводов МК
// Out In Out Out In Out In Out
// 1 0 1 1 1 1 0 1

Сообщение отредактировал lomtev - Sep 23 2007, 20:07
Go to the top of the page
 
+Quote Post
OLEG_BOS
сообщение Sep 23 2007, 20:16
Сообщение #13


Местный
***

Группа: Свой
Сообщений: 386
Регистрация: 1-12-05
Пользователь №: 11 639



Цитата(lomtev @ Sep 23 2007, 23:05) *
Я уже начал искать совершенно тупые варианты и назрел вопрос:

Может надо было?:

память - проц
SO - SI
SI - SO


В контроллере сигналы SPI именуются как: MISO (Master Input Slave Output) и MOSI (Master Output Slave Input). У флеши соответсвенно : SO (Slave Output) и SI(Slave Input).

Поэтому нужно соединять :

MISO -> SO;
MOSI -> SI;
Go to the top of the page
 
+Quote Post
lomtev
сообщение Sep 23 2007, 20:25
Сообщение #14


Участник
*

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



Цитата(OLEG_BOS @ Sep 24 2007, 00:16) *
В контроллере сигналы SPI именуются как: MISO (Master Input Slave Output) и MOSI (Master Output Slave Input). У флеши соответсвенно : SO (Slave Output) и SI(Slave Input).

Поэтому нужно соединять :

MISO -> SO;
MOSI -> SI;

Ясно, значит отпадает, все верно. Спасибо за ответ...
Go to the top of the page
 
+Quote Post
OLEG_BOS
сообщение Sep 23 2007, 20:28
Сообщение #15


Местный
***

Группа: Свой
Сообщений: 386
Регистрация: 1-12-05
Пользователь №: 11 639



Цитата(lomtev @ Sep 23 2007, 23:25) *
Ясно, значит отпадает, все верно. Спасибо за ответ...


..Ну я надеюсь о согласованием уровней все ОК ? wink.gif
Go to the top of the page
 
+Quote Post

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

 


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


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