Dobrý den,
Mám na Vás prosbu. Dostal se mi pod ruku ATmega128, a tak se mi naskytla možnost si s ním trochu pohrát, než ho budu muset vrátit. Jsem student, proto nemám moc financí, abych si tento modul mohl pořídit, a i kdybych si pořídil, tak bych ho dlouho nepoužíval. Mikroprocesorová technika je pěkná věc, ale mě osobně více baví mechanika a elektronika více(hlavně ve škole programování mikroprocesorů nemám rád.) Mám zadaný domácí úkol, který musím v úterý odprezentovat na tomto modulu při jeho vrácení. Rád bych od Vás dostal rady, popřípadě napsaný programu. Mým úkolem je zobrazit čas na tomto displeji. Nemusí být použitá klávesnice! Displej je EL1602A 2 řádky a 16 sloupců (dále jen 2x16). Vedle procesoru ATmega128 je IO(zda se nemýlím) HD44780, tím by měl být řízený displej. K času. Nemusí ukazovat aktuální čas. Má ukazovat někde na displeji sekundy a minuty(hodiny jsou bonus). Při 60 sekundách musí dojít ke změně minut a sekundy se musí vynulovat. Po překročení 60 minut se musí minuty i sekundy vynulovat…Program musí být napsaný v programovacím jazyce assembler. Já osobně používám AVR studio 4 a PKDesign AVR ISP programmer. Bylo mi ve škole řečeno, že tento mikroprocesor je na frekvenci 14745600Hz. Povedlo se mi zobrazit na displeji slovíčko pokus, které bliká(zdrojový kód níže, abych jen nežádal a sám se nesnažil něco udělat.)Jenže můj hlavní kámen úrazu je to, že umím naprogramovat pouze pauzu odčítaním proměnných, a ta není přesná. Máme mít řešenou pauzu pomocí TIM0_OVF, kterému ani po přečtení datasheetu, ani jiných stránek, které to yvsvětlují nepochopil. Takže k jádru věci. Rád bych vás poprosil o podprogram, který mi zařídí tuto pauzu, popř. program celý, jestli by byl někdo tak laskavý. Mnoho podprogramů jsem použil od prácí mých spolužáků, takže někde ani nevím, proč to tam je.
Děkuji předem všem, kdo mi podají pomocnou ruku! Děkuji moc!
Kod vypsání na displej pokus s nepřesným zpožděním odečítaním proměnných:
;Ladislav
;15.4.2016
.NOLIST
.include “m128def.inc”
.LIST
.DEF NulReg = r0
.DEF Stat = r1
.DEF Tmp = r16
.DEF Dl1 = r17
.DEF Dl2 = r18
.DEF LCDreg = r19
;datový segment
.DSEG
.ORG 0x0110
Buf4s: .byte 0x04
;programový segment
.CSEG
.ORG 0x0000
jmp Reset ;
Reset: ldi Tmp, low(RAMEND)
out SPL, Tmp
ldi Tmp, high(RAMEND)
out SPH, Tmp
ldi Tmp, 0xFF
out DDRD, Tmp
clr NulReg
out PortD, NulReg
out PortB, NulReg
jmp main
; nastaveni portu B na vystupni
PB_O: ldi Tmp, 0xFF
out DDRB, Tmp
ret
pause:
push Tmp
ldi Tmp, 200
pau1: call pause_500us
dec Tmp
brne pau1
pop Tmp
ret
;pauza 1s
pause_1s:
rcall pause_100ms
rcall pause_100ms
rcall pause_100ms
rcall pause_100ms
rcall pause_100ms
rcall pause_100ms
rcall pause_100ms
rcall pause_100ms
rcall pause_100ms
rcall pause_100ms
ret
; pauza 100ms
pause_100ms:
rcall pause_10ms
rcall pause_10ms
rcall pause_10ms
rcall pause_10ms
rcall pause_10ms
rcall pause_10ms
rcall pause_10ms
rcall pause_10ms
rcall pause_10ms
rcall pause_10ms
ret
; pauza 10ms
pause_10ms:
rcall pause_1ms
rcall pause_1ms
rcall pause_1ms
rcall pause_1ms
rcall pause_1ms
rcall pause_1ms
rcall pause_1ms
rcall pause_1ms
rcall pause_1ms
rcall pause_1ms
ret
; pauza 1ms
pause_1ms:
rcall pause_500us
rcall pause_500us
ret
; pauza 500us
pause_500us:
ldi Dl1, 10 ; Nastav konstanty pro 05 ms
dly2: ldi Dl2, 240
dly1: dec Dl2 ; Dekrementuj Dl2 dokud neni nulovy
brne dly1
dec Dl1 ; Dekrementuj Dl1 dokud neni nulovy
brne dly2
ret
; vyslani znaku na displej
LCD_znak:
push Tmp
in Tmp, PortD
andi Tmp, 0b11100000 ; E=RW=RS=0
ori Tmp, 0b00000100 ; RS=1…data
out PortD, Tmp
nop
out PortB, LCDreg ;PortB=data
nop
ori Tmp, 0b00010000 ;E=1 potv. plat. dat
out PortD, Tmp
nop
andi Tmp, 0b11100000 ;E=0 zrus. plat. dat
out PortD, Tmp
call pause_1ms
pop Tmp
ret
;Ridici signaly pro LCD displej:
; RS…PORTD.2
; R/W…PORTD.3
; E…PORTD.4
;
;Vyslani povelu na displej
LCD_povel:
push Tmp
in Tmp, PortD
;E=0…zrus plat.dat
;RW=0…Write
;RS=0…povel
andi Tmp, 0b11100000
out PortD, Tmp
nop
out PortB, LCDreg;PortB=povel
nop
ori Tmp, 0b00010000;E=1(potvrdit platnost dat)
out PortD, Tmp
nop
andi Tmp, 0b11100000;E=0(zrusit platnost dat)
out PortD, Tmp
call pause_1ms
pop Tmp
ret
;inicializace displeje
Disp_init:
call PB_O
call pause_500us
ldi LCDreg, 0b00111000 ; Set, 8bit data, 2linky, 5x7
call LCD_povel
call pause_1ms
ldi LCDreg, 0b00000010 ; kurzor na prvni pozici
call LCD_povel
call pause_1ms
ldi LCDreg, 0b00000001 ; vymazat displej
call LCD_povel
call pause_1ms
ldi LCDreg, 0b00000110 ; posouvani kurzoru
call LCD_povel
call pause_1ms
ldi LCDreg, 0b00001110 ; zapnut displej, kurzor a blikani
call LCD_povel
call pause_1ms
ret
;pauza
Cekej:
call pause
ret
;vstupni retezec na displej
Print_horni_radek:
call Disp_init
call pause
prnt2:
lpm LCDreg, Z+
cpi LCDreg, 0
brne prnt1
ret
prnt1:
call LCD_znak
rjmp prnt2
Print_dolni_radek:
ldi LCDreg, 0b11000000;nast. adr. DD RAM 0x40(adresa 1.bajtu ve 2.radku)
call LCD_povel
rjmp prnt2
;programova smycka
main:
ldi ZL, low(Text1 * 2)
ldi ZH, high(Text1 * 2)
call Print_horni_radek
ldi ZL, low(Text2 *2)
ldi ZH, high(Text2 * 2)
call Print_dolni_radek
call pause_1s
ldi ZL, low(Text3 *2)
ldi ZH, high(Text3 * 2)
call Print_horni_radek
ldi ZL, low(Text4 * 2)
ldi ZH, high(Text4 * 2)
call Print_dolni_radek
call pause_1s
rjmp main
Text1: .DB "pokus 4 "
.DB 0x00, 0x00
Text2: .DB "pokus 3 "
.DB 0x00, 0x00
Text3: .DB "pokus 2 "
.DB 0x00, 0x00
Text4: .DB "pokus "
.DB 0x00, 0x00
Příloha mi zlobila, takže přikládám odkaz na ten displej:
imgur.com/s1ied6o