Страница 1 из 1

Помогите написать код на АСМЕ.

Добавлено: Пн мар 23, 2009 16:51:41
Tigra
Кто силён в асме ? Помогите написать код,чтобы переменная или просто бит записывался каждый раз в следующую ячейку памяти EEPROM.А когда память заполнится что бы она стиралась и всё начиналось заново.
Я в асме вообще ничего не понимаю,а на си это не сделаешь!

Добавлено: Пн мар 23, 2009 17:17:19
Yellow Tiger
Какой контроллер-то?

Добавлено: Пн мар 23, 2009 18:00:27
Tigra
Yellow Tiger писал(а):Какой контроллер-то?
Attiny 2313

Добавлено: Пн мар 23, 2009 18:58:42
Pooher

Код: Выделить всё

WriteToEEPROM:
 inc r16;адрес EEP++
 ldi r18, 0x80;r18=EEPEND+1
 cpse r16, r18;если адрес EEP = EEPEND+1 то очищаем адрес и  переходим к записи
 rjmp write
 clr r16 
write:			
 sbic EECR, EEWE ;ждём готовности EEPROM
 rjmp write	
 out EEARL, r16;EEARL(Регистр адреса EEPROM) = адрес EEP
 out EEDR, r17 ; EEDR(Регистр данных EEPROM) = r17
 ldi tmp,(1<<EEMWE) ;Разрешаем запись бла, бла, бла...
 out EECR, tmp
 ldi tmp, (1<<EEWE)|(1<<EEMWE)
 out EECR, tmp
 ret

Добавлено: Пн мар 23, 2009 19:13:13
Tigra
Pooher писал(а):

Код: Выделить всё

WriteToEEPROM:
 inc r16;адрес EEP++
 ldi r18, 0x80;r18=EEPEND+1
 cpse r16, r18;если адрес EEP = EEPEND+1 то очищаем адрес и  переходим к записи
 rjmp write
 clr r16 
write:			
 sbic EECR, EEWE ;ждём готовности EEPROM
 rjmp write	
 out EEARL, r16;EEARL(Регистр адреса EEPROM) = адрес EEP
 out EEDR, r17 ; EEDR(Регистр данных EEPROM) = r17
 ldi tmp,(1<<EEMWE) ;Разрешаем запись бла, бла, бла...
 out EECR, tmp
 ldi tmp, (1<<EEWE)|(1<<EEMWE)
 out EECR, tmp
 ret
Спасибо за код!
В моём устройстве (противоугонка) при правильном наборе кода записывается переменная (в ЕЕПРОМ) и если произойдёт перезагрузка устройства то программа начинает работать с нужного места,а не начинает заново.
У важаемый Pooher подскажите как применить ваш код к моей программе на си?

Добавлено: Пн мар 23, 2009 20:10:10
bsyomov
А зачем писать не критичный к скорости код на асме, чтобы потом использовать в Сшной программе? =)

Добавлено: Пн мар 23, 2009 20:13:00
Tigra
bsyomov писал(а):А зачем писать не критичный к скорости код на асме, чтобы потом использовать в Сшной программе? =)
Если знаете как написать это на си - напишите пожалуйста буду очень признателен!

Добавлено: Пн мар 23, 2009 21:22:25
Pooher
В моём устройстве (противоугонка) при правильном наборе кода записывается переменная (в ЕЕПРОМ) и если произойдёт перезагрузка устройства то программа начинает работать с нужного места,а не начинает заново.
Для таких целей код нужен другой...

Добавлено: Пн мар 23, 2009 21:26:55
Tigra
Pooher писал(а):Для таких целей код нужен другой...
Подскажите какой,и как его применить?

Добавлено: Пн мар 23, 2009 21:36:09
Pooher
Как я понимаю, Ваша программа должна после Reset считывать ячейку EEPROM, и по её содержимому определять с каково места ей работать?

Добавлено: Пн мар 23, 2009 21:47:13
Tigra
Pooher писал(а):Как я понимаю, Ваша программа должна после Reset считывать ячейку EEPROM, и по её содержимому определять с каково места ей работать?
Совершенно верно!
Я собрал противоугонное устройство в нём всё работало как и было задуманно, но появился подводный камень- из за помех бортовой сети автомобиля стали происходить перезагрузки.И как результат- машина глохнет и начинает сигналить. Попытка бороться с помехами не чего не дала .Последний шанс наладить устройство это записывать состояние устройства в энергонезависимую память системы, но я боюсь что циклов гарантированной перезаписи будет маловато.И вот по этому мне надо использоать весь объём ЕЕПРОМ.

Добавлено: Пн мар 23, 2009 22:10:06
Pooher
Тогда код подойдёт, с начала неправильно понял смысл задачи.
В начале (после ресет) можно такой код использовать.

Код: Выделить всё

ReadEEP:
clr r16 ;очищаем адрес
Read:
out EEARL, r16 ;загружаем
ldi r17, 1
out EECR, r17 
in  r17, EEDR ;читаем
ldi r18, 0xFF   
cpse r17, r18 ;если что нибудь по этому адресу записано, переход
rjmp Lable
inc r16     ;если нет, адрес++, и снова читаем
rjmp Read 

Lable:
;код определения места, куда программа перейдёт, или выставить флаг можно
ret
В Си я не силён, но по моему можно использовать ASM вставки.

