ATmega16 zdroják v asembleru, příklad programu pro pochopení

Zdravím
Abych více pochopil princip programování atmelů tak bych potřeboval nějaký program v asembleru například registrové pole není mi jasné protože u PIC mikroktrolérů je to úplně jinak, protože jsem začínal napřed PICkama z důvodu vycházející školy v magazínu dnes už zaniklém KTE díky

:arrow_right: administrator: přejmenováno z "ATmega16 zdroják v asembleru"

Zkus si nejdříve pročíst některou z těchto knih:
[forum.mcontrollers.com/t/knihy-prace-s-mikrokontrolery-atmel/891/1).

Co se týče prográmků, tak těch můžeš nalézti hafo všude na webu
a pár se jich najde i zde na foru.

Ale abys neřek, že jen radím, tak tady máš jeden můj starší kousek
pro simulaci policejního majáku.
Není to dokonalé, ale na pochopení to doufám bude stačit.
Je dělaný pro ATTINY13.

[code]//**************************************************************************************
//*** DEFINOVÁNÍ PROCESORU ********
//**************************************************************************************
.NOLIST
.INCLUDE “tn13def.inc”
.LIST

//**************************************************************************************
//*** DEFINICE KONSTANT ********
//**************************************************************************************
.CSEG
.DEF RR=R16 ;IN OUT registr
.EQU SPCNT=0x05 ;Velikost Stacku

//**************************************************************************************
//*** DATA V EEPROM ********
//**************************************************************************************
.ESEG
.ORG 5 ;Přeskoč prvních 5 bytů (pro jistotu)
MODE: .BYTE 1 ;zobrazovaný mod
OSCI: .BYTE 1 ;kalibrace oscilatoru
//**************************************************************************************
//*** Reservace Stacku po vložení všech INCLUDE souborů ********
//**************************************************************************************
.DSEG
.ORG RAMEND-SPCNT ;Na konec paměti
STACK: .BYTE SPCNT ;reservuj paměť pro Stack

//**************************************************************************************
//*** VEKTORY PŘERUŠENÍ ********
//**************************************************************************************
.CSEG
.ORG 0 ; Vektor resetu
RJMP START

.ORG OVF0addr
RJMP INT00

//**************************************************************************************
//*** ZAČÁTEK PROGRAMU ********
//**************************************************************************************

.ORG INT_VECTORS_SIZE
//**************************************************************************************
//*** POPIS FUNKCE REGISTRU ********
//**************************************************************************************

//R3 blokování testu pinu modu
//R4 pomocná proměnná pro synchronizaci
//R5 hodnota pro č/č0
//R6 zvoleny mód
//R7

//R16 obdoba acc
//R17 obdoba bcc
//R18 odpočet milisekund

//R28,R29 segment adresy tabulky
//R30,R31 aktuální ADRESA TABULKY

START: // Nastavení portů
ldi RR,0b00010011
out DDRB,RR
ldi RR,0b00101100
out PORTB,RR

// Častavení časovače
// selected time = 1 ms (4800 ticks)
// prescaler = 64 
ldi	RR,(1<<CS01)|(1<<CS00)
out	TCCR0B,RR
ldi	RR,181
mov	r5,RR
out	TCNT0,r5
ldi	RR,(1<<TOIE0)
out	TIMSK0,RR
clr	r3
ldi	r18,100

//načteni módu z EEPROM

EEPROM_read:
sbic EECR,EEPE
rjmp EEPROM_read
ldi RR,MODE //adresa v EEPROM
out EEARL, RR
sbi EECR,EERE
in r6,EEDR

//**************************************************************************************
//*** NORMAL MODE ********
//**************************************************************************************
// Nastavení adresy tabulky
UPLOAD: mov RR,r6
cpi RR,0
breq TAB1
cpi RR,1
breq TAB2
clr RR //v případě vadné hodnoty
rjmp EEPROM_write //nastav první tabulku a skoč si ji zapsat

TAB1: ldi r28,LOW(TSVLM1) // !!! Mod načíst z EEPROM
ldi r29,HIGH(TSVLM1)
lsl r28
rol r29
movw r30,r28
sei
rjmp IMPULS1

TAB2: ldi r28,LOW(TSVLM2) // !!! Mod načíst z EEPROM
ldi r29,HIGH(TSVLM2)
lsl r28
rol r29
movw r30,r28
sei

IMPULS1:sbis PINB,3 //čekej dokud se neshodí linka
rjmp IMPULS1
ldi r18,5
LOOP1: tst r18 //5ms na zklidnění linky
brne LOOP1

ldi	r18,240			//250ms

LOOP2: tst r18
breq READT //čekej dokud neuplyne 250ms
sbic PINB,3 //nebo dokud se opětovně nenahodí linka
rjmp LOOP2

