Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Кто работал с памятью at45db161d или в принципе с at45dbxxxd, пожалуйста подскажите
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Страницы: 1, 2
lomtev
Так вот, ситуация такая. Использовал примеры программ из аппноутов, переписал коды команд на те которые советуют в даташите. Перепроверил и в других источниках типа занятие 7 с сайт 123avr. Функции написаны правильно. Сначала стираю память, потом пишу в нее значения до 176, тобишь записываю 176 байт. Потом читаю память и сохраняю данные в массив, после вывожу массив на экран (в выводе символов ошибок нет точно), выводятся исключительно значения 255, в рядок так 255 255 255 и т.д. Впихивал вывод значений в разные места программы с выводом разных переменных - вроде все работает. да и в противном случае вывело первоначальное значение массива а это 0. Забавная еще вещь наблюдается, программа написана изначально была для 28 ногово чипа, а я использую 8 ногий так что приходится читать занятость из регистра стуса строчкой типа while (!(SPSR & temp));, я думал что ошибка в ожидании и добавил строчку SPDR = STATUS_REGISTER;, но потом удалил, покуда изменений не произошло.
Так теперь зараза не хочет работать без этой строчки, хотя раньше работала так же криво как и сейчас.
И еще при стирании биты выставляются как я понял в значение 255.
Кто-нибудь сталкивался или работал с данным чипом? В тупике. предположений нет вообще. Если кто хочет помочь и нуждается в наглядной демонстрации кода, то я выложу.
sensor_ua
Похоже, чтение регистра статуса неправильное. Покажи. Вероятно отправляешь не 0xD7+1 байт, а только 0xD7 и сразу читаешь содержимое регистра SPI;)
lomtev
Цитата(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 или наоборот, тобишь единица должна накидываться начиная со старшего или младшего бита?
sensor_ua
Цитата
я понял надо писать до chip_select

Неправильно понял. Для ЛЮБОЙ КОМАНДЫ сначала активировать /CS, потом выдать opcode, потом, если надо (а со Status Register надо), выдать чем-попало (кроме случая записи) сколько нужно байт (при чтении статуса аж один, при чтении множества байт - многоwink.gif), потом деактивировать /CS
lomtev
Цитата(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.
Все же вероятней косяк в адресации.
sensor_ua
Цитата
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)));
lomtev
Написал аналог предложенного выше цикла... вот что получилось:

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 тож разбирусь. Буду очень благодарен
sensor_ua
Ну а остальные команды обрамить CS?
Вот примерчик с AVRFreaks
lomtev
Цитата(sensor_ua @ Sep 23 2007, 22:40) *
Ну а остальные команды обрамить CS?
Вот примерчик с AVRFreaks

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

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

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

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

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

память - проц
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
OLEG_BOS
Цитата(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;
lomtev
Цитата(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;

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


..Ну я надеюсь о согласованием уровней все ОК ? wink.gif
sensor_ua
wink.gif))
MISO - Master Input Slave Output
MOSI - Master Output Slave Input
Посмотрите AN AVR252, AN AVR107 - может, чем поможет
ЗЫ. Ещё раз - не читайте всякой фигни (курс забаненного здесь кое-кого). Проблемы оттуда.
lomtev
Цитата(sensor_ua @ Sep 24 2007, 00:32) *
wink.gif))
MISO - Master Input Slave Output
MOSI - Master Output Slave Input
Посмотрите AN AVR252, AN AVR107 - может, чем поможет
ЗЫ. Ещё раз - не читайте всякой фигни (курс забаненного здесь кое-кого). Проблемы оттуда.

Да что о поблемах каких то все говорят?... Гы, его тут забанили... забавно... Кстати процессорам я именно по его сайту начинал учиться... Конечно сумбурно, но понять можно... CodeVisionAVR, VMLAB, Proteus, все узнал именно от туда... конечно как человека автора я не знаю да и хрен с ним...
А вот AN AVR252 и AN AVR107, я не понял что есть такое.

Цитата(OLEG_BOS @ Sep 24 2007, 00:28) *
..Ну я надеюсь о согласованием уровней все ОК ? wink.gif

А вот это правильный вопрос.... Память на 2,7 Вольта, а шпарю я на пяти 07.gif , но в рассказе забанненного кое-кого я прочитал что она может работать и на пяти.
sensor_ua
Цитата
я не понял что есть такое.