Добавлено: Пн мар 23, 2009 22:16:44
Tigra
Pooher писал(а):
Lable:
;код определения места, куда программа перейдёт, или выставить флаг можно
ret
[/code]
А там можно вставить переменную "stat" что бы если там
0-иди туда-то;
1-иди туда-то;
или не переменную а просто бит
0-иди туда-то;
1-иди туда-то;
?????????????

Добавлено: Пн мар 23, 2009 22:35:59
Pooher

Код: Выделить всё

Lable:
ldi tmp, xx
cpse r17, xx ; прочитанное из EEPROM = xx
ldi stat, 1     ; тогда пропускаем
ldi tmp, yy
cpse r17, yy  прочитанное из EEPROM = yy
ldi stat, 0     ; тогда пропускаем
ret 
т.е. если прочитанное из EEPROM = xx, то если = yy stat=0
если = yy, то stat=1
В главном цикле:

Код: Выделить всё

main:
rcall ReadEEP
cpi stat, 1
breq stat1
cpi stat, 0
breq stat0
rjmp main
Или проще:

Код: Выделить всё

ReadEEP:
clr r16 ;очищаем адрес
Read:
out EEARL, r16 ;загружаем
ldi r17, 1
out EECR, r17
in  r17, EEDR ;читаем
ldi r18, 0xFF   
cpse r17, r18 ;если что нибудь по этому адресу записано, выход
ret
inc r16     ;если нет, адрес++, и снова читаем
rjmp Read 
ret

main:
rcall ReadEEP
cpi r17, xx
breq stat1
cpi r17, yy
breq stat0
rjmp main

Добавлено: Пн мар 23, 2009 22:54:10
Tigra
Извините меня пожалуйста,но в этом коде я вообще ничего не могу понять!
Я разобрался как с помощью переменной из ЕЕПРОМ возвращаться в нужное место в программе . Я ни как не могу разобраться, как записывать в следующую ячейку ЕЕПРОМ.
У себя в программе я могу создать подпрограмму,для работы с ЕЕПРОМ. Мне нужно чтобы попав в эту подпрограмму (на АСМЕ) записывалась в следующую ячейку памяти переменная "stat" в которую я уже заранее (на Си) запишу значение 0 или 1 или 2 или 3.
Это возможно сделать? (извените за назойливость)

Добавлено: Пн мар 23, 2009 23:16:01
Pooher
Этим и занимается код из моего первого поста:

Код: Выделить всё

WriteToEEPROM:
 inc r16;адрес EEP++
 ldi r18, 0x80;r18=EEPEND+1
 cpse r16, r18;если адрес EEP = EEPEND+1 то очищаем адрес и  переходим к записи
 rjmp write
 clr r16
write:         
 sbic EECR, EEWE ;ждём готовности EEPROM
 rjmp write   
 out EEARL, r16;EEARL(Регистр адреса EEPROM) = адрес EEP
 out EEDR, r17 ; EEDR(Регистр данных EEPROM) = r17
 ldi tmp,(1<<EEMWE) ;Разрешаем запись бла, бла, бла...
 out EECR, tmp
 ldi tmp, (1<<EEWE)|(1<<EEMWE)
 out EECR, tmp
 ret 
r16 - счётчик. Он инкрементируется перед каждым циклом записи.
ЗЫ: Неужели Вам мало "100,000 Write/Erase Cycles"

Добавлено: Пн мар 23, 2009 23:23:58
Tigra
Pooher писал(а): ЗЫ: Неужели Вам мало "100,000 Write/Erase Cycles"
Постановка на охрану-перезапись,
Снятие с охраны - перезапись,
Тревога - перезапись,
Режим VALET -перезапись.
Думаю что с такими запросами маловато будет!

А по поводу вашего кода ,как он узнает переменная "stat" какое число содержит? Где там её пририсовать?
(СПАСИБО!)

Добавлено: Вт мар 24, 2009 02:35:46
ibiza11
100000 циклов перезаписи всего
пусть 5 циклов на это:
1)Постановка на охрану-перезапись,
2)Снятие с охраны - перезапись,
3)Тревога - перезапись,
4)Режим VALET -перезапись.
5)Че нить еще, перезапись

пусть 10 раз в день(!!!) все это повторяется по циклу

тогда в день 50 раз перезапись.

100000/50=2000 дней

ИТОГ около 5 лет и 6 месяцев.... за это время ваша система устареет, либо раньше откажет что то менее надежное в системе (электролитические кондеры, например... :? )

Добавлено: Вт мар 24, 2009 11:27:17
Pooher
А по поводу вашего кода ,как он узнает переменная "stat" какое число содержит? Где там её пририсовать?
Какой именно код? Для чтения, или для записи?
Постановка на охрану-перезапись,
Снятие с охраны - перезапись,
Тревога - перезапись,
Режим VALET -перезапись.
Думаю что с такими запросами маловато будет!
Я бы в таком случае для каждого действия использовал свою ячейку.
100000/50=2000 дней

ИТОГ около 5 лет и 6 месяцев.... за это время ваша система устареет, либо раньше откажет что то менее надежное в системе (электролитические кондеры, например... Confused )
Согласен. Хватить должно "за глаза".