Добрый день! Хочу связать ATMega 2561 и флеш-память AT45DB041A через SPI. На данном этапе хочу хотя бы считать состояние регистр статуса. Но не работает. Помогите плиз!
чет хлопотно асм ковырять, типичная ошибка при работе с данной флехой забывают дергать чип селектом вот рабочий код, правда на си (и не через апаратный spi)
;PB0 - SS ;PB1 - SCLK ;PB2 - MOSI ;PB3 - MISO ; Установка MOSI и SCK на вывод, все остальные на ввод ldi r19,(0<<PB3)|(1<<PB2)|(1<<PB1)|(0<<PB0) out DDRB,r18
Почему SS (PB0) на ввод? AT45 принимает команды по SPI при низком уровне SS, им должен управлять контроллер! Так что во первых: 1<<PB0 в DDRB (и сразу этот же пин в единицу в PORTB)
Во вторых: перед началом обмена по SPI - CBI PORTB,PB0, после окончания приема/передачи - SBI PORTB,PB0.
;PB0 - SS ;PB1 - SCLK ;PB2 - MOSI ;PB3 - MISO ; Установка MOSI и SCK на вывод, все остальные на ввод ldi r19,(0<<PB3)|(1<<PB2)|(1<<PB1)|(0<<PB0) out DDRB,r18
Почему SS (PB0) на ввод? AT45 принимает команды по SPI при низком уровне SS, им должен управлять контроллер! Так что во первых: 1<<PB0 в DDRB (и сразу этот же пин в единицу в PORTB)
Во вторых: перед началом обмена по SPI - CBI PORTB,PB0, после окончания приема/передачи - SBI PORTB,PB0.
Пока что все...
Опередили... Ну зато у меня ассемблер
SS на флеш памяти идет с инверсией. Сначала устанавливаем SS в 1. До посылки байта его в 0 - а после в 1. Правильно? У меня еще тут Оооочень важный вопрос? А как переключать наш контроллер в режим чтения?
Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей.
Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре.
Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.
Сначала устанавливаем SS в 1. До посылки байта его в 0 - а после в 1. Правильно?
Да
Slavast писал(а):
У меня еще тут Оооочень важный вопрос? А как переключать наш контроллер в режим чтения?
Здрасьте приехали... У вас же уже есть 2 отдельные процедуры, одна для записи (SPI_MasterTransmit), одна для чтения (SPI_MasterReceive). Послали сколько надо, прочитали сколько надо, чего переключать-то?
Slavast писал(а):
Т. Е непосредственно единицу на сам порт этого пина?
Нам же нужно со старта программы держать высокий уровень на SS пока не начался процесс обмена по SPI.
Сначала устанавливаем SS в 1. До посылки байта его в 0 - а после в 1. Правильно?
Может загвоздка в следующем. В даташите пишут:
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?
Т.е. чтоб задать SS нужно:
ldi r16,(1<<PB0) ldi r17,(1<<DDB0) out PORTB,r16 out DDRB,r17
чет хлопотно асм ковырять, типичная ошибка при работе с данной флехой забывают дергать чип селектом вот рабочий код, правда на си (и не через апаратный spi)
Код:
не забыть про инверсию на чип селект
Спасибо. А есть такой же примерно код на ассемблере?
Вот тут и непонятно: MOSI и SCK нужно задавать в 1 на DDRB или PORTB (т.е. указывать только направление или в заранее заданном на выход порт выдавать 1 или 0)? Это же ведь существенно! В Си коде за этим не могу уследить. Точно также и SS - нужно 1 посылать в DDRB или PORTB?
Когда мы начинаем передавать данные по SPI, МК сам ставит сигналы MOSI и SCK в нужные состояния (при настройке SPI задается режим 0 или 3). Но пином SS (лииня CS) он не управляет. Управлять линией CS можно вообще с любого свободного пина МК, и делается это программно, особенно если на SPI сидит более одного устройства.
Читаем даташит на память, раздел Device operation: "A valid instruction starts with FALLING EDGE of CS followed by the....". Значит перед началом передачи данных должен быть переход линии CS с высокого уровня на низкий, следовательно нужно программно установить при старте SS в 1, а перед передачей его установить в 0. Чтобы еще лучше понять читайте раздел AC Waveforms, там оба режима (0 и 3) нарисованы.
Пример, правда для тини24, и SPI программно-аппаратный (CLK управляется программно), процедура SPIOUT служит одновременно для записи и для чтения. PA3 - CS (вывод), PA4 - CLK (вывод), PA5 - MOSI (вывод), PA6 - MISO (ввод)
SPIOUT: ;fastest possible out via USI OUT USIDR,r16 ;send byte to SPI data register LDI r16,(1<<USIWM0)|(0<<USICS0)|(1<<USITC) ;clk=0 LDI r17,(1<<USIWM0)|(0<<USICS0)|(1<<USITC)|(1<<USICLK) ;clk=1 OUT USICR,r16 OUT USICR,r17 ;clock 1 OUT USICR,r16 OUT USICR,r17 ;clock 2 OUT USICR,r16 OUT USICR,r17 ;clock 3 OUT USICR,r16 OUT USICR,r17 ;clock 4 OUT USICR,r16 OUT USICR,r17 ;clock 5 OUT USICR,r16 OUT USICR,r17 ;clock 6 OUT USICR,r16 OUT USICR,r17 ;clock 7 OUT USICR,r16 OUT USICR,r17 ;clock 8 IN r16,USIDR ;read byte from SPI data register RET
чет хлопотно асм ковырять, типичная ошибка при работе с данной флехой забывают дергать чип селектом вот рабочий код, правда на си (и не через апаратный spi)
Код:
не забыть про инверсию на чип селект
Спасибо. А есть такой же примерно код на ассемблере?
к сожалению нет. да и очень прозрачно все. переходите на си. можно ведь просто один к одному заменить команды и в симуляторе глянуть что да как ауже потом ножко дрыганье заменить на хардварный спи
_________________ С уважением, Денис Железняков aka ZiB Мой блог: http://ziblog.ru
В конечном итоге получилось только передать по SPI: осциллографом щупаю MOSI - вижу передаваемые данные, SS - вижу низкие уровни в момент передачи,на SCLK - тактирование. Но на MISO ничего нет.!.((((((((( И на UART выдаются 00 (((((((( HELP!
Ну как говорится "Чудес не бывает!" Ошибки возможны ведь не только в программе но и в железе Приведите схему включения, фото платы или ещё что. Что с ресетом у вас? (какой уровень подали)
_________________ С уважением, Денис Железняков aka ZiB Мой блог: http://ziblog.ru
Ну как говорится "Чудес не бывает!" Ошибки возможны ведь не только в программе но и в железе Приведите схему включения, фото платы или ещё что. Что с ресетом у вас? (какой уровень подали)
Ресет на флеш подается вместе с ресетом на МК. Вот решил вместо первой флешки на плате использовать вторую - на MISO появились какие-то сигналы. Похож вроде на состояние Статус регистра: RDY|-BUSY- COMP 0 1 1 x x x Только вместо высого сяигнала на RDY|BUSY стоит низкий (BUSY). Может так и надо. Но все же UART не выдает на терминал. Может надо использовать так называемый режим UART в SPI??
Почему в процедуре вывода по UART стоит STS, а не OUT?
PS: настройки SPI/UART не проверял. Модифицированный (AT25 вместо AT45, команда RDID вместо 0хD7) вариант проверен в симуляторе - работает.
www2: SBiS UCSR0A,UDRE0 RJMP www2 out UDR0, r20 break
Здесь AVR STUDIO ругается: D:\Slava\Atmel\Projects\SPI sobran\SPIsobran.asm(114): error: Operand 1 out of range: 0xc0 D:\Slava\Atmel\Projects\SPI sobran\SPIsobran.asm(117): error: Operand 1 out of range: 0xc6
Можете свой вариант на AT25 кинуть? У меня примерно все остальное так же?
Подскажите что я делаю не так. Пытаюсь считать ID из флешь памяти ID как бы считывает но почему-то не принимается вместо этого одни FF принимаются.
где-то в середине видно READID [1F60] но вот вместо 1F и 60 принимаются почему-то FF Для выбора кристалла SS переход с высокого уровня на низкий сделал в функции передачи но мне кажется что это не очень хорошо как сделать правильно ? И ещё вопросик что бы записать регистр состояния надо сначала подать команду записи регистра (0x1) а следующим байтом отправить что записывать в сам регистр ? на русском описание не нашёл вот сижу два дня читаю даташит по тихонько начинаю понимать =)
Код:
void SPI_MasterTransmit(char cData) { PORTB=(0<<PORTB0); //переход с высого уровня на назкий (SS) /* Запуск передачи данных */ SPDR = cData; /* Ожидание завершения передачи данных */ while(!(SPSR & (1<<SPIF))); input=SPDR; PORTB=(1<<PORTB0);
// Alphanumeric LCD functions #asm .equ __lcd_port=0x15 ;PORTC // Для изменения порта подключения вставляем вместо .equ __lcd_port=0x15 ;PORTC (исходя из даташита стр. Register Summary) #endasm // .equ __lcd_port=0x1B ;PORTA или .equ __lcd_port=0x18 ;PORTB или .equ __lcd_port=0x12 ;PORTD (даташит atmega16)
#include <lcd.h> char x; int input; // LCD // char lcd_buffer[33]; unsigned char data; int temp;
void SPI_MasterInit(void) { /* Установка MOSI и SCK на вывод, все остальные на ввод */
DDRB = (1<<DDB2)|(1<<DDB1)|(1<<DDB0); // 1<<DDB0 для SS /* Разрешение SPI в режиме мастера, установка скорости связи fck/16 */SPCR = (0<<SPIE) | (1<<SPE) | (0<<DORD) | (1<<MSTR) | (0<<CPOL) | (0<<CPHA) | (0<<SPR1) | (0<<SPR0);
}
void SPI_MasterTransmit(char cData) { PORTB=(0<<PORTB0); //переход с высого уровня на назкий (SS) /* Запуск передачи данных */ SPDR = cData; /* Ожидание завершения передачи данных */ while(!(SPSR & (1<<SPIF))); input=SPDR; PORTB=(1<<PORTB0);
Хорошо, но так тоже принимаются одни FF. Вытащил их из функции и сделал так
Код:
PORTB=(0<<PORTB0); //переход с высого уровня на назкий (SS) SPI_MasterTransmit(0x15); SPI_MasterTransmit(0xFF); SPI_MasterTransmit(0xFF); PORTB=(1<<PORTB0);
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 23
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения