|
Atmega 2561 + флеш AT45DB041A - как связать по SPI?, Не работает |
|
|
|
Nov 30 2010, 09:59
|
Частый гость
 
Группа: Участник
Сообщений: 81
Регистрация: 25-10-10
Пользователь №: 60 395

|
Не получается связать Atmega 2561 + флеш AT45DB041A. На данном этапе хочу хотя бы прочитать состояние статус регистра Памяти. Но не работает.((( Информацию состояния Статус-регистра вывожу на терминал компьютера через UART. UART работает 100 %. Подскажите плиз - что не так? Спасибо откликнувшимся.
Прикрепленные файлы
spi.RAR ( 235.11 килобайт )
Кол-во скачиваний: 20
|
|
|
|
2 страниц
1 2 >
|
 |
Ответов
(1 - 18)
|
Nov 30 2010, 10:36
|
Частый гость
 
Группа: Участник
Сообщений: 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 и только теперь якобы его можно прочитать. Поэтому я делаю последовательно.
|
|
|
|
|
Nov 30 2010, 10:45
|
Частый гость
 
Группа: Свой
Сообщений: 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
|
|
|
|
|
Nov 30 2010, 11:11
|
Частый гость
 
Группа: Участник
Сообщений: 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
Причина редактирования: Бездумное цитирование
|
|
|
|
|
Nov 30 2010, 11:34
|

Профессионал
    
Группа: Свой
Сообщений: 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
|
|
|
|
|
Nov 30 2010, 11:59
|
Частый гость
 
Группа: Участник
Сообщений: 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 определить какой бит будет слаться первым - старший или младший?
|
|
|
|
|
Nov 30 2010, 13:11
|

Профессионал
    
Группа: Свой
Сообщений: 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
|
|
|
|
|
Dec 1 2010, 08:13
|
Частый гость
 
Группа: Участник
Сообщений: 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 ?
|
|
|
|
|
Dec 1 2010, 09:34
|

Профессионал
    
Группа: Свой
Сообщений: 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 работает как положено.
Также почитайте и посмотрите приложенные файлы.
|
|
|
|
|
Dec 2 2010, 08:54
|
Частый гость
 
Группа: Участник
Сообщений: 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.
|
|
|
|
|
Dec 3 2010, 12:30
|
Частый гость
 
Группа: Участник
Сообщений: 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! Код прикрепляю.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|