Вот-вот. Проблема в том, что сначала нужно изучать информацию от производителя, а уж потом религиозные толкованияwink.gif Припадите к истокам, плз. ->
http://www.atmel.com/dyn/products/app_note...p?family_id=607

ЗЫ. Некто забанен был за неприкрытую рекламу. Но, ИМХО, о содержании известного ресурса нужно было бы много нехороших слов сказать. Но ОНО их не понимает;(
lomtev
Цитата(sensor_ua @ Sep 24 2007, 01:02) *
Вот-вот. Проблема в том, что сначала нужно изучать информацию от производителя, а уж потом религиозные толкованияwink.gif Припадите к истокам, плз. ->
http://www.atmel.com/dyn/products/app_note...p?family_id=607

AN значи аппноут... Сейчас посмотрю и спать, вставать в шесть утра
sensor_ua
Цитата
она может работать и на пяти

Для этого нужно не забыть, что уровни КМОП (у проца) есть для лог. 1 - 0.7 и выше (т.е. выше 3.5В), а 0 - 0.3 и ниже от напряжения питания. Т.е. линию приёма от FLASH нужно тем или иным способом согласовать. Хотя вид непонятности говорит о близости сигнала к 1-е, а не к 0, т.е. проблемы разные (хотя могут сосуществовать совместно)
Snaky
Цитата(lomtev @ Sep 23 2007, 14:48) *
Кто-нибудь сталкивался или работал с данным чипом? В тупике. предположений нет вообще. Если кто хочет помочь и нуждается в наглядной демонстрации кода, то я выложу.

Есть готовая рабочая билиотека для этой памяти на http://kurt.embedders.org/
sensor_ua
Цитата
Есть готовая рабочая билиотека

А была надеждаwink.gif, что lomtev хотя бы из любопытства обнаружит на страничке аппликух AN AVR335:)))
GDI
Раньше выпускались АТ45 с какой то буквой(вроде cool.gif, которая могла работать от 5в, сейчас их выпуск ПРЕКРАЩЕН, смотрите внимательно даташиты - они отличались последней буквой в названии. Я сейчас работаю именно с АТ45DB161D питание и меги и флешки 3.3в - никаких проблем, за исключением того что пришлось поменять опкоды некоторые, в частности и опкод чтения регистра статуса. Библиотеку не помню где брал, может и с avrfreaks
Код
#define FlashPageRead           0xd2    // Main memory page read
#define FlashToBuf1Transfer        0x53    // Main memory page to buffer 1 transfer
#define Buf1Read           0xd4    // Buffer 1 read
#define FlashToBuf2Transfer        0x55    // Main memory page to buffer 2 transfer
#define Buf2Read           0xd6    // Buffer 2 read
#define StatusReg           0xd7    // Status register
#define AutoPageReWrBuf1       0x58    // Auto page rewrite through buffer 1
#define AutoPageReWrBuf2       0x59    // Auto page rewrite through buffer 2
#define FlashToBuf1Compare           0x60    // Main memory page to buffer 1 compare
#define FlashToBuf2Compare       0x61    // Main memory page to buffer 2 compare
#define ContArrayRead           0x68    // Continuous Array Read (Note : Only A/B-parts supported)
#define FlashProgBuf1           0x82    // Main memory page program through buffer 1
#define Buf1ToFlashWE          0x83    // Buffer 1 to main memory page program with built-in erase
#define Buf1Write           0x84    // Buffer 1 write
#define FlashProgBuf2           0x85    // Main memory page program through buffer 2
#define Buf2ToFlashWE          0x86    // Buffer 2 to main memory page program with built-in erase
#define Buf2Write           0x87    // Buffer 2 write
#define Buf1ToFlash            0x88    // Buffer 1 to main memory page program without built-in erase
#define Buf2ToFlash           0x89    // Buffer 2 to main memory page program without built-in erase
вот коды которые у меня работают
lomtev
Цитата(sensor_ua @ Sep 24 2007, 08:12) *
А была надеждаwink.gif, что lomtev хотя бы из любопытства обнаружит на страничке аппликух AN AVR335:)))

