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

 
 
> Atmega 2561 + флеш AT45DB041A - как связать по SPI?, Не работает
Slavast
сообщение Nov 30 2010, 09:59
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 81
Регистрация: 25-10-10
Пользователь №: 60 395



Не получается связать Atmega 2561 + флеш AT45DB041A. На данном этапе хочу хотя бы прочитать состояние статус регистра Памяти.
Но не работает.(((
Информацию состояния Статус-регистра вывожу на терминал компьютера через UART. UART работает 100 %.
Подскажите плиз - что не так?
Спасибо откликнувшимся.
Прикрепленные файлы
Прикрепленный файл  spi.RAR ( 235.11 килобайт ) Кол-во скачиваний: 20
 
Go to the top of the page
 
+Quote Post
2 страниц V   1 2 >  
Start new topic
Ответов (1 - 18)
xelax
сообщение Nov 30 2010, 10:23
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 370
Регистрация: 7-11-06
Пользователь №: 22 035



Цитата(Slavast @ Nov 30 2010, 12:59) *
Не получается связать Atmega 2561 + флеш AT45DB041A. На данном этапе хочу хотя бы прочитать состояние статус регистра Памяти.
Но не работает.(((
Информацию состояния Статус-регистра вывожу на терминал компьютера через UART. UART работает 100 %.
Подскажите плиз - что не так?
Спасибо откликнувшимся.


Что-то не понятно. Во первых почему у вас SS как вход сконфигурирован. Надо его сделать выходом и в добавок ко всему управлять им во время совершения транзакций на SPI шине. А во вторых SPI интерфейс, передавая байт через MOSI, одновременно по тем же тактам принимает байт из MISO. А у вас приём и передача разнесена по времени.
Go to the top of the page
 
+Quote Post
Slavast
сообщение Nov 30 2010, 10:36
Сообщение #3


Частый гость
**

Группа: Участник
Сообщений: 81
Регистрация: 25-10-10
Пользователь №: 60 395



Цитата(xelax @ Nov 30 2010, 13:23) *
Что-то не понятно. Во первых почему у вас SS как вход сконфигурирован. Надо его сделать выходом и в добавок ко всему управлять им во время совершения транзакций на SPI шине. А во вторых SPI интерфейс, передавая байт через MOSI, одновременно по тем же тактам принимает байт из MISO. А у вас приём и передача разнесена по времени.


Как управлять SS во время транзакций? До посылки каждого байта ставить в 0, а после пересылки в 0?
как переходить в режим чтения после каждого переданного бита - захватывать состояние MISO в SPDR, включая при этом на время SS?
Для прочтения состояния регистра статуса в флеш памяти - даташит пишет что после полной отправки OPCODa D7 в течение последующих 8 тактов 8 бит регистра статуса будет полностью перенесено на MISO и только теперь якобы его можно прочитать. Поэтому я делаю последовательно.
Go to the top of the page
 
+Quote Post
Sergey_Aleksandr...
сообщение Nov 30 2010, 10:45
Сообщение #4


Частый гость
**

Группа: Свой
Сообщений: 168
Регистрация: 8-10-08
Из: РФ Смоленск
Пользователь №: 40 764



Slavast, читаем мануал на флешку вместе (4 старница)
Цитата
To read the status register, an
opcode of 57H or D7H must be loaded into the device.
After the last bit of the opcode is shifted in, the eight bits of
the status register, starting with the MSB (bit 7), will be
shifted out on the SO pin during the next eight clock cycles.

Дословно "Для чтения статусного регистра в устройство должен быть записан код 0x57 или 0xD7. После того, как последний бит "опкода" будет вдвинут в регистр, 8 бит статусного регистра (начиная со старшего 7-го бита) будут выдвигаться наружу на вывод SO (MISO) на протяжении следующих 8 тактов".
Т.е. Вам надо сперва передать опкод 0x57, потом передать 0x00 (при этом линия MOSI будет в 0, а по SCK пройдут 8 тактовых импульсов и микросхема памяти будет по MISO слать в МК значение статусного регистра). Только после этого из SPDR читаете принятый байт данных.
Приём и передачу неправильно так разносить ибо для SPI они по времени едины. Лучше чтобы ваша функция возвращала прочитанный в SPDR байт через регистр (пусть будет r16)
Код
;--------------- Передача по SPI --------------------

            SPI_MasterTransmit:
// НЕ ЗАБЫВАЕМ УСТАНАВЛИВАТЬ SlaveSelect (SS) в 0
CBI PORTB,0
                ldi r16,0xD7; Посылаем OPCODE для чтения Статус-регистра
                out SPDR,r16
        Wait_Transmit:        ; Wait for transmission complete
                lds r18, SPSR
                sbrs r18,SPIF
                rjmp Wait_Transmit

// Передаёи байт 0x00 для чтения результата из DataFlash в МК
                ldi r16,0
                out SPDR,r16
                            Wait_Transmit1:
                lds r18, SPSR
                sbrs r18,SPIF
                rjmp Wait_Transmit1

// Деактивируем SlaveSelect (SS) после каждой транзакции с DataFlash
SBI PORTB,0

in r16,SPDR   //ПРИ ВЫХОДЕ ИЗ ФУНКЦИИ в r16 будет лежать прочитанный байт (там с ним творите что хотите, хоть в UART его передать, хоть сохранить куда-нить)
             ret


Сообщение отредактировал Sergey_Aleksandrovi4 - Nov 30 2010, 10:53
Go to the top of the page
 
+Quote Post
Slavast
сообщение Nov 30 2010, 11:11
Сообщение #5


Частый гость
**

Группа: Участник
Сообщений: 81
Регистрация: 25-10-10
Пользователь №: 60 395



Цитата(Sergey_Aleksandrovi4 @ Nov 30 2010, 13:45) *
Slavast, читаем мануал на флешку вместе (4 старница)



Ааа! Вот оно что! Теперь понял.
Но а что же делать с SS в теч всео этого времени - начиная от "SPI_MasterTransmit:" и до "rjmp Wait_Transmit1". все время держать его в 0? А после этого поставить его в 1?
И главный вопрос - чем переключить ATMega2561 в режим чтения? Или его не нужно переключать? наша информация и так автоматически попадет в SPDR?

Цитата(Slavast @ Nov 30 2010, 14:00) *
Но а что же делать с SS в теч всео этого времени - начиная от "SPI_MasterTransmit:" и до "rjmp Wait_Transmit1". все время держать его в 0? А после этого поставить его в 1?


Простите, по попводу SS не увидел в конце ваших советов. теперь ясно.
Что же касается переключения в режим чтения - это все еще вопрос.

Сообщение отредактировал IgorKossak - Dec 1 2010, 18:00
Причина редактирования: Бездумное цитирование
Go to the top of the page
 
+Quote Post
mempfis_
сообщение Nov 30 2010, 11:34
Сообщение #6


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

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



Цитата(Slavast @ Nov 30 2010, 15:11) *
Что же касается переключения в режим чтения - это все еще вопрос.

Чтение/запись для SPI это одно и то же.
Вы ложите в SPDR байт и он отправляется. Одновременно с этим в SPDR вдвигается байт ответа.
Т.о. процедура чтения регистра статуса сводится к следующему:
1. SS в 0
2. В SPDR опкод - чтение регистра статуса, дождаться отправки.
3. В SPDR любое число, после отправки считать SPDR - получим регист статуса
Если операция выполнена (смотреть на биты в регистре статуса) SS в 1 и выход
Иначе возврат на П3.

Сообщение отредактировал mempfis_ - Nov 30 2010, 11:34
Go to the top of the page
 
+Quote Post
Slavast
сообщение Nov 30 2010, 11:59
Сообщение #7


Частый гость
**

Группа: Участник
Сообщений: 81
Регистрация: 25-10-10
Пользователь №: 60 395



Цитата(mempfis_ @ Nov 30 2010, 14:34) *
Чтение/запись для SPI это одно и то же.
Вы ложите в SPDR байт и он отправляется. Одновременно с этим в SPDR вдвигается байт ответа.
Т.о. процедура чтения регистра статуса сводится к следующему:
1. SS в 0
2. В SPDR опкод - чтение регистра статуса, дождаться отправки.
3. В SPDR любое число, после отправки считать SPDR - получим регист статуса
Если операция выполнена (смотреть на биты в регистре статуса) SS в 1 и выход
Иначе возврат на П3.


Теперь ясно. Ни в какой режим чтения заходить не надо. Вcе со следующим циклом задвинется в SPDR.
НО до сих пор не работает..(((
Может нужно в DORD определить какой бит будет слаться первым - старший или младший?
Go to the top of the page
 
+Quote Post
mempfis_
сообщение Nov 30 2010, 13:11
Сообщение #8


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

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



Цитата(Slavast @ Nov 30 2010, 15:59) *
Теперь ясно. Ни в какой режим чтения заходить не надо. Вcе со следующим циклом задвинется в SPDR.
НО до сих пор не работает..(((
Может нужно в DORD определить какой бит будет слаться первым - старший или младший?


Пример инициализации SPI на C из документации на atmega128 (взято из рабочего проекта).
Там же есть и примеры на ассемблере.
Также пример ожидания готовности памяти по регистру статуса.

Код
void SPIMasterInit(void)
{
/* Enable SPI, Master, set clock rate fck/4 */
SPCR = (1<<SPE)|(1<<MSTR);
}

void SPIWriteChar(unsigned char data)
{
  /* Start transmission */
  SPDR = data;
  /* Wait for transmission complete */
  while(!(SPSR & (1<<SPIF)));
}

unsigned char SPIReadChar(void)
{
  /* Start transmission */
  SPDR = 0x00;
  /* Wait for transmission complete */
  while(!(SPSR & (1<<SPIF)));
  return SPDR;

/***************************************************************/
//активация/деактивация микросхемы памяти перед операциями
inline void at45xx_init_op(void){SPI_PORT &= ~( (1<<nSS_AT45DBXX)|(1<<SCK)|(1<<MOSI) );}
inline void at45xx_end_op(void){ SPI_PORT |= (1<<nSS_AT45DBXX);}
/***************************************************************/

#define STATUS_REGISTER_READ  0xD7 /**< status register */

/***************************************************************/
//ожидание готовности памяти
unsigned char at45xx_wait(void)
{
  unsigned int i = 25000;
  unsigned char read_data;  
  
  at45xx_init_op(); //активация микросхемы памяти
  SPIWriteChar(STATUS_REGISTER_READ); //инициализация опкода

  while(i>0)
  {
    __watchdog_reset();
    delay_us(100);
    read_data = SPIReadChar(); //чтение регистра статуса
    if( (read_data & 0x80 ) != 0 ) break;
    i--;
  }
  
  at45xx_end_op(); //деактивация микросхемы памяти

  if (i != 0) return DF_NO_ERROR; //обработка ошибок
  else     return DF_WAIT_FAIL;
}
/***************************************************************/
}



SS настроен как выход? Какое его исходное состояние (должно быть 1)? Опкод правильно посылается?
И что подразумевается под "не работает" ?

Сообщение отредактировал mempfis_ - Nov 30 2010, 13:12
Go to the top of the page
 
+Quote Post
Slavast
сообщение Dec 1 2010, 08:13
Сообщение #9


Частый гость
**

Группа: Участник
Сообщений: 81
Регистрация: 25-10-10
Пользователь №: 60 395



Цитата(mempfis_ @ Nov 30 2010, 16:11) *
Пример инициализации SPI на C из документации на atmega128 (взято из рабочего проекта).
Там же есть и примеры на ассемблере.
Также пример ожидания готовности памяти по регистру статуса.

SS настроен как выход? Какое его исходное состояние (должно быть 1)? Опкод правильно посылается?
И что подразумевается под "не работает" ?


А есть такой же пример на Ассемблере?
Если можно - киньте плииз!
"Не работает" - на UART вижу только 00.

Может загвоздка в следующем. В даташите пишут:

SPI_MasterInit: ; Set MOSI and SCK output, all others input
ldi r17,(1<<DD_MOSI)|(1<<DD_SCK)
out DDR_SPI,r17 ; Enable SPI, Master, set clock rate fck/16
ldi r17,(1<<SPE)|(1<<MSTR)|(1<<SPR0)
out SPCR,r17
ret

Вот тут и непонятно: MOSI и SCK нужно задавать в 1 на DDRB или PORTB (т.е. указывать только направление или в заранее заданном на выход порт выдавать 1 или 0)? Это же ведь существенно! В Си коде за этим не могу уследить. Точно также и SS - нужно 1 посылать в DDRB или PORTB?

Т.е.

ldi r16,(1<<PB0)
ldi r17,(1<<DDB0)
out PORTB,r16
out DDRB,r17


или только

ldi r17,(1<<DDB0)
out DDRB,r17 ?
Go to the top of the page
 
+Quote Post
mempfis_
сообщение Dec 1 2010, 09:34
Сообщение #10


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

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



Прочитайте раздел SPI в документации. Там всё подробно описано. Примеры инициализации и работы на 100% рабочие.
Зациклите передачу по SPI (например постоянно опрашивайте регистр статуса) и потыкайте осциллографом на MOSI, MISO, SCK и SS.
Посмотрите что передаётся, что принимается.
По поводу настроек портов MOSI, SCK, SS настаиваете на выход (соотв. биты в DDR установлены в 1), исходные состояния пинов MOSI, SCK 0 (соотв. биты в PORT сброшены в 0), SS - 1. MISO настройте как вход без подтягивающего резистора (бит в DDR 0, бит в PORT тоже в 0).
Как вариант перед активацией микросхемы памяти приводите MOSI, SCK в исходное состояние (0,0) и только потом тяните SS в 0.
Я так делаю постоянно - SPI работает как положено.

Также почитайте и посмотрите приложенные файлы.
Go to the top of the page
 
+Quote Post
Палыч
сообщение Dec 1 2010, 09:48
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(Slavast @ Dec 1 2010, 11:13) *
Вот тут и непонятно: MOSI и SCK нужно задавать в 1 на DDRB или PORTB (т.е. указывать только направление или в заранее заданном на выход порт выдавать 1 или 0)? Это же ведь существенно!
Для MOSI и SCK в инициализации указывают только направление - всё остальное лежит на аппаратуре.

Цитата(Slavast @ Dec 1 2010, 11:13) *
Точно также и SS - нужно 1 посылать в DDRB или PORTB?
Для мастера SS не используется при работе SPI. Разработчик может эту ногу МК использовать по своему усмотрению. Например, может соединить SS мастера и SS слэйва. В этом случае в инициализации мастера указывают направление и начальный уровень (по даташиту слэйва). Можно SS слэйва подключить к другой ноге МК мастера (если слэйвов несколько, то - так и будет).
Go to the top of the page
 
+Quote Post
Slavast
сообщение Dec 1 2010, 14:07
Сообщение #12


Частый гость
**

Группа: Участник
Сообщений: 81
Регистрация: 25-10-10
Пользователь №: 60 395



А для команд вывода на SPDR и SPSR нужно использовать команду OUT или STS?
Go to the top of the page
 
+Quote Post
Палыч
сообщение Dec 1 2010, 15:35
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(Slavast @ Dec 1 2010, 17:07) *
А для команд вывода на SPDR и SPSR нужно использовать команду OUT или STS?
Эти регистры лежат в области I/O Registers, к которой можно обращаться командой OUT. При необходимости можно обращаться к этим регистрам и командой STS (адрес при этом на 20h больше, чем при обращении командой OUT).
Go to the top of the page
 
+Quote Post
mempfis_
сообщение Dec 1 2010, 15:38
Сообщение #14


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

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



Цитата(Slavast @ Dec 1 2010, 17:07) *
А для команд вывода на SPDR и SPSR нужно использовать команду OUT или STS?


Такое чувство что Вы даже не заглядываете в документацию на Ваш контроллер.
Под рукой нету доков на atmega2561 поэтому сами откройте раздел относящийся к SPI и посмотрите на примеры.
Если всё ещё будет не понятно какие команды использовать то найдите таблицу адресов всех регистров (Register Summary) atmega2561 найдите в ней SPDR, SPSR. Посмотрите сколько адресов соответствуют этим регистрам. Если 1 то они расположены в пространстве оперативной памяти (доступ LDS/STS), если 2 - в пространстве ввода-вывода (доступ IN/OUT)
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Dec 1 2010, 15:53
Сообщение #15


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

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



Цитата(mempfis_ @ Dec 1 2010, 18:38) *
Такое чувство что Вы даже не заглядываете в документацию на Ваш контроллер.
Под рукой нету доков на atmega2561 поэтому сами откройте раздел относящийся к SPI и посмотрите на примеры.

Этот совет был дан ему давным давно , но с того времени ничего не изменилось


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post
Slavast
сообщение Dec 2 2010, 08:54
Сообщение #16


Частый гость
**

Группа: Участник
Сообщений: 81
Регистрация: 25-10-10
Пользователь №: 60 395



Цитата(mempfis_ @ Dec 1 2010, 19:38) *
SPDR, SPSR. Посмотрите сколько адресов соответствуют этим регистрам. Если 1 то они расположены в пространстве оперативной памяти (доступ LDS/STS), если 2 - в пространстве ввода-вывода (доступ IN/OUT)


Спасибо. Теперь знаю как проверять. В Registers summary SPDR, SPSR действительно занимают по 1 байту - значит lds/sts.
Go to the top of the page
 
+Quote Post
Палыч
сообщение Dec 2 2010, 10:25
Сообщение #17


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(Slavast @ Dec 2 2010, 11:54) *
В Registers summary SPDR, SPSR действительно занимают по 1 байту - значит lds/sts.
Что-то я не пойму... Речь, вроде, идет о mega2561? Тогда: регистр SPDR имеет адрес 2E при обращении к нему командами in/out и адрес 4Е при обращении командами lds/sts; соответственно для регистра SPSR - эти адреса 2D и 4D.
Go to the top of the page
 
+Quote Post
Slavast
сообщение Dec 3 2010, 12:30
Сообщение #18


Частый гость
**

Группа: Участник
Сообщений: 81
Регистрация: 25-10-10
Пользователь №: 60 395



Цитата(Палыч @ Dec 2 2010, 14:25) *
Что-то я не пойму... Речь, вроде, идет о mega2561? Тогда: регистр SPDR имеет адрес 2E при обращении к нему командами in/out и адрес 4Е при обращении командами lds/sts; соответственно для регистра SPSR - эти адреса 2D и 4D.


Все таки поменял на InOut - по крайней мере с 2D и 2E точно должно читать.



Спасибо Sergey_Aleksandrovi4, Mempfis, Палыч!
В конечном итоге получилось только передать по SPI: осциллографом щупаю MOSI - вижу передаваемые данные, SS - вижу низкие уровни в момент передачи,на SCLK - тактирование. Но на MISO ничего нет.!.(((((((((
Вроде делаю все по аналогии.
И на UART выдаются 00.......((((((((
HELP!

Код прикрепляю.
Прикрепленные файлы
Прикрепленный файл  SPI_Posled.rar ( 59.24 килобайт ) Кол-во скачиваний: 14
 
Go to the top of the page
 
+Quote Post
Slavast
сообщение Dec 3 2010, 14:35
Сообщение #19


Частый гость
**

Группа: Участник
Сообщений: 81
Регистрация: 25-10-10
Пользователь №: 60 395



Может для вывода на терминал нужно использовать режим UART c SPI?
Go to the top of the page
 
+Quote Post

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

 


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


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