Страница 2 из 3
Re: Attiny13 : 3х канальный ШИМ по внешниму прерыванию
Добавлено: Чт апр 26, 2012 09:53:27
Engineer_Keen
Во-первых, надо скопировать и поделить пополам значение яркости, так что не просто:
Код: Выделить всё
SEQ1: Delay_d100s 351 ;Black -> Yellow 15 min (351/100s 256 ~ 15 min)
SetColor BRI,R2,ZERO
IJNZ BRI,SEQ1
SER BRI
а вот так
Код: Выделить всё
SEQ1: Delay_d100s 351 ;Black -> Yellow 15 min (351/100s 256 ~ 15 min)
MOV R2,BRI ;копируем
LSR R2 ;делим на 2 сдвигом вправо
SetColor BRI,R2,ZERO
IJNZ BRI,SEQ1
SER BRI
Получается что R каждые 3.51с увеличивается на 1 (1,2,3,4,5 ... 254,255), а G в это же самое время на 0,5 или на 1 за 7,02с (1/2=0, 2/2=1, 3/2=1, 4/2=2, 5/2=2 ... 254/2=127,255/2=127). Что касается максимального синего цвета, то там можно поступить точно также, не меняя самого условия цикла (макросы DJNZ/IJNZ)
Re: Attiny13 : 3х канальный ШИМ по внешниму прерыванию
Добавлено: Чт апр 26, 2012 09:55:33
wixa
Понял