Возможно удивитесь, не такой я лузер конченный и этот аппноут у меня уже пару месяцев валяется, все фунции списаны с него и изучил его я с первой до последней строчки. А еще замечу, что там используется 28 ножный флеш и проверка занятости идет через BUSY, а в 8 ногом ее нет и приходится факаться с этим регистром. Если бы все было так просто.

Цитата(GDI @ Sep 24 2007, 16:01) *
Раньше выпускались АТ45 с какой то буквой(вроде cool.gif, которая могла работать от 5в, сейчас их выпуск ПРЕКРАЩЕН, смотрите внимательно даташиты - они отличались последней буквой в названии. Я сейчас работаю именно с АТ45DB161D питание и меги и флешки 3.3в - никаких проблем, за исключением того что пришлось поменять опкоды некоторые, в частности и опкод чтения регистра статуса. Библиотеку не помню где брал, может и с avrfreaks
Код
#define FlashPageRead           0xd2    // Main memory page read
#define FlashToBuf1Transfer        0x53    // Main memory page to buffer 1 transfer
#define Buf1Read           0xd4    // Buffer 1 read
#define FlashToBuf2Transfer        0x55    // Main memory page to buffer 2 transfer
#define Buf2Read           0xd6    // Buffer 2 read
#define StatusReg           0xd7    // Status register
#define AutoPageReWrBuf1       0x58    // Auto page rewrite through buffer 1
#define AutoPageReWrBuf2       0x59    // Auto page rewrite through buffer 2
#define FlashToBuf1Compare           0x60    // Main memory page to buffer 1 compare
#define FlashToBuf2Compare       0x61    // Main memory page to buffer 2 compare
#define ContArrayRead           0x68    // Continuous Array Read (Note : Only A/B-parts supported)
#define FlashProgBuf1           0x82    // Main memory page program through buffer 1
#define Buf1ToFlashWE          0x83    // Buffer 1 to main memory page program with built-in erase
#define Buf1Write           0x84    // Buffer 1 write
#define FlashProgBuf2           0x85    // Main memory page program through buffer 2
#define Buf2ToFlashWE          0x86    // Buffer 2 to main memory page program with built-in erase
#define Buf2Write           0x87    // Buffer 2 write
#define Buf1ToFlash            0x88    // Buffer 1 to main memory page program without built-in erase
#define Buf2ToFlash           0x89    // Buffer 2 to main memory page program without built-in erase
вот коды которые у меня работают

А не могли бы вы скинуть сами функции записи-чтения. Коды у меня прописаны те же самые.
sensor_ua
Цитата
Возможно удивитесь

Не принимайте так близко к сердцу. При несколько неудачных Ваших результатах после "пошагового хождения" возникают сомнения в правильности подбора общего подхода. Изучение документации, в том числе особенностей применения чипа от производителя, без некоторого любопытства может занимать несколько меньше времени, но иногда всё же лучше оглядеть всё доступное. Так как для Вас хранилище аппнотов от производителя было некоторой новостью (может мне показалось), я позволил себе намекнуть, что Вы таки бываете любопытным. Оскорбить не думал, но поддеть - даwink.gif
Лучше скажите, что поправили и как что работает.
Кстати, может какой ляпсус в настройках пинов? может DDRn на выход для CS не установили?
zltigo
Цитата(lomtev @ Sep 24 2007, 17:00) *
в 8 ногом ее нет и приходится факаться с этим регистром.

Для начала просто задержки вставьте вместо ожидания готовности, а то тяжело искать ошибки тем, где их нет.
lomtev
Цитата(sensor_ua @ Sep 24 2007, 18:30) *
Не принимайте так близко к сердцу. При несколько неудачных Ваших результатах после "пошагового хождения" возникают сомнения в правильности подбора общего подхода. Изучение документации, в том числе особенностей применения чипа от производителя, без некоторого любопытства может занимать несколько меньше времени, но иногда всё же лучше оглядеть всё доступное. Так как для Вас хранилище аппнотов от производителя было некоторой новостью (может мне показалось), я позволил себе намекнуть, что Вы таки бываете любопытным. Оскорбить не думал, но поддеть - даwink.gif
Лучше скажите, что поправили и как что работает.
Кстати, может какой ляпсус в настройках пинов? может DDRn на выход для CS не установили?

Проработал строку SPCR = 0x5C; //Включили SPI
Вроде все нормально как написано в сноске ниже

/ interrupt выключен,SPI port включен, master mode, MSB first, SPI mode 3, Fcl/4
Порт инициализируется тоже верно:

void setup(void) // настройка переферии МК
{
DDRB = 0xBD; // 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

PORTB = 0xFF; // all outputs high, inputs have pullups
#asm("sei") // разрешить прерывания

}

Распаяно у меня тоже верно. Единственная строчка которая у меня вызвала непонятие это из аппноута 335, а именно:

do
{
write_SPI(0xFF); // write dummy value to start register shift
while(!(ACSR&T1_OVF)); // wait for timer1 overflow interrupt
OCR1B = SPDR; // play data from shift register
ACSR &= (~T1_OVF); // clear the signal flag
} while (--buffer_counter);

Читают буфер и пишут его в регистр, но куда пишут не важно, можно и в массив. Идет ожидание прерывания после записи фиктивного значения. Сама фукция по вектору:

#pragma vector = TIMER1_OVF_vect
__interrupt void out_now(void)
{
ACSR |= T1_OVF; // an interrupt has occured
}

Это прерывание связано непосредственно с передачей в ШИМ или нужно ждать чего-то после отправки фиктивного значения или это взаимозаменияемо с while (!(SPSR & temp)); ????


И кстати если можно, то пожалуйста на ТЫ... wink.gif
lomtev
В прикрепленном файле функции. Файл не большой поскольку пишу-читаю только буфер.
Основной код очень прост.

int main(void)
{

setup(); //Установка SPI

erasing(); // Стереть пмять

for(k=0;k<176;k++){ //цикл записи в память
if(k<124)flash_write(k);
else flash_write(246-k);
}

flash_read();

while (1){}
return(0);
}
sensor_ua
1) Прерывания пока разрешать не нужно (в setup()), а иногда и вредно - а вдруг где-то в дебрях спрятанного текстаwink.gif обработчик прерывания SPI от Папы Карло затерялся?
2) Сначала нужно всё-таки записать-прочитать буфер, чтобы убедиться в правильной настройке интерфейса, пинов и вааще - похоже, к этому уже пришли. Для работы с буфером ничего стирать не нужно (там ОЗУ), т.е. erasing(); нафиг. Это для отладки.
3) В функции записи нет строки unsigned char temp = 0x80; оно типа глобально, но в чтениичто-то есть -намешано. Вообще использовать переменные там, где можно использовать литералы (константные объявления через #define) - это моветон. Переменные жрут озу (стек), их нужно правильно объявлять, не забывать инициализировать, не позволять опитмизатору их выбрасывать... Кроме того, цифирьки разбирать типа SPCR = 0x5C; не очень хорошо - это приводит к нежеланию читать код у меня (ИМХО, и у большинства тоже), но это бы полбеды - беда в том, что такое написание приводит к механическим ошибкам и не позволяет поддерживать код уже через очень короткое время после написания. Компилятор всё-равно всё в цифирьки перепакует, но нафига человеку его работу пытаться сделать, да ещё и неуклюже? Помотрите хотя бына примеры инициализации из DS - там достаточно читабельно. Короче, замените, где надо эту temp на (1<<SPIF), а где на (1<<BUSY). Равно и остальное, а то обсуждение усложняетсяwink.gif
5) Приведение типа к знаковому (char)SPDR в функции чтения - нафиг. Объявление bt_word[] не нашёл.
4)Для отладки уберите всякие static buffer_counter и запишите хотя бы один раз в буфер с нулевого адреса несколько байт данных, ну и прочитайте оттуда же. Цикл, вызывающий запись в буфер одного байта, уберите из main и положите в функцию записи, а лучше пока вааще убить и попробовать тупо записать, например, 4 константы.
5) Убрав вызов erasing() из main перестанет выключаться SPI 8-D
SPCR = 0x00; // Выключить SPI
и есть вероятность, что то, что написано далее, будет фунциклироватьwink.gif
6) Функцию стирания надо будет рихтовать - там некорректные кусочки ожидания готовности (обсуждали ранее)- ожидание либо вынести в отдельную функцию, либо по месту поправить. Я, например, не использую принципиально функции записи со стиранием, потому, если драйвер для себя, то могу запихнуть ожидание внутрь, но если иначе, то смысла прятать нет. Кроме того, в ожидании (а это порядком 40+ мс!!!) часто можно заниматься чем-то более важнымwink.gif иногда узнавая, как же ж там дела...
GDI
Вот библиотека с которой я работаю, инициализация порта сделана для мега128, компилятор IARAVR, инклюд файла Config.h можно убрать.
lomtev
1. В setup написал #asm("cli") // запретить прерывания
2. eracing() нафиг
3. temp заменил через #define 0x80
4. Приведение типа убрал.
Объявление мссива забыл написать, покуда это только половина программы была, причем вторая и внизу. Первую занимает дисплей. Управление им осуществлятся через программный spi, никакие регистры там не затрагиваются. Сам массив:
char bt_word[176]={0};
5. Попытался записать только одну константу...

