Если сам не сможеш, помогу, как чуть время появится......
Ассемблер (ASM) для AVR в вопросах и ответах
- Сообщения: 882
- Зарегистрирован: Ср фев 22, 2012 01:25:21
Тут http://radiokot.ru/forum/viewtopic.php?f=61&t=87127 я как то выкладывал свой вариант читалки на Си, думаю перевернуть для асма, проблем не составит...
Если сам не сможеш, помогу, как чуть время появится......
Если сам не сможеш, помогу, как чуть время появится......
- Реклама
pyzhman - главный критерий - аккуратность во всём, иначе я просто бы начал изучение МК с Си.
А то, что прерывание занимает больше, чем остальной код - хорошего ничего в этом нет.
shads, сейчас у меня нечто похожее и есть, но выглядит оно не сильно здорово, согласись.
А то, что прерывание занимает больше, чем остальной код - хорошего ничего в этом нет.
shads, сейчас у меня нечто похожее и есть, но выглядит оно не сильно здорово, согласись.
Прибор, защищённый предохранителем, сгорает первым, защитив предохранитель. Закон Мерфи.
По мне, определение длительности паузы приводит к необходимости двух разных типов прерываний - по фронту и по спаду. А вот если определять длительность посылки между двумя фронтами, то получается проще. Вот попробовал написать в предположении, что входной сигнал подается на вход INT0 и инвертирован по отношению к протоколу.Seriyvolk писал(а):по прерыванию сравниваю время паузы меду импульсами от большего к меньшему и по итогам сравнения уже идёт какое-либо действие (запись 1/0 в регистр и его сдвиг)
Спойлер
Код: Выделить всё
;TEST_Seriyvolk
.include "tn13def.inc" ; Используем Tiny13
.set Fo=9600000 ; встроенный генератор 9.6MHz
;//////////////////////////////////////////////////////////////////////////////
;//////////// ПЕРЕМЕННЫЕ /////////////
;//////////////////////////////////////////////////////////////////////////////
.CSEG
;/////////////////////////////////////////////////////////
;//////////// ПРЕРЫВАНИЯ /////////////
;/////////////////////////////////////////////////////////
RJMP START
IJMP ; обслуживание прерывания посылки
RETI
TIME_OVER:
ADIW XH:XL,1
CP R19,XL
CPC R18,XH
BRLO START
RETI
;***********************************
ISR_INT_BEG:
CLR XH
CLR XL
LDI ZL,LOW(ISR_INT_END)
RETI
ISR_INT_END:
SET
RET
;/////////////////////////////////////////////////////////
;//////////// ИНИЦИАЛИЗАЦИЯ /////////////
;/////////////////////////////////////////////////////////
Start:
LDI R16,RAMEND
OUT SPL,R16
CLR ZH
CLR XH
CLR XL
LDI R16,0b00000010
OUT PORTB,R16
OUT DDRB,R16
NOP
OUT DDRB,ZH
LDI R18,HIGH(120000/(1000000/(Fo/256))) ;порог для определения отсутствия
LDI R19,LOW (120000/(1000000/(Fo/256))) ;операций
LDI R20,HIGH(13000/(1000000/(Fo/256))) ; длительность синхропосылки
LDI R21,LOW (13000/(1000000/(Fo/256))) ; минус защитный интервал
LDI R16,0b00100010
OUT MCUCR,R16 ; разрешение прерывания по спаду INT0
LDI R16,$40
OUT GIMSK,R16 ; разрешение прерывания INT0
LDI R16,0b00000010
OUT TIMSK0,R16
SER R16
OUT TIFR0,R16
OUT GIFR,R16
LDI ZL,LOW(ISR_INT_BEG)
LDI R16,1
OUT TCCR0B,R16
CLT
SEI
WAIT_SINHRO:
SLEEP
BRTC WAIT_SINHRO
CLT
CP XL,R21
CPC XH,R20
BRLO START ; не, это не синхропосылка
; принята синхропосылка
RESEIVE_CODE_BEGIN:
CLR R10
CLR R11
CLR R12
CLR R13 ;очистить регистры приёма
LDI R22,32 ; счётчик битов
GO_RESEIVE:
CLR XH
CLR XL
LDI R20,HIGH(1680/(1000000/(Fo/256))) ;порог для определения 1 или 0
LDI R21,LOW (16800/(1000000/(Fo/256))) ;
SER R16
OUT TIFR0,R16
OUT GIFR,R16
LDI ZL,LOW(ISR_INT_END)
LDI R16,1
OUT TCCR0B,R16
CLT
SEI
WAIT_CODE:
SLEEP
BRTC WAIT_CODE
CLT
; принят очередной бит
CP XL,R21
CPC XH,R20
BRLO SET_0 ;
SET_1:
SEC
RJMP SET_GND
SET_0:
CLC
SET_GND:
ROR R10
ROR R11
ROR R12
ROR R13
DEC R22
BRNE GO_RESEIVE
; принят адрес и код команды
;
;
RJMP GO_RESEIVE
; RJMP START
; END
Последний раз редактировалось akl Вс янв 19, 2014 18:30:48, всего редактировалось 1 раз.
Да, длительность посылки вполне реально определять между фронтами, а поскольку с ИК приёмника сигнал идёт инвертированным - фронты спадающие.
Идею почти понял, ща немного раскурю этот кусок кода и попробую воплотить его в жизнь
Идею почти понял, ща немного раскурю этот кусок кода и попробую воплотить его в жизнь
Прибор, защищённый предохранителем, сгорает первым, защитив предохранитель. Закон Мерфи.
- Сообщения: 882
- Зарегистрирован: Ср фев 22, 2012 01:25:21
Хотите сказать, что на Си не возможно писать аккуратно?Seriyvolk писал(а):pyzhman - главный критерий - аккуратность во всём, иначе я просто бы начал изучение МК с Си.
Вообще то большой код в прерывании, совсем не означает, что оно выполняется долго (я так понял вы именно это имели ввиду)...Seriyvolk писал(а):А то, что прерывание занимает больше, чем остальной код - хорошего ничего в этом нет.
На сам деле, обычно туда включено много (коротких и быстрых) ветвей алгоритма... и именно поэтому код может кажется громоздким.....
В целом, вот как я решил у себя http://radiokot.ru/forum/viewtopic.php? ... 6#p1623176Seriyvolk писал(а):Да, длительность посылки вполне реально определять между фронтами
- Реклама
В целом, на данный момент я имею крайне схожее решение, но оно мне не нравится.shads писал(а):В целом, вот как я решил у себя http://radiokot.ru/forum/viewtopic.php? ... 6#p1623176
Прибор, защищённый предохранителем, сгорает первым, защитив предохранитель. Закон Мерфи.
- Сообщения: 882
- Зарегистрирован: Ср фев 22, 2012 01:25:21
Чем?Seriyvolk писал(а):В целом, на данный момент я имею крайне схожее решение, но оно мне не нравится.shads писал(а):В целом, вот как я решил у себя http://radiokot.ru/forum/viewtopic.php? ... 6#p1623176
Алгоритмом, вестимо. Так же вся борода обрабатывается в прерывании. Много сравнений/переходов и всяких других действий.
Да, без знания основ - невозможно.Хотите сказать, что на Си не возможно писать аккуратно?
Прибор, защищённый предохранителем, сгорает первым, защитив предохранитель. Закон Мерфи.
- Сообщения: 882
- Зарегистрирован: Ср фев 22, 2012 01:25:21
И что из за этого у вас в программе страдает?Seriyvolk писал(а):вся борода обрабатывается в прерывании.
По другому у вас получится калека, а не декодер...Seriyvolk писал(а):Много сравнений/переходов и всяких других действий.
Согласен... основы не помешаютSeriyvolk писал(а):Да, без знания основ - невозможно.
- Сообщения: 52
- Зарегистрирован: Пн май 27, 2013 17:02:32
Здравствуй, РадиоКот.
Ты меня пока ни разу не подводил.
Уверен, что не подведёшь и сейчас.
Помоги мне, пожалуйста, а то я уже голову сломал.
Пишу часики на ассме.
Для ATMega16 всё написано, просимулировано, работает отлично, посмотреть можно тут.
Но решил я впихнуть свои часики в ATMega8, ибо жирновато им быть в 16-й Меге.
И тут появились траблы.
Во-первых, Протеус не может симулировать в реальном времени, ругается, что чрезмерная загрузка проца.
Во-вторых, 9-й и 10-й выводы контроллера походу работают в режиме GPIO (PB6, PB7), хотя настроены на работу с часовым кварцем.
Блин, но в проекте для ATMega16 таких проблем не возникало!!!
Где искать баги???
Ну и собстно прилагаю сам код, из которого вырезал всё лишнее, оставил только индикацию для одного семисегментника.
Ты меня пока ни разу не подводил.
Уверен, что не подведёшь и сейчас.
Помоги мне, пожалуйста, а то я уже голову сломал.
Пишу часики на ассме.
Для ATMega16 всё написано, просимулировано, работает отлично, посмотреть можно тут.
Но решил я впихнуть свои часики в ATMega8, ибо жирновато им быть в 16-й Меге.
И тут появились траблы.
Во-первых, Протеус не может симулировать в реальном времени, ругается, что чрезмерная загрузка проца.
Во-вторых, 9-й и 10-й выводы контроллера походу работают в режиме GPIO (PB6, PB7), хотя настроены на работу с часовым кварцем.
Блин, но в проекте для ATMega16 таких проблем не возникало!!!
Где искать баги???
Ну и собстно прилагаю сам код, из которого вырезал всё лишнее, оставил только индикацию для одного семисегментника.
По-моему, Вы слишком рано выключаете разряд, нужно немного попозже, примерно одну четверть времени от полного цикла вывода всех четырех разрядов.
P.S. Организация дисплея конечно не очень. Посмотрите в протеусе, есть хороший пример с драйвером для семисегментника на асме, в папке C:\Program Files\Labcenter Electronics\Proteus 7 Professional\SAMPLES\VSM for AVR\AVR Tiny15 Demo, главное поймите как это работает
P.S. Организация дисплея конечно не очень. Посмотрите в протеусе, есть хороший пример с драйвером для семисегментника на асме, в папке C:\Program Files\Labcenter Electronics\Proteus 7 Professional\SAMPLES\VSM for AVR\AVR Tiny15 Demo, главное поймите как это работает
Последний раз редактировалось zero648 Чт янв 23, 2014 23:41:35, всего редактировалось 1 раз.
в протеусе в свойствах контроллера указать CKSEL fuses - внешний кварц, и указать частоту кварцаBlYur писал(а):Протеус не может симулировать в реальном времени
Коктейль "Рекурсивный": 20% спирта, 30% воды, 50% коктейля "Рекурсивный"...
Эт снова я!
По старой доброй традиции опять с проблемой...
Суть её такова: В регистре (допустим R25) имею число в диапазоне от нуля до 99 по десятичной системе. Мне это число нужно вывести на дисплей 44780, и всего-то.
Для вывода пользуюсь функцией, в переменную которой (R17) нужно загружать код символа перед выводом.
Т.е. примерно так:
LDI R17,0b00100000
DATA_WR //Вывели на дисплей пробел
DATA_WR //Вывели ещё один пробел
Может кто скажет, как это проще делается?
Суть её такова: В регистре (допустим R25) имею число в диапазоне от нуля до 99 по десятичной системе. Мне это число нужно вывести на дисплей 44780, и всего-то.
Для вывода пользуюсь функцией, в переменную которой (R17) нужно загружать код символа перед выводом.
Т.е. примерно так:
LDI R17,0b00100000
DATA_WR //Вывели на дисплей пробел
DATA_WR //Вывели ещё один пробел
Может кто скажет, как это проще делается?
Прибор, защищённый предохранителем, сгорает первым, защитив предохранитель. Закон Мерфи.
Таки непонятно, у вас переменная в bcd формате или двоичном. Потому могут быть варианты.Seriyvolk писал(а):Может кто скажет, как это проще делается?
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
А что может быть не понятно?
В регистре торчит число, 0b00001111, мне нужно вместо этого числа на дисплей вывести "15". Вопрос - как? И аналогично с числами от 0b00000000 до 0b01100011 Пример доступного мне способа вывода я привёл.
В регистре торчит число, 0b00001111, мне нужно вместо этого числа на дисплей вывести "15". Вопрос - как? И аналогично с числами от 0b00000000 до 0b01100011 Пример доступного мне способа вывода я привёл.
Прибор, защищённый предохранителем, сгорает первым, защитив предохранитель. Закон Мерфи.
Спросили же, bcd или двоичный? Если 0b00001111 - это 15, то в двоичном. В bcd это будет выглядеть как 0b00010101 (0001 = 1, 0101 = 5, итого 1 и 5, т.е. 15)Seriyvolk писал(а):А что может быть не понятно?
Просто некоторые функции, которые вы не сами писали, могут использовать именно bcd, а к нему ещё надо преобразовать число.
Ну раз это так называется, то мне нужно двоичный код в регистре перегнать в этот "BCD". Дальше я сам разберусь.
Всем спасибо, задачу решил сам.
Всем спасибо, задачу решил сам.
Прибор, защищённый предохранителем, сгорает первым, защитив предохранитель. Закон Мерфи.
Нарыл крайне интересный для меня кусочек кода
Но непонятна одна запись... LDI r18,-1+'0'
Это значит загрузили в R18 минус единицу, а +'0' - это что и зачем?
Но непонятна одна запись... LDI r18,-1+'0'
Это значит загрузили в R18 минус единицу, а +'0' - это что и зачем?
Прибор, защищённый предохранителем, сгорает первым, защитив предохранитель. Закон Мерфи.
-1+'0' - загрузить код символа "0" -1,Seriyvolk писал(а):Но непонятна одна запись... LDI r18,-1+'0'
А откуда загрузить? Нужно писать какую-то таблицу?
Вот весь кусок кода
Вот весь кусок кода
Код: Выделить всё
Hex2Ascii: LDI r18,-1+'0'
bcd1: INC r18
SUBI r16,100
BRCC bcd1
LDI r17,10+'0'
bcd2: DEC r17
SUBI r16,-10
BRCS bcd2
SBCI r16,-'0'
RETПрибор, защищённый предохранителем, сгорает первым, защитив предохранитель. Закон Мерфи.