Спасибо:)
Re: Attiny13 : 3х канальный ШИМ по внешниму прерыванию
Добавлено: Чт апр 26, 2012 15:27:38
wixa
Отчитываюсь
Сделал вот так :
Код: Выделить всё
LOOP4: Delay_d100s 24 ;Black -> Blue 1 min
MOV R2,BRI ;копируем
LSR R2 ;делим на 2 сдвигом вправо
SetColor ZERO,ZERO,R2
CPI R18,0
BRNE RES
IJNZ BRI,LOOP4
LOOP5: Delay_d100s 24 ;Blue -> Black 1 min
MOV R2,BRI ;копируем
LSR R2 ;делим на 2 сдвигом вправо
SetColor ZERO,ZERO,R2
CPI R18,0
BRNE RES
DJNZ BRI,LOOP5
WFI ;wait for pin change
RJMP SEQ1
Но вот теперь выбивает ошибку :
Error 1 Relative branch out of reach в 119 строке
Это строка
в LOOP5....
Строку
перед
я убрал , так как с ней выдало такую ошибку :
и такую
Код: Выделить всё
Error 2 syntax error, unexpected ',', expecting ':'
Вообщем так
Скомпилировалось без ошибок если убрать и
и
Но тогда прерывание во время LOOP5 не работает ....
Re: Attiny13 : 3х канальный ШИМ по внешниму прерыванию
Добавлено: Чт апр 26, 2012 16:20:45
Engineer_Keen
Метка просто слишком далеко впереди осталась и brne до нее не достает, лечится изменением brne на breq:
Код: Выделить всё
CPI R18,0
BREQ XXX1 ;перепрыгиваем команду перехода на RES если 0
RJMP RES ;переход на RES если не 0, rjmp точно достанет из любого места
XXX1: ;тут DJNZ или IJNZ, как и было
Почему ругается на CJNE непонятно, ведь он же есть в других строчках?
Re: Attiny13 : 3х канальный ШИМ по внешниму прерыванию
Добавлено: Чт апр 26, 2012 16:24:24
wixa
Engineer_Keen писал(а):
Почему ругается на CJNE непонятно, ведь он же есть в других строчках?
Нету
Он её почему то вообще не определяет как допустим BRNE (сининьким цветом)... Я в AVR Studio5 пишу, там используется AVR Assembler.... может в нём нет этой команды?
Re: Attiny13 : 3х канальный ШИМ по внешниму прерыванию
Добавлено: Чт апр 26, 2012 16:27:04
Engineer_Keen
Так это макрос, я его в начале не написал чтоле? Ну да, не написал
Вот он
У меня все эти макросы просто в отдельном файле лежат, и я его через include подключаю, поэтому не заметил.
Re: Attiny13 : 3х канальный ШИМ по внешниму прерыванию
Добавлено: Чт апр 26, 2012 16:28:55
wixa
Engineer_Keen писал(а):Так это макрос, я его в начале не написал чтоле? Ну да, не написал
Вот он
Так получается он не стандартный как BRNE ???
Re: Attiny13 : 3х канальный ШИМ по внешниму прерыванию
Добавлено: Чт апр 26, 2012 16:32:49
Engineer_Keen
Нет, несмотря на сходство, она не является командой ассемблера AVR. Такая команда, есть в ассемблере mcs51, поэтому пришлось написать такой макрос. Если в студии ткнуть на BRNE F1, то появится справка со всеми командами ассемблера. Все команды BRxx проверяют флаги в регистре статуса и потом переходят или нет. А чтобы эти флаги установить нужно сначала использовать команды сравнения (CP, CPI, CPC). А команда CJNE 51-го ассемблера сама сравнивала содержимое аккумулятора с другим числом и сама делала условный переход.
Re: Attiny13 : 3х канальный ШИМ по внешниму прерыванию
Добавлено: Чт апр 26, 2012 16:35:09
wixa
Вставил макрос в начале, между другими макросами, получил
Вот на всякий случай:
Код: Выделить всё
.include "tn13Adef.inc"
.def ZERO=R0
.def STR=R1
.def TEMP=R16
.def BRI=R17
.def FULL=R19
.def PWMR=R20
.def PWMG=R21
.def PWMB=R22
.def PWMC=R23
.def MASK=R24
.equ R=PB2
.equ G=PB1
.equ B=PB0
.equ CONT=PB3
.macro CJNE
CPI @0,@1
BRNE @2
.endm
.macro DJNZ
DEC @0 BRNE @1
.endm
.macro IJNZ
INC @0 BRNE @1
.endm
.macro OUTI
LDI TEMP,@1 OUT @0,TEMP
.endm
.macro DELAY_d100s ;Delay X/100 seconds
.if @0<256
LDI TEMP,@0
RCALL DEL
.else
LDI TEMP,255
RCALL DEL
LDI TEMP,(@0-255)
RCALL DEL
.endif
.endm
.macro SetColor ;Set RGB Color
MOV PWMR,@0 MOV PWMG,@1 MOV PWMB,@2
.endm
.macro WFI ;wait for interrupt
CLR R18
WAIT:CPI R18,0 ;(PIN Cnange)
BREQ WAIT
CLR R18
.endm
.cseg
CLR ZERO ;Clear ZERO
RJMP RESET ;RESET
SER R18 ;PCINT
RETI ;T0_OV
RETI ;EE_RDY
RETI ;ANA_COMP
RETI ;T0=A
RETI ;T0=B
RETI ;WDT
PWM: IN STR,SREG ;ADC
INC PWMC ;increment PWM counter
LDI MASK,((1<<CONT)>>3)
CP PWMC,PWMR ;compare counter and RED value
ROL MASK
CP PWMC,PWMG ;compare with GREEN
ROL MASK
CP PWMC,PWMB ;compare with BLUE
ROL MASK
OUT PORTB,R24 ;apply MASK to port
OUT SREG,STR
RETI
RESET: SER FULL
OUTI CLKPR,(1<<CLKPCE) ;Reset Fclk/8 Divider
OUT CLKPR,ZERO
OUTI SPL,low(RAMEND) ;Stack
OUTI DDRB,(1<<R)|(1<<G)|(1<<B) ;Set PORT Direction
OUTI PORTB,(1<<CONT) ;Set PORT PullUPs
OUTI ADMUX,(1<<ADLAR)|(1<<MUX1)|(1<<MUX0)
OUTI ADCSRA,(1<<ADEN)|(1<<ADSC)|(1<<ADIE)|(1<<ADATE)|(1<<ADPS2)|(0<<ADPS1)|(0<<ADPS0)
OUT ADCSRB,ZERO
OUTI PCMSK,(1<<CONT) ;Set Pin Change
OUTI GIMSK,(1<<PCIE) ;interrupt
SetColor ZERO,ZERO,ZERO ;Turn off all LEDs
SEI
RES:CLR BRI
CLR R18
SBIS PINB,CONT
RJMP SEQ2
SEQ1: Delay_d100s 50 ;Black -> Yellow 2 min (351/100s 256 ~ 15 min)
SetColor BRI,BRI,ZERO
CPI R18,0
BRNE RES
IJNZ BRI,SEQ1
SER BRI
LOOP1: Delay_d100s 24 ;Yellow -> Red 1 min
SetColor FULL,BRI,ZERO
CPI R18,0
BRNE RES
DJNZ BRI,LOOP1
WFI ;wait for pin change
SEQ2: Delay_d100s 24 ;Red -> Yellow 1 min
SetColor FULL,BRI,ZERO
CPI R18,0
BRNE RES
IJNZ BRI,SEQ2
SER BRI
LOOP3: Delay_d100s 50 ;Yellow -> Black 2 min
SetColor BRI,BRI,ZERO
CPI R18,0
BRNE RES
DJNZ BRI,LOOP3
LOOP4: Delay_d100s 24 ;Black -> Blue 1 min
MOV R2,BRI ;копируем
LSR R2 ;делим на 2 сдвигом вправо
SetColor ZERO,ZERO,R2
CPI R18,0
BRNE RES
IJNZ BRI,LOOP4
LOOP5: Delay_d100s 24 ;Blue -> Black 1 min
MOV R2,BRI ;копируем
LSR R2 ;делим на 2 сдвигом вправо
SetColor ZERO,ZERO,R2
CPI R18,0
BREQ XXX1
RJMP RES
CJNE R18,0,RES
XXX1:DJNZ BRI,LOOP5
WFI ;wait for pin change
RJMP SEQ1
DEL: LDI XH,0x54 ;Delay
LDI XL,0x73
SBIW XL,1
BRNE PC-1
DEC TEMP
BRNE DEL
RET
Re: Attiny13 : 3х канальный ШИМ по внешниму прерыванию
Добавлено: Чт апр 26, 2012 16:38:20
Engineer_Keen
на какой строке?
а, ну так там CJNE уже не нужно, мы же уже перед этим сравнили R18 с нулем.
Re: Attiny13 : 3х канальный ШИМ по внешниму прерыванию
Добавлено: Чт апр 26, 2012 16:39:29
wixa
Engineer_Keen писал(а):на какой строке?
Re: Attiny13 : 3х канальный ШИМ по внешниму прерыванию
Добавлено: Чт апр 26, 2012 16:49:00
wixa
Убрал CJNE.... заработало как надо. Спасибо....
Эх, если бы вы разжували на пальцах, как работает эта программа, с точки зрения написания её на Ассемблере..... но это уже будет наглость с моей стороны просить Вас об этом

))
P.S. Я мог бы заменить в каждом цикле
на
?
Re: Attiny13 : 3х канальный ШИМ по внешниму прерыванию
Добавлено: Чт апр 26, 2012 16:56:42
Engineer_Keen
wixa писал(а):Эх, если бы вы разжували на пальцах, как работает эта программа, с точки зрения написания её на Ассемблере..... но это уже будет наглость с моей стороны просить Вас об этом

))
Да, это уже совсем беспредел