И не хочу показаться занудой или неудачником, но 255 на экрачике в рядок.

Парни... кажится до меня доперло... У меня на памяти на ноже WP +5 Вольт... Случаем это не защита от записи? 05.gif
Ответ на вопрос выше, отпаял я этот вывод - не помогло... Ну что за хрень
rezident
Цитата(lomtev @ Sep 25 2007, 23:49) *
Парни... кажится до меня доперло... У меня на памяти на ноже WP +5 Вольт... Случаем это не защита от записи? 05.gif
Ответ на вопрос выше, отпаял я этот вывод - не помогло... Ну что за хрень

Да, WP это вход защиты от записи, но только активный уровень у этого сигнала низкий.
Не настаиваю, а просто предлагаю посмотреть мою библиотеку для работы с AT45, написанную когда-то для MSP430. Писал для одного проекта, который заглох и эти исходники мне не пригодились. Исходники минимально тестировались. Дважды уже давал ее нуждающимся, но к сожалению никакой обратной реакции хотя бы на уровне "работает / не работает / глючит / фуфло полное" не получил sad.gif Может хотя бы вы попробуете и как-то выскажетесь?
lomtev
Предложенный исходник, написан явно не для Codevision а с другими компиляторами разбираться все равно что с нуля учиться. Так что врядли я скажу вам о правильности вашей прошивки...
Так вот еще забавно. Как я понял резет должен быть высоко а он у меня низко. Надо будет припаять их (WP тоже) к VCCи взглянуть что получиться.
rezident
Цитата(lomtev @ Sep 26 2007, 00:38) *
Предложенный исходник, написан явно не для Codevision а с другими компиляторами разбираться все равно что с нуля учиться. Так что врядли я скажу вам о правильности вашей прошивки...