// Provoz

READT: clr r4
clr r7
lpm r18,Z+ //načtení času v ms
tst r18
brne SETB //pokud není 0, skoč dále

// Restart tabulky

RESTAR: sbic PINB,5
clr r3 // blokace se vynuluje pouze, pokud je na pinu Hi

movw	r30,r28
rjmp	READT

// Aplikace tabulky

SETB: in RR,PORTB //načtení stavu PORTB
andi RR,0b00101100 //vymazání tří bitů

lpm	r17,Z+		//load změny stavu PORTB
or	r17,RR		//aplikuj změnu
out	PORTB,r17

// Rozhodni co dál

DECIDE: mov RR,r18
andi RR,0xFE
brne TESTIK //v případě hodnoty větší jak 3, skoč na test

// Čekání na ukončení odpočtu

LOOPX: tst r18
brne LOOPX
rjmp READT

// Test vstupu

TESTIK: tst r3 // ZDE je test pinu pro změnu modu
brne SYNTST // je li R3>0 skoč dále

sbic	PINB,5
rjmp	SYNTST		// je li PINB.5 v Hi, skoč dále

cbi	PORTB,4		// shoď linku
inc	r3		// zablokuj test na 500ms :-)
mov	RR,r6		// VOLBA MODU
inc	RR		

EEPROM_write: // Zápis změny do EEPROM
cli
mov r6,RR // navrať hodnotu do r3
sbic EECR,EEPE
rjmp EEPROM_write
ldi RR, (0<<EEPM1)|(0<<EEPM0)
out EECR,RR
ldi RR,MODE // na adrese 5
out EEARL,RR
out EEDR,r6
sbi EECR,EEMPE
sbi EECR,EEPE
rjmp UPLOAD // aplikuj novou volbu

// Synchronizace

SYNTST: sbic PORTB,4
rjmp DECIDE //vynechej synch. v případě mnou nahozené linky

sbis	PINB,3
rjmp	ROZHOD		//vynechej synch. v případe nahozene linky jinym MCU

ldi	RR,1		//zapiš si, že linka byla shozena
mov	r4,RR
rjmp	DECIDE

ROZHOD: tst r4
breq DECIDE //dokud linka nebyla shozena, nezájem

rjmp	RESTAR		// v opačném případě restartuj

//**************************************************************************************
//*** PŘERUŠENÍ ********
//**************************************************************************************

INT00: out TCNT0,r5 //opětovné vložení časovače
tst r18
breq enINT0
dec r18

enINT0: reti

//**************************************************************************************
//*** TABULKY ********
//**************************************************************************************

TSVLM1: .DB 136,0x11 ;Prvni byte = delka pulsu
.DB 36,0x10 ;Druhy byte = požadovaný stav PORTB
.DB 56,0x11 ;
.DB 16,0x10
.DB 136,0x02
.DB 36,0x00
.DB 56,0x02
.DB 16,0x00
.DB 0,0

TSVLM2: .DB 56,0x11
.DB 38,0x10
.DB 56,0x11
.DB 38,0x10
.DB 56,0x11
.DB 56,0x02
.DB 38,0x00
.DB 56,0x02
.DB 38,0x00
.DB 56,0x02
.DB 0,0
//**************************************************************************************
//*** KONEC PROGRAMU ********
//**************************************************************************************
.EXIT
[/code]

Díky jen jsem to překopíroval přes schránku ani kompiler nic proti tomu nenamítal ještě bych potřeboval vědět jak máš nakonfigurovány pojistky?
a k mé úplné spokojenosti teď už chybí schéma díky

Pojistky jsou snadné:
-vyplý reset
-interní RC oscilátor 4,8MHz
-Brown-out na 4.3V
a samozřejmě vyplý SPIEN a CKDIV8

Piny portu jsou definovány takto:
0…levá strana majáku
1…pravá strana majáku
2…nepoužito
3…příjem ze synchronizační linky
4…obsluha synchronizační linky
5…změna modu

Se schématkem to bude horší, žádné jsem tenkrát nekreslil.
Tak aspoň drobný popis:
Na majákové piny jsem přes tranzistory připojil vysokosvítivé ledky.
Synchronizační linka sloužila pro synchronizaci dvou majáků na jednom autě.
V podstatě když tyto piny nezapojíš, tak by to také mělo fungovat.
Pro představu ti však vysvětlím, jak to fungovalo.
Linka byla pouze jednožilová.
Pin4 spínal pomocí PNP tranzistoru pull-up napájení pro tuto linku.
Pin3 tuto linku zase snímal skrz optočlen.

No a nakonec uzemněním Pinu5 docházelo ke změně modu.
Tato změna se zapisuje do EEPROMky.