Максимум подскажу мелочи. Остальное - читать книжки.
wixa писал(а):
P.S. Я мог бы заменить в каждом цикле
на
?
Да, это одно и тоже.
Re: Attiny13 : 3х канальный ШИМ по внешниму прерыванию
Добавлено: Чт апр 26, 2012 17:07:02
wixa
И всё-же я понял, что вставили последний цикл мы не туда

.....
Он должен был идти как пункт 2.0 - т.е. Первым циклом первой подпрограммы...., а получился последним пунктом второй подпрограммы.... что не логично

так, как теперь время ночи фиксировано временем исполнения LOOP4 и LOOP5.... А ночь у нас должна заканчиваться по прерыванию

.... соответственно, этот цикл нужно как то впихнуть перед SEQ1, или сделать его SEQ1, а SEQ1 переименовать в LOOP1, и так далее сместить нумерацию..... правильно я размышляю?
Re: Attiny13 : 3х канальный ШИМ по внешниму прерыванию
Добавлено: Чт апр 26, 2012 17:30:36
wixa
Сделал так..... SEQ1 переименовал в LOOP0, а LOOP5 в SEQ1, получилось!
Но пришлось подравить
в LOOP4, а то опять выдал ту же ошибку что и с LOOP5....
Решил Избавится от
с помощью
, но нарвался опять на ошибку в 18 строке :
BRNE @2
..... ошибка всё таже.... как от неё избавится ?:)....
P.S.вхожу во вкус