Вообще-то библа написана под ANSI C и компилировать ее что в IAR, что в CodeVision, что в GCC без разницы. Если вас смутили мои типы данных, то они в хидере _xOS_LOC.h задаются. Единственно, что #pragma pack может какому-то компилятору не понравиться, но четыре строки подправить не большой труд. Эх, опять сорвалось тестирование! sad.gif Ну да ладно. Хозяин - барин.
lomtev
ТАк парни, кажись пошло г**вно по трубам, перепаял резет на VCC и стало выводить какой-то мусор... хрен знает что это, но всяко прогресс... 08.gif
sensor_ua
А какой проц? пока почему-то думал, что мега16.
lomtev
Всё парни.... всё заработало, по крайней мере первый байт пишится правильно. а там дело за адресацией и все. Что хочу подытожить.
Не работало правильно по двум причинам.
Первая - Не знаю почему на нужную ножку с резетом не выводилась единица, перепаял ее на VCC и по счастливой случайности у меня плата не была подключена к шнуру програматора и на экран вывелся мусор. Позже я подключил программатор и стал искать ошибку, но при запуске у меня снова вывелись 255, я допер что оказывается причина была совсем не там где мы ее искали.
Вторая - Не знаю почему но программатор (Обычный пяти проводковый через LPT) соединяет вместе SO или SI и SCK. таким образом когда процессор ждал в SPDR значения сдвигового регистра он получал клон сигнала с SCK и выдавал 0xFF. Стебно. Правда я мозг. smile3046.gif
Всем вам a14.gif И спасибо за помощь. Надеюсь эта темка поможет таким же лузерам как я. Упорство и проработка любых возможных ошибок, пусть даже самых нелепых - это залог успеха в достижении поставленной задачи. До связи.

Цитата(sensor_ua @ Sep 25 2007, 23:25) *
А какой проц? пока почему-то думал, что мега16.

