Доброе время суток.
Неподскажите как можно реализовать прерывание .Незнаю с чего начать,по входу получаю
импульсы от шестерни,при сравнении счотчика должны включаться порта.И это должно быть
переменным те. колличество прерываний и место по сравнению .Проблемма для меня серъезная
регистров нехватает.!!!
АТмега8 Assembler
Заранее благодарю за вашу помощ.
Здравствуйте. Лучше привести конкретный пример
-эскиз схемы
-код
Навскидку. Импульсы от шестерни подать на вход внешнего прерывания, допустим, INT0. В RAM предварительно сформирована таблица сравнений с привязкой каждого элемента оной к управлению портами. Каждое прерывание наращивает счетчик, значение которого сравнивается с табличными значениями и, при совпадении, соответственно управляются порты.
Zahler_vor:
sbis PINC,0
rjmp Zahler_vor
inc r16
brne wait
stop1: sbic PINC,0
rjmp stop1
inc r24
rcall lcdGoto
rcall lcdZahl
ret
wait: rjmp Zahler_vor
;------------------------------------------------------------------------------
; WegZähler Manuel-rück
;------------------------------------------------------------------------------
Zahler_rück:
sbis PINC,0
rjmp Zahler_rück
inc r16
brne wait1
stop2: sbic PINC,0
rjmp stop2
dec r24
rcall lcdGoto
rcall lcdZahl
ret
wait1: rjmp Zahler_rück
;---------------------------------------------------------------------------
это сам счотчик движения вперед или назад порт D у меня занят LCD
r24 счотчик регистр
ну а дальше
cp r24,r23
breq portB3_on
cp r24,r22
breq portB3_off
rjmp Zäler_vor
portB3_on:sbi PORTB,3
rjmp Zäler_vor
breq portB3_off: cbi PORTB,3
rjmp Zäler_vor
и так далее.
Принцип напоминает кодовый замок, это должен быть сварочный автомат, где я задаю
откуда варить где прерваться, круглые поверхности обваривать.
Подправил сообщение - выделил код. Радиодед.
Здравствуйте. Вам нужно реализовать автомат по принципу "унитаза - пока один не встанет, другой не сядет", т.е. пока не выполнится текущий цикл, следующего не будет.
Отсюда делаю следующие выводы
-все подходящие прерывания заняты под обслуживание индикатора
-у автомата должно быть начало и конец
-вся работа предполагается от импульсов(назовем их шагами), поступающих от датчика, установленного на шестерне
-предварительно задается программа работы автомата в шагах, которая запоминается в EEPROM.
Посмотрите этот набросок кода. Правильно ли понята задача? .INCLUDE "8535def.inc"
.ESEG
.ORG $60
TB:
.DB 20,40 ; через 20 шагов после начала включить, а через 40 шагов выключить
.DB 80,133 ; через 80 шагов после начала включить, а через 133 шага выключить
TB_END:
.CSEG
RESET:
RJMP START ; On Reset
; .............
; .............
; .............
;*********************************************
START:
LDI R16,LOW(RAMEND)
OUT SPL,R16
LDI R16,HIGH(RAMEND)
OUT SPH,R16
CLR R17
SER R16
OUT PORTB,R17
OUT DDRB,R16 ; Инициализация порта B
OUT PORTD,R17
OUT DDRD,R16 ; Инициализация порта D
OUT PORTC,R16
OUT DDRC,R16 ; Инициализация порта C
NOP
OUT DDRC,R17
;***********************************************
; здесь нужно переписать из EEPROM в ОЗУ всю временную диаграмму в шагах
;
;***********************************************
CLR R24 ; счетчик шагов 0...255
LDI XH,HIGH(TB)
LDI XL,LOW(TB)
LDI YH,HIGH(TB_END)
LDI YL,LOW(TB_END)
END:
SBIS PINC,0
RJMP END ; стоим и ждем конец импульса
BEGIN:
SBIC PINC,0
RJMP BEGIN ; стоим и ждем начало импульса
; дождались
INC R24
LD R23,X
CP R23,R24
BRNE END
IN R22,PINB
LDI R21,$08
EOR R22,R21
OUT PORTB,R22
ADIW XL,1
CP XL,YL
CPC XH,YH
BRNE END ; еще не дошли до конца
RJMP START ; усё
;*********************************************
Я сильно признателен ,что мне ещо хотят помоч,нодело в том ,что всё это должно быть
переменным(количество включений и место)может я чегото недопанимаю в этом коде,но
это все фиксированные значения.Можно-ли создавать таблицу без повторного прошивания.Уменя
есть одна идея но я незнаю как это реализовать.Начало выглядит так
пишу в EEPROM
waitE: sbic EECR,1
rjmp waitE
ldi r17,0x00 ; счотчик памяти
ldi r16,0x00
out EEARH,r17
out EEARL,r16
out EEDR,r25 ;копирование регистра в EEPROM
sbi EECR,2
sbi EECR,1
waitF: sbic EECR,1
rjmp waitF
это я записал,при последующей записи счотчик памяти увеличивать на 1
и также потом читать.
Почему "фиксированные" значения? Программа написана так, что вся работа ведется из RAM с циклической перезагрузкой из EEPROM. Но, это было написано к примеру. Можно ведь менять(подбирать, оптимизировать) в RAM без записи в EEPROM и только после получения положительного результата осуществить запись в EEPROM. Ведь не зря адреса RAM и EEPROM сделаны одинаковыми.
Интересно, откуда Вы, если не секрет. :?:
Секретов нет Германия. Немецкого образования у меня нет(русское ремонт телерадиоаппаратуры) вот занимаюсь самообразованием.
Я новичок в этом деле, но как я понимаю мне надо сделать кучу таблиц, а потом выбирать подходящую по номеру, и написать таблицу с прерываниями на листе. Я просто думал это реализовать как китайская игрушка, нажал на различные кнопки, а потом она делает то, что я там нажимал. Или как я понял наделать таблиц по одному зубу ,а потом выбирать какой таблицей начать, а какой закончить и т.д. опять может регистров не хватить или я смотрю на яйцо с другой стороны?
Эту коробку уже собрал всё работает.
Последняя функция заинтересовала мне кажется как на кодовом замке принцип написания тот же.
Если время есть не могли-бы поставить на путь истинный.
Вам нужно разделить задачи
- управления автоматом по таблице, находящейся в области памяти от "TB......TB_END"
- создания собственно таблиц управления для каждой детали, для чего должна быть возможность пошагового управления автоматом в ручном режиме; должен быть предусмотрен способ передачи готовой таблицы в хранилище
- хранения созданных таблиц, их нумерацию и способ пересылки в память управления автоматом
Естественно, необходимо обеспечить начальное положение как автомата, так и обрабатываемой детали.
У меня всё есть .Ручное передвижение,включение сварки с задержкой на включения каруселя,
конечная остановка,откат назад,и в заключении последние 5 зубев,что вперёд, датчик нуля или счотчик нуль,обнулние общего счотчика .Всё это переменные.
Мыслите Вы правильно,я просто хотел в меню лсд сделать место для 10таблиц ,а таблицы должны
писаться или пеписываться через кноки управления ,а не через программатор.хранить и записывать в EPPROM идея прекрасная .Я был-бы доволен если после каждого включения на кнопках набирать таблицу или изменять,но она должна-быть ручная.
Возможно ли это или только составить таблицы основного пользования ,а потом выбирать.
Я хотел вставить весь код что у меня на данный момент актуальный ,но администратор непропускает,как текст чересчур длинно.
Даже заархивированный не пропускает? Ничего себе код у Вас. :shock:
Нет он пишет sax файлы блокирует администратор и txt файлы.Хорошо попробую напрямую.
Только у меня немного эксклюзивная программа пишет в Assembler GNU не совсем как студия.
Со студией у меня проблема первая английский вторая не могу найти программатор.
;-------------------------------------------------------------------------
; Titel : Sweisautomat
;-------------------------------------------------------------------------
; Funktion :
; Schaltung :
;-------------------------------------------------------------------------
; Prozessor : ATmega8
; Takt : 4 MHz
; Sprache : Assembler (GNU)
; Datum : 9.02.2010
; Version : 90210
; Autor : Haag Jörg
; Programmer:
; Port :
;-------------------------------------------------------------------------
;-------------------------------------------------------------------------
;
.include "avr.h"
begin:
rjmp main ; 1 POWER ON RESET
reti ; 2 Int0-Interrupt
reti ; 3 Int1-Interrupt
reti ; 4 TC2 Compare Match
reti ; 5 TC2 Overflow
reti ; 6 TC1 Capture
reti ; 7 TC1 Compare Match A
reti ; 8 TC1 Compare Match B
reti ; 9 TC1 Overflow
reti ;10 TC0 Overflow
reti ;11 SPI, STC Serial Transfer Complete
reti ;12 UART Rx Complete
reti ;13 UART Data Register Empty
reti ;14 UART Tx Complete
reti ;15 ADC Conversion Complete
reti ;16 EEPROM Ready
reti ;17 Analog Comparator
reti ;18 TWI (I²C) Serial Interface
reti ;19 Store Program Memory Ready
;------------------------------------------------------------------------
; Initialisierungen
;------------------------------------------------------------------------
main:
;--- Stack Initialisierung ---
ldi r16,hi8(RAMEND)
out SPH,r16
ldi r16,lo8(RAMEND)
out SPL,r16
;-------------------------------------------------------------
rcall lcdInit
ldi r30,lo8(text-begin)
ldi r31,hi8(text-begin)
rcall lcdString
rcall lcdLine2
ldi r30,lo8(text0-begin)
ldi r31,hi8(text0-begin)
rcall lcdString
rcall myWait_ms_v
rcall lcdInit
ldi r30,lo8(mail-begin)
ldi r31,hi8(mail-begin)
rcall lcdString
rcall lcdLine2
ldi r30,lo8(mail0-begin)
ldi r31,hi8(mail0-begin)
rcall lcdString
;--------------------------------------------------------------
ldi r24,0 ;Lade Registr r24 (wegzahler) mit 0 (Anfang)
ldi r23,20 ;Lade Registr r23 (zeitverzogerung)
ldi r25,38 ;Lade Registr r25 (gesamt_wegzahler) endgrenze
;----------------------------------------------------------------
cbi DDRC,0 ;Eingang Wegzahler (Sensor)
sbi PORTC,0
cbi DDRC,1 ;Taster (-) (Zurück)
sbi PORTC,1
cbi DDRC,2 ;Taster Stop
sbi PORTC,2
cbi DDRC,3 ;Taster Start
sbi PORTC,3
cbi DDRC,4 ;Taster (+) (Vor)
sbi PORTC,4
cbi DDRC,5
sbi PORTC,5
cbi DDRB,5 ;Engang Null Position (Anfang) (Sensor)
sbi PORTB,5
sbi DDRB,0 ;Ausgang Motor rückwerts
sbi DDRB,1 ;Ausgang Stopanzeige
sbi DDRB,2 ;Ausgang Sweisapparat ON-OFF
sbi DDRB,3 ;Ausgang Motor vorwerts
sbi DDRB,4
;-----------------------------------------------------------------------
;------------------------------------------------------------------------
; Hauptprogramm-Schleife
;------------------------------------------------------------------------
mainloop: cbi PORTB,0
cbi PORTB,1
cbi PORTB,2
cbi PORTB,3
sbis PINC,2
rjmp S_start ; ..
rjmp mainloop ; Sprung zum Beginn der Hauptprogrammschleife
text : .string " Service Tel. "
text0 : .string " 09404/649762 "
mail : .string " Service EMail "
mail0 : .string " haag8@msn.com "
start : .string "<<< Weg >>> "
start0 : .string " START "
stop_v : .string " Weg >>> "
stop0 : .string " STOP "
stop_r : .string "<<< Weg "
g_weg : .string "<< Ges-Weg >> "
zeit_mot: .string "Mot-ON Zeitverz. "
zeiger : .string "<<< >>> "
;--------------------------------------------------------------------------------
; Start-Stop Steuerung
;--------------------------------------------------------------------------------
S_start:
sbi PORTB,1
cbi PORTB,0
cbi PORTB,2
cbi PORTB,3
sbis PINC,2
rjmp ges_weg
sbis PINC,3
rjmp A_start_vor
sbis PINC,4
rjmp m_vor
sbis PINC,1
rjmp m_ruck
rcall lcdGoto
rcall lcdZahl
rjmp S_start
;-------------------------------------------------------------------------------
; GesamtesWeg
;-------------------------------------------------------------------------------
ges_weg:
rcall lcd_weg_anzeige
rjmp ges_weg_
ges_weg_:
rcall lcdGoto_g
rcall lcdZahl_g
sbic PINC,2
rjmp A_stop
sbis PINC,3
rjmp O_stellung
cpi r25,99
breq ges_weg_rück
sbis PINC,4
rcall Zahler_vor_g
ges_weg_rück:
cp r24,r25
breq ges_weg_
sbis PINC,1
rcall Zahler_rück_g
rjmp ges_weg_
;------------------------------------------------------------------------------
; Wegregistr löschen
;------------------------------------------------------------------------------
O_stellung: ldi r24,0
rcall lcd_Start
rcall lcdGoto
rcall lcdZahl
O_stellung_:sbis PINC,3
rjmp O_stellung_
sbic PINC,2
rjmp mot_z_verzogerung_
rjmp S_start
;------------------------------------------------------------------------------
; Motoreinschaltverzogerung
;------------------------------------------------------------------------------
mot_z_verzogerung_:
rcall lcd_mot_zeit
rcall lcdGoto_mot
rcall lcdZahl_mot
mot_z_verzogerung:
rcall lcdGoto_mot
rcall lcdZahl_mot
sbis PINC,2
rjmp A_stop
sbis PINC,4
rcall Zahler_mot_zeit_vor
cpi r23,1
breq mot_z_verzogerung
sbis PINC,1
rcall Zahler_mot_zeit_rück
rjmp mot_z_verzogerung
lcd_mot_zeit:
rcall lcdInit
ldi r30,lo8(zeit_mot-begin)
ldi r31,hi8(zeit_mot-begin)
rcall lcdString
rcall lcdLine2
ldi r30,lo8(zeiger-begin)
ldi r31,hi8(zeiger-begin)
rcall lcdString
ret
;-------------------------------------------------------------------------------
; Start-Stop Ausgänge
;----------------------------------------------------------------------------
A_start_vor:
rcall lcd_Stop
rcall lcdGoto
rcall lcdZahl
A_start_vor_:
cp r24,r25
breq A_start_rück
sbi PORTB,2
cbi PORTB,1
cbi PORTB,3
rcall mot_v
A_start_vor_1:
sbi PORTB,2
cbi PORTB,1
sbi PORTB,3
sbis PINC,2
rjmp A_stop
cp r24,r25
breq umschaltverzogerung
rcall Zahler_vor
rjmp A_start_vor_1
mot_v:
push r16
ldi r16,1
mot_3_v:
push r16
mov r16,r23
mot_2_v:
push r16
ldi r16,155
mot_1_v:
dec r16
brne mot_1_v
pop r16
dec r16
brne mot_2_v
pop r16
dec r16
brne mot_3_v
pop r16
dec r16
brne mot_v
ret
;-----------------------------------------------------------------------------
; umschaltverzogerung
;----------------------------------------------------------------------------
umschaltverzogerung:
cbi PORTB,2
cbi PORTB,3
cbi PORTB,1
sbis PINC,2
rjmp A_stop
rcall lcd_Stop_a
rcall lcdGoto
rcall lcdZahl
rcall myWait_ms_v
rjmp A_start_rück
myWait_ms_v:
push r16
ldi r16,2
myWait_ms_3_v:
push r16
ldi r16,20
myWait_ms_2_v:
push r16
ldi r16,255
myWait_ms_1_v:
dec r16
brne myWait_ms_1_v
pop r16
dec r16
brne myWait_ms_2_v
pop r16
dec r16
brne myWait_ms_3_v
pop r16
dec r16
brne myWait_ms_v
ret
;-----------------------------------------------------------------------------
A_start_rück:
rcall lcd_Stop_a
rcall lcdGoto
rcall lcdZahl
A_start_rück_:
sbi PORTB,0
cbi PORTB,1
cbi PORTB,2
cbi PORTB,3
sbis PINC,2
rjmp A_stop
cpi r24,5
brcs sensor_abfrage
weiter:cpi r24,0
breq A_stop
rcall Zahler_rück
rjmp A_start_rück_
sensor_abfrage:
sbis PINB,5
rjmp wegzahler_loschen
rjmp weiter
wegzahler_loschen:
ldi r24,0
rjmp A_stop
;---------------------------------------------------------------------------------
A_stop:
sbi PORTB,1
cbi PORTB,0
cbi PORTB,2
cbi PORTB,3
sbis PINC,3
rjmp A_stop
rcall lcd_Start
rjmp S_start
;-----------------------------------------------------------------------------
; Manuel Vor
;---------------------------------------------------------------------------
m_vor:
cp r24,r25
breq gr_m_vor
rcall lcdGoto
rcall lcdZahl
cbi PORTB,0
cbi PORTB,1
cbi PORTB,2
sbi PORTB,3
sbic PINC,4
rjmp A_stop
rcall Zahler_vor
rjmp m_vor
;-------------------------------------------------------------------------------
gr_m_vor: cbi PORTB,3
rcall lcd_gr_m_vor
rcall lcdGoto
rcall lcdZahl
end_gr_m_vor:
sbis PINC,4
rjmp end_gr_m_vor
rjmp S_start
lcd_gr_m_vor:
rcall lcdInit
ldi r30,lo8(stop_r-begin)
ldi r31,hi8(stop_r-begin)
rcall lcdString
rcall lcdLine2
ldi r30,lo8(start0-begin)
ldi r31,hi8(start0-begin)
rcall lcdString
ret
;----------------------------------------------------------------------------------
; Manuel Rück
;---------------------------------------------------------------------------------
m_ruck:
rcall lcdGoto
rcall lcdZahl
sbi PORTB,0
cbi PORTB,1
cbi PORTB,2
cbi PORTB,3
sbic PINC,1
rjmp A_stop
rcall Zahler_rück
rjmp m_ruck
;---------------------------------------------------------------------------
;---------------------------------------------------------------------------
; WegZähler Manuel vor
;---------------------------------------------------------------------------
Zahler_vor:
sbis PINC,0
rjmp Zahler_vor
inc r16
brne wait
stop1: sbic PINC,0
rjmp stop1
inc r24
rcall lcdGoto
rcall lcdZahl
ret
wait: rjmp Zahler_vor
;------------------------------------------------------------------------------
; WegZähler Manuel-rück
;------------------------------------------------------------------------------
Zahler_rück:
sbis PINC,0
rjmp Zahler_rück
inc r16
brne wait1
stop2: sbic PINC,0
rjmp stop2
dec r24
rcall lcdGoto
rcall lcdZahl
ret
wait1: rjmp Zahler_rück
;---------------------------------------------------------------------------
; WegZähler Manuel-vor
;------------------------------------------------------------------------
Zahler_vor_g:
sbic PINC,4
rjmp Zahler_vor_g
inc r16
brne wait_c
stop_c: sbis PINC,4
rjmp stop_c
inc r25
ret
wait_c: rjmp Zahler_vor_g
;------------------------------------------------------------------------------
; WegZähler Manuel-rück
;------------------------------------------------------------------------------
Zahler_rück_g:
sbic PINC,1
rjmp Zahler_rück_g
inc r16
brne wait_d
stop_d: sbis PINC,1
rjmp stop_d
dec r25
ret
wait_d: rjmp Zahler_rück_g
;------------------------------------------------------------------------
;------------------------------------------------------------------------
; Zeitverzogerung vor
;------------------------------------------------------------------------
Zahler_mot_zeit_vor:
sbic PINC,4
rjmp Zahler_mot_zeit_vor
inc r16
brne wait_c_mot
stop_c_mot:
sbis PINC,4
rjmp stop_c_mot
inc r23
ret
wait_c_mot: rjmp Zahler_mot_zeit_vor
;------------------------------------------------------------------------------
; Zeitverzogerung rück
;------------------------------------------------------------------------------
Zahler_mot_zeit_rück:
sbic PINC,1
rjmp Zahler_mot_zeit_rück
inc r16
brne wait_d_mot
stop_d_mot: sbis PINC,1
rjmp stop_d_mot
dec r23
ret
wait_d_mot: rjmp Zahler_mot_zeit_rück
;------------------------------------------------------------------------
;------------------------------------------------------------------------
; LCD Start
;-----------------------------------------------------------------------
lcd_Start:
rcall lcdInit
ldi r30,lo8(start-begin)
ldi r31,hi8(start-begin)
rcall lcdString
rcall lcdLine2
ldi r30,lo8(start0-begin)
ldi r31,hi8(start0-begin)
rcall lcdString
ret
;--------------------------------------------------------------------------------
; LCD automat vor ablauf
;---------------------------------------------------------------------------------
lcd_Stop:
rcall lcdInit
ldi r30,lo8(stop_v-begin)
ldi r31,hi8(stop_v-begin)
rcall lcdString
rcall lcdLine2
ldi r30,lo8(stop0-begin)
ldi r31,hi8(stop0-begin)
rcall lcdString
ret
;--------------------------------------------------------------------------------
; LCD automat rück ablauf
;---------------------------------------------------------------------------------
lcd_Stop_a:
rcall lcdInit
ldi r30,lo8(stop_r-begin)
ldi r31,hi8(stop_r-begin)
rcall lcdString
rcall lcdLine2
ldi r30,lo8(stop0-begin)
ldi r31,hi8(stop0-begin)
rcall lcdString
ret
;--------------------------------------------------------------------
; LCD Strecke
;--------------------------------------------------------------------
lcd_weg_anzeige:
rcall lcdInit
ldi r30,lo8(g_weg-begin)
ldi r31,hi8(g_weg-begin)
rcall lcdString
ret
;--------------------------------------------------------------------
; myWait_ms - Warte-Routine für x-Millisekunden
; ein Millisekundenzyklus dauert 1,052 ms
; PE: r16 = Anzahl der zu wartenden Milisekunden
; PA: r16 = 0
;--------------------------------------------------------------------
myWait_ms:
push r16
ldi r16,1
myWait_ms_3:
push r16
ldi r16,5
myWait_ms_2:
push r16
ldi r16,75
myWait_ms_1:
dec r16
brne myWait_ms_1
pop r16
dec r16
brne myWait_ms_2
pop r16
dec r16
brne myWait_ms_3
pop r16
dec r16
brne myWait_ms
ret
;-----------------------------------------------------------------------------
lcdOut: mov r17, r16
swap r17
andi r16, 0b11110000
or r16,r18
andi r17, 0b11110000
or r17,r18
out PORTD, r16
rcall lcdEnable
out PORTD, r17
rcall lcdEnable
rcall lcdWait
ret
;------------------------------------------------------------------------
;-----------------------------------------------------------------------------
lcdData:
ldi r18,0b0000100 ; RS = hi
rjmp lcdOut
ret
;------------------------------------------------------------------------
;--------------------------------------------------------------------
; Warte-Routine für 5 ms
; die Routine wartet inclusive Aufruf 5,031 ms
;--------------------------------------------------------------------
lcdWait:
ldi r16,2
rcall myWait_ms
ret
;------------------------------------------------------------------------
;-----------------------------------------------------------------------------
lcdCmd: ldi r18,0b0000000 ; RS = lo
rjmp lcdOut
ret
;------------------------------------------------------------------------
;-----------------------------------------------------------------------------
lcdOn:
ldi r16, 0b00001100
rcall lcdCmd
rcall lcdWait
ret
;------------------------------------------------------------------------
;-----------------------------------------------------------------------------
lcdClear:
ldi r16, 0b00000001 ; Display löschen
rcall lcdCmd
rcall lcdWait
ret
;------------------------------------------------------------------------
;-----------------------------------------------------------------------------
lcdOff:
ldi r16, 0b00001000
rcall lcdCmd
rcall lcdWait
ret
;------------------------------------------------------------------------
;-----------------------------------------------------------------------------
lcdEnable:
sbi PORTD, 3 ; Enable high
nop ; kurz warten
nop
nop
cbi PORTD, 3 ; Enable wieder low
ret
;------------------------------------------------------------------------
;-----------------------------------------------------------------------------
lcdInit:
sbi DDRD,2 ; LCD RS = OUT
sbi DDRD,3 ; LCD E = OUT
sbi DDRD,4 ; LCD D4 = OUT
sbi DDRD,5 ; LCD D5 = OUT
sbi DDRD,6 ; LCD D6 = OUT
sbi DDRD,7 ; LCD D7 = OUT
cbi PORTD,2 ; LDC RS = Low
; warte bis PowerUp
ldi r18,20
powerUp:
rcall lcdWait
dec r18
brne powerUp ; Power-Up Wartezyklus min 30 ms
; sende Resetsequenz kompatibel zu HD44780 Industriestandard
ldi r16,0b00110000 ; Reset-Sequenz Teil 1
out PORTD,r16
rcall lcdEnable ; Enable-Impuls
rcall lcdWait
ldi r16,0b00110000 ; Reset-Sequenz Teil 2
out PORTD,r16
rcall lcdEnable ; Enable-Impuls
rcall lcdWait
ldi r18,100 ; Wartezyklus bei RESET LCD min 100 µs
resetLCD:
nop
nop
nop
dec r18
brne resetLCD
ldi r16,0b00110000 ; Reset-Sequenz Teil 3
out PORTD,r16
rcall lcdEnable ; Enable-Impuls
rcall lcdWait
rcall lcdOn
; sende init 1
ldi r16, 0b00100000 ; 4 Bit Modus aktivieren
out PORTD, r16
rcall lcdEnable ; Enable-Impuls
rcall lcdWait
ldi r16, 0b00101000
rcall lcdCmd ; Function Set 4 Bit, 2 Zeilen, 5x7
rcall lcdOff
rcall lcdClear
ldi r16, 0x06
rcall lcdCmd ; Entry Mode Set, increase+shifted
rcall lcdOn
ret
;------------------------------------------------------------------------
;------------------------------------------------------------------------
; Sendet einen mit 0x00 abgeschlossenen String von Flash an UART
; PE: Z=StartAdresse
;------------------------------------------------------------------------
lcdString:
push r16
push r30
push r31
lcdString1:
lpm r16,Z+
cpi r16,0
breq lcdString2
rcall lcdData
rjmp lcdString1
lcdString2:
pop r31
pop r30
pop r16
ret
;-----------------------------------------------------------------------------
lcdHome:
ldi r16, 0b00000010 ; Display Cursor HOME
rcall lcdCmd
rcall lcdWait
ret
;------------------------------------------------------------------------
;-----------------------------------------------------------------------------
lcdLine1:
ldi r16, 0b10000000 ; DRAM auf Adresse 0x00
rcall lcdCmd
rcall lcdWait
ret
;-----------------------------------------------------------------------------
lcdLine2:
ldi r16, 0b11000000 ; DRAM auf Adresse 0x40
rcall lcdCmd
rcall lcdWait
ret
;------------------------------------------------------------------------
;-----------------------------------------------------------------------------
; Goto r16 = Adresse (Zeile 1 = 0x00..0x0F, Zeile 2 = 0x40..0x4F)
lcdGoto:
ori r16, 0b10001010 ; Goto DRAM auf Adresse r16
rcall lcdCmd
rcall lcdWait
ret
;------------------------------------------------------------------------
;-----------------------------------------------------------------------------
; Goto r16 = Adresse (Zeile 1 = 0x00..0x0F, Zeile 2 = 0x40..0x4F)
lcdGoto_g:
ori r16, 0b10001011 ; Goto DRAM auf Adresse r16
rcall lcdCmd
rcall lcdWait
ret
;------------------------------------------------------------------------
;-----------------------------------------------------------------------------
; Goto r16 = Adresse (Zeile 1 = 0x00..0x0F, Zeile 2 = 0x40..0x4F)
lcdGoto_mot:
ori r16, 0b11000110 ; Goto DRAM auf Adresse r16
rcall lcdCmd
rcall lcdWait
ret
;------------------------------------------------------------------------
;------------------------------------------------------------------------
;------------------------------------------------------------------------
; wandelt ein Byte in die in die einzelnen Ziffern um (unsigned)
; PE:
; r16 binärwert (0...255)
; PA: FF 99 1
; r1 Ergebnis (einer) 5 9 1
; r2 Ergebnis (zehner) 5 9 0
; r3 Ergebnis (hunderter) 2 0 0
;------------------------------------------------------------------------
lcdZahl:
mov r1,r24 ; Zwischenspeicher und Einer-Stelle
clr r3
clr r2
hundert:
ldi r16,100 ; solange die 100 in die Restzahl (r1) passt
cp r1,r16
brlo zehner
sub r1,r16 ; 100 abziehen und
inc r3 ; Hunderter-Stelle erhöhen
rjmp hundert
zehner:
ldi r16,10 ; wie bei den Hundertern
cp r1,r16
brlo einer
sub r1,r16
inc r2
rjmp zehner
einer:
ldi r21,0x30 ; 30 hex für Zahl
; mov r16,r3
; add r16,r21 ; hunderter + 30 hex
; rcall lcdData
mov r16,r2
add r16,r21 ; zehner + 30 hex
rcall lcdData
mov r16,r1
add r16,r21 ; einer + 30 he
rcall lcdData
ret
;------------------------------------------------------------------------
;------------------------------------------------------------------------
; wandelt ein Byte in die in die einzelnen Ziffern um (unsigned)
; PE:
; r16 binärwert (0...255)
; PA: FF 99 1
; r1 Ergebnis (einer) 5 9 1
; r2 Ergebnis (zehner) 5 9 0
; r3 Ergebnis (hunderter) 2 0 0
;------------------------------------------------------------------------
lcdZahl_g:
mov r1,r25 ; Zwischenspeicher und Einer-Stelle
clr r3
clr r2
hundert_g:
ldi r16,100 ; solange die 100 in die Restzahl (r1) passt
cp r1,r16
brlo zehner_g
sub r1,r16 ; 100 abziehen und
inc r3 ; Hunderter-Stelle erhöhen
rjmp hundert_g
zehner_g:
ldi r16,10 ; wie bei den Hundertern
cp r1,r16
brlo einer_g
sub r1,r16
inc r2
rjmp zehner_g
einer_g:
ldi r21,0x30 ; 30 hex für Zahl
; mov r16,r3
; add r16,r21 ; hunderter + 30 hex
; rcall lcdData
mov r16,r2
add r16,r21 ; zehner + 30 hex
rcall lcdData
mov r16,r1
add r16,r21 ; einer + 30 he
rcall lcdData
ret
;------------------------------------------------------------------------
;------------------------------------------------------------------------
; wandelt ein Byte in die in die einzelnen Ziffern um (unsigned)
; PE:
; r16 binärwert (0...255)
; PA: FF 99 1
; r1 Ergebnis (einer) 5 9 1
; r2 Ergebnis (zehner) 5 9 0
; r3 Ergebnis (hunderter) 2 0 0
;------------------------------------------------------------------------
lcdZahl_mot:
mov r1,r23 ; Zwischenspeicher und Einer-Stelle
clr r3
clr r2
hundert_mot:
ldi r16,100 ; solange die 100 in die Restzahl (r1) passt
cp r1,r16
brlo zehner_mot
sub r1,r16 ; 100 abziehen und
inc r3 ; Hunderter-Stelle erhöhen
rjmp hundert_mot
zehner_mot:
ldi r16,10 ; wie bei den Hundertern
cp r1,r16
brlo einer_mot
sub r1,r16
inc r2
rjmp zehner_mot
einer_mot:
ldi r21,0x30 ; 30 hex für Zahl
mov r16,r3
add r16,r21 ; hunderter + 30 hex
cpi r16,0x30 ;vergleiche r16 mit 0
breq n1 ;wenn ja dann wierd gesprungen zu maske n1
rcall lcdData
n: mov r16,r2
add r16,r21 ; zehner + 30 hex
rcall lcdData
mov r16,r1
add r16,r21 ; einer + 30 he
rcall lcdData
ret
n1: ldi r16,' ' ;So lange das erste ziffer 0 ist
rcall lcdData ;wird mit leer zeichen eingefült
rjmp n
;------------------------------------------------------------------------
для делитанта я думаю неплохо.Пока она у меня самая большая .С макросами я пока не силён
r24 общий счотчик
r23 таймер задержки на карусель
r25 конечная остановка
некоторые вещи повторяются ,упрощением я пока не занимался.
Спасибо за поправку Радиодед.
Здравствуйте.
Я начал разбираться с прерываниями и возник вопрос.
Как поместить прерывание в цикл while?
вот пример:
Код:
Вот так вот...