Re: Attiny13 : 3х канальный ШИМ по внешниму прерыванию
Добавлено: Пт апр 27, 2012 00:25:12
Alexeyslav
от идеи в голове, до конечной реализации
Этому процессу здорово помогает принцип
черного ящика.
Ну и само собой способность досконально представить как работает микроконтроллер, для этого даже не нужно ничего заучивать - можно по даташиту пройтись пальчиком. Так раз десять пройдешь а в 11-й уже не потребуется - все будет в памяти.
И когда в тупик заходишь, слишком сложно становится - нужно разбивать на части и грызть их в отдельности. Уметь смотреть программу на разных уровнях детализации.
Re: Attiny13 : 3х канальный ШИМ по внешниму прерыванию
Добавлено: Пт апр 27, 2012 08:23:00
wixa
Немного раскинул мозгами, и решил проблему с CJNE и ошибкой
Макрос теперь выглядит так:
Код: Выделить всё
.macro CJNE
CPI @0,@1
BREQ @2
RJMP @3
.endm
А цыклы вот так :
Код: Выделить всё
SEQ1: Delay_d100s 1 ;Blue -> Black 1 min
MOV R2,BRI ;копируем
LSR R2 ;делим на 2 сдвигом вправо
SetColor ZERO,ZERO,R2
CJNE R18,0,XXX1,RES
XXX1: DJNZ BRI,SEQ1
LOOP0: Delay_d100s 2 ;Black -> Yellow 2 min (351/100s 256 ~ 15 min)
SetColor BRI,BRI,ZERO
CJNE R18,0,XXX2,RES
XXX2: IJNZ BRI,LOOP0
SER BRI
LOOP1: Delay_d100s 1 ;Yellow -> Red 1 min
SetColor FULL,BRI,ZERO
CJNE R18,0,XXX3,RES
XXX3: DJNZ BRI,LOOP1
WFI ;wait for pin change
SEQ2: Delay_d100s 1 ;Red -> Yellow 1 min
SetColor FULL,BRI,ZERO
CJNE R18,0,XXX4,RES
XXX4: DJNZ BRI,SEQ2
SER BRI
LOOP3: Delay_d100s 2 ;Yellow -> Black 2 min
SetColor BRI,BRI,ZERO
CJNE R18,0,XXX5,RES
XXX5: DJNZ BRI,LOOP3
LOOP4: Delay_d100s 1 ;Black -> Blue 1 min
MOV R2,BRI ;копируем
LSR R2 ;делим на 2 сдвигом вправо
SetColor ZERO,ZERO,R2
CJNE R18,0,XXX6,RES
XXX6: IJNZ BRI,LOOP4
WFI ;wait for pin change
RJMP SEQ1
Или можно еще как то упростить?
Re: Attiny13 : 3х канальный ШИМ по внешниму прерыванию
Добавлено: Пт апр 27, 2012 08:24:31
wixa
Alexeyslav писал(а):от идеи в голове, до конечной реализации
Этому процессу здорово помогает принцип
черного ящика.
Ну и само собой способность досконально представить как работает микроконтроллер, для этого даже не нужно ничего заучивать - можно по даташиту пройтись пальчиком. Так раз десять пройдешь а в 11-й уже не потребуется - все будет в памяти.
И когда в тупик заходишь, слишком сложно становится - нужно разбивать на части и грызть их в отдельности. Уметь смотреть программу на разных уровнях детализации.
Прочитал, но понял что надо вникать.... сразу идею понять сложно..... Или я еще не проснулся

Но за советы спасибо

Re: Attiny13 : 3х канальный ШИМ по внешниму прерыванию
Добавлено: Пт апр 27, 2012 08:47:28
Engineer_Keen
wixa писал(а):Немного раскинул мозгами, и решил проблему с CJNE и ошибкой

Макрос теперь выглядит так:
Код: Выделить всё
.macro CJNE
CPI @0,@1
BREQ @2
RJMP @3
.endm
В принципе мысль верная, я просто использую другой макрос - CJEQ (Compare and Jump if EQuivalent), там только нет команды RJMP. Дело в том, что где-то может понадобится этот-же макрос без RJMP, и его туда уже не вставишь. Но ни кто не мешает сделать например макросы с RJMP и без него и назвать их например CJNE и CJNER (CJEQ-CJEQR), это ограничено только фантазией программиста.
wixa писал(а):Или можно еще как то упростить?
Можно конечно весь цикл запихать в макросы (один с увеличением счетчика, другой с уменьшением), тогда вместо
Код: Выделить всё
SEQ1: Delay_d100s 1 ;Blue -> Black 1 min
MOV R2,BRI ;копируем
LSR R2 ;делим на 2 сдвигом вправо
SetColor ZERO,ZERO,R2
CJNE R18,0,XXX1,RES
XXX1: DJNZ BRI,SEQ1
можно будет написать что-то вроде
Код: Выделить всё
SEQ1: INCREMENT_AND_DELAY 1,ZERO,ZERO,R2 ;delay,R,G,B
Однако не стоит сразу увлекаться макросами до такой степени, можно что-то где-то пропустить или ошибиться, а такие большие вложенные макросы могут затруднить отладку. Например в том-же протеусе во время выполнения макроса указатель не переходит по его строкам, а стоит в том месте программы, где макрос был вызван, и отследить ход программы можно только по изменению регистров.
Re: Attiny13 : 3х канальный ШИМ по внешниму прерыванию
Добавлено: Пт апр 27, 2012 08:59:45
wixa
CJEQ (Compare and Jump if EQuivalent)
- он будет выглядеть вот так?
А циклы будут такого вида:
Код: Выделить всё
SEQ1: Delay_d100s 1 ;Blue -> Black 1 min
MOV R2,BRI ;копируем
LSR R2 ;делим на 2 сдвигом вправо
SetColor ZERO,ZERO,R2
CJQE R18,0,RES
DJNZ BRI,SEQ1
или так:
Код: Выделить всё
SEQ1: Delay_d100s 1 ;Blue -> Black 1 min
MOV R2,BRI ;копируем
LSR R2 ;делим на 2 сдвигом вправо
SetColor ZERO,ZERO,R2
CJQE R18,0,XX1
RJMP RES
XXX1: DJNZ BRI,SEQ1
-?