мега32-16ua
uriy
Цитата
Вторая - Не знаю почему но программатор (Обычный пяти проводковый через LPT) соединяет вместе SO или SI и SCK. таким образом когда процессор ждал в SPDR значения сдвигового регистра он получал клон сигнала с SCK и выдавал 0xFF.

Держите микроконтроллер в ресете когда его шьете внешним программатором. Его ноги будут в третьем состоянии и не будут мешать программированию.
GDI
Программатор все же лучше сделать покруче, например поставить таки туда буфер НС244, хотя и с буферизированным программатором у меня были проблемы. проблемы такого плана, что в один "прекрасный" момент он чуть-чуть поддох таким образом что при подаче питания на схему и программатор, последний садил сигнал SO, так было до первого прошивания контроллера, далее все работало нормально. Правда это мешало только на этапе отладки когда прграмматор держится постоянно подключенным в схему smile.gif
lomtev
Фишка не в самом программаторе, а в компе, если программатор отключить от LPT то клона сигнала нет. Но буфер это хорошо не спорю, но причина выяснена так что можно ее избегать простым отключением разъема. Да еще и времени нет, и так от графика отстаю. Но всем, огромное спасибо за внимание. a14.gif
lomtev
Заметил странную штуку. Была проблема что у меня на дисплей выводилось следующее (всего пять символов)
0_ *01_*02_*03_*04

* - помечано символ который я не кодировал (никакой просто белеберда 8*12 pix), как там вылазил бред понять не могу поскольку на вывод чисел у меня стоит фильтр и ничего кроме записаных в кодировке символов высти нельзя в принципе... а однако можно...
_ - на дисплее это пробел... просто пустая ячейка цвета фона.

Так вот, бред такой выводился при следующим цикле записи

char k=0;

for(k=0;k<5;k++){
flash_write(k);
}

Я морщил репу, один байт в виде функции flash_write(77); в любую ячейку буфера пишится отлично, а цикл не хочет. Перепахал все битовые сдвиги адрессации бита в буфере. ноль эмоций. Решил сделать так

for(k=0; k<5; k++){
if(k==0) flash_write(77);
if(k==1) flash_write(69)
if(k==2) flash_write(18);
if(k==3) flash_write(13);
if(k==4) flash_write(54);
}

И странно но факт, он вывел все в виде

77_69_18_13_54

В общем, как надо. В чем причина? Почему в функцию правильно передается только константа, а не переменная?
sensor_ua
А unsigned char k не пробовал?
lomtev
Цитата(sensor_ua @ Sep 27 2007, 00:43) *
А unsigned char k не пробовал?

Попробовал. Не помогло. Согласен что скорее всего все дело в переменной k, но как она нарушила довольно жесткий цикл пересчета:

void math_screen(unsigned char eds,unsigned char new_znach)
{
unsigned char i=0;
unsigned char mas_eds[4]={10,10,10,10};

if(eds>=100) mas_eds[0]=0; //Если число больше или равно сотни, то там явно будет число и надо убрать пробел
if(eds>=10) mas_eds[1]=0; //Если число больше или равно десяти, то там явно будет число и надо убрать пробел
if(eds!=0) mas_eds[2]=0; //Если число больше не равно нулю, то там явно будет число и надо убрать пробел
if(eds==0) mas_eds[2]=0;

for(i=0; i<eds; i++) //Разбиение числа на единицы, десятки и сотни
{
mas_eds[2]++;
if(mas_eds[2]==10){mas_eds[2]=0; mas_eds[1]++;}
if(mas_eds[1]==10){mas_eds[1]=0; mas_eds[0]++;}
}

for(i=0; i<4; i++) put_char (new_znach+i*8,60, mas_eds[i]);
}

Вызывается мат_скрин циклом:

unsigned char g=0;

for(g=0; g<5; g++)
{
math_screen(bt_word[g], 10+g*32);
}

Сам массив bt_word:

unsigned char bt_word[176]={0};

Дальше идет, сравнение с кодировкой символов, причем только цифр и пробела - но это уже не важно. Башню ему сносит где-то на пересчете. Что он пишет в mas_eds[0] что выводит казилябры, число должно быть больше десяти, но как в char можно запихнуть значение больше тысячи, лишнее должно было бы срезаться. Надеюсь вам понятно, а то без пива явно не разобраться. beer.gif

Может все дело в скорости и надо согласовать все циклы и функции или цикл с мат_скрином убрать в отдельную функцию с ожиданием пересчета байта. Допустим она пересчитывает один, а цикл ему уже отправил другой и все накладывается... ну что-нить вроде этого smile.gif
lomtev
Я иногда дивлюсь своему аналитическому уму lol.gif Добавил в функцию пересчета строчку
if(mas_eds[0]>=11) mas_eds[0]=6;
Если значение отвечающее за сотни перевалит за значение превышающее число символом в таблице кодировок, то в него запишется значение равное 6. И мне вывелось на экран следующее.

__0_601_602_603_604 (Хочу заметить что нули здесь лишнии за исклчением первого)

_ - пробел
Будем думать почему пишится число больше тысячи и все это упихивается в переменную char. Не int, я не совсем дурак 07.gif
Вот такая муть
sensor_ua
eds == 0xFF для
Цитата
for(i=0; i<eds; i++) //Разбиение числа на единицы, десятки и сотни

плачевно, если не int i
Дальше не разбирал. Подход к делению через сложение ниасилилwink.gif
lomtev
Я бобер хитрый и вывел значение которое должно отображать количество сотен. Значение равно 11, такого символа в таблице нет и по этому выводит мусор. Надо определить почему вылазит эта единица, потому как верное значение должно быть 10 при числах меньших 100. Если число больше или равно сотни происходит обнуление 10 и в последствии при пересчете в нее записывается единица. В моем случаем в фукцию засылается сначало ноль, потом единица, два, три, четыре - нигде сотни нет, нет даже числа больше десяти. Надо понять откуда она берется эта сотня.

Я нашел ошибку. Смотрим внимательно на цикл Если число отправляется меньше десяти что происходит: eds=1, это как раз то что мы записали в память

Сам цикл

unsigned char mas_eds[4]={10,10,10,10};

if(eds>=100) mas_eds[0]=0; //Сотни
if(eds>=10) mas_eds[1]=0; //Десятки
if(eds!=0) mas_eds[2]=0; // Единицы
if(eds==0) mas_eds[2]=0;

for(i=0; i<eds; i++) // ноль меньше единицы выполним один раз
{
mas_eds[2]++; // записали в единицы значение один
if(mas_eds[2]==10){mas_eds[2]=0; mas_eds[1]++;} //Значение единиц равно единице, не десять... пропускаем
if(mas_eds[1]==10){mas_eds[1]=0; mas_eds[0]++;} //И вот эврика!!! - Значение десятков равно то десяти, мы же десятки не обнулили и мы получем... десятки ноль, сотни равны одиннадцати. На выходе имеем
*01_*02
* - мусор, это одиннадцать сотен
0 - это обнуленные десятки
_ - это пробел, его не видно

Я дурак и гений в одном флаконе. =) Константы я ведь писал все не меньше десяти =)
}


Сделал изменения:

if(mas_eds[1]==10){mas_eds[1]=0; mas_eds[0]++;}
заменил на:
if(mas_eds[1]==10 && eds>=10){mas_eds[1]=0; mas_eds[0]++;}
И все зарабатало великолепно
НУ что друзья. До следующего гемороя. Всем респект. Еще спишемся
Ivaxa
Решил и про свою проблему написать. При замене AT45DB161B на - 161D возникла проблема:
стала искажаться информация на линии SO (161D; Vcc=3.3V) - MISO (Mega128; Vcc=5V). Решилась впаиванием резистора
на 180 Ом в эту линию.
uriy
А какую частоту CLK используете? У меня при частотах более 10 МГц тоже проблемы. Длина дорожек не превышает 3 сантиметров. 161D + ADSP-BF533
Roger
Помогите решить проблемы, курсач нужно было сдать "вчера".

проблема прочитать статус регистр(да и вообще что то прочитать) с at45db161d
В аттаче привожу схему и исходник(для отладки) по которой подключить ATmega8L<->SPI<->at45db
В данный момен такая схема собрана, единственно что для отладки подрубил по uart к компу, чтобы видеть что читается.
в Test.c написан цикл который отсылает по адресс регистра 0x57(пробывал и 0xD7)
В результате в терминали приходит строчка SR=00; и только.
GDI
Программатор пробовали от схемы отключать?
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.