AVR assembler: Tři tlačítka zapínají a vypínají tři LED

Zdravím. Začínám se učit s procesory 8051 a programuju je v assembleru. Nějaké jednoduché programy jako zanout/vypnout LED, blikání už dovedu. Kamarád se mě ptal, jestli bych mu vytořil program, kde budou 3 tlačítka a 3 LED a každé tlačítko bude ovládat svojí LEDku. Pro 8051 nemám problém napsat program, jenomže je problém ve velikosti. Jemu by vyhovoval ATTiny který je daleko menší. Prošel jsem si instrukční sabu, která je podobná 8051, ale práce s nimi už neovládám. když dám např.

vypinac equ p.0

mov a,vypinac

jak by to vypadalo v AVR? Vím, že jsou port značený písmeny a čísly, ale nevím jak to napsat aby to fungovalo.

Díky Honza

:arrow_right: administrator: přejmenováno z "AVR assembler"

Kdyby si to chtěl v Bascomu, tak bych s tím neměl sebemenší problém, ale takhle musíš počkat na někoho dalšího.

Zdar.

Takže to bude na mne. Vkládám ti neúplnou část svého kódu.
Je to jen pro ilustraci.

[code]//**************************************************************************************
//*** DEFINOVÁNÍ PROCESORU ********
//**************************************************************************************
.NOLIST
.INCLUDE “can32def.inc” ;procesot AT90CAN32
.DEVICE AT90CAN32
.LIST

//**************************************************************************************
//*** DEFINICE KONSTANT ********
//**************************************************************************************
.CSEG
.DEF RR=R16 ;IN OUT registr
.EQU SPCNT=0x10 ;Velikost Stacku
//**************************************************************************************
//*** Reservace paměti ********
//**************************************************************************************
.DSEG
.ORG RAMEND-SPCNT ;Na konec paměti
STACK: .BYTE SPCNT ;reservuj paměť pro Stack

.ORG SRAM_START ;A teď klasicky na začátek
BUFR: .BYTE 1
//**************************************************************************************
//*** DEKLARACE REGISTRŮ (takhle si vedu přehled o tom, ktrý registr používám a k čemu) ********
//**************************************************************************************
// R0 -
// R1 -
// R2 -
// R3 -
// R4 -
// R5 -
// R6 -
// R7 -
// R8 -
// R9 -
// R10 -
// R11 -
// R12 - uložiště příkazu pro AD převodník
// R13 - uložiště příkazu pro AD převodník
// R14 - uložiště příkazu pro AD převodník
// R15 - pomocný latch pro blikání LED
// R16 - UNIVERSÁLNÍ REGISTR RR (náhrada za acc :slight_smile:
// R17 - sekundární UNI registr (náhrada za bcc :smiley:
// R18 - prozatímní uložiště vstupu z AD převodníku
// R19 - časovač
// R20 - časovač
// R21 - časovač
// R22 -
// R23 -
// R24 - aktuální CANPAGE (0-1) 2 a výše není použita
// R25 -
// R26 -
// R27 -
// R28 -
// R29 -
// R30 - Adresace paměti
// R31 - Adresace paměti
//**************************************************************************************
//*** VEKTORY PŘERUŠENÍ ********
//**************************************************************************************
.CSEG
.ORG 0 ; Vektor resetu
RJMP START

.ORG OC1Aaddr
rjmp INT01

.ORG OC0addr ; vektor č/č 0
RJMP INT00
.ORG OVF0addr
RJMP INT00

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

.ORG INT_VECTORS_SIZE
//**************************************************************************************
//*** VLOŽENÍ SOUBORŮ ********
//**************************************************************************************
.INCLUDE “MyMacros.asm”

START: // Nastavení portů

HiImps	A     //Toto jsou má makra z knihovny MyMacros.asm
Totems1    B     // Nahraď je tímto:
Totems1	C     // clr r16
HiImps	D     // out DDRA, r16
Totems1	E     // out PORTA, r16
HiImps	F
HiImps	G

//STACK
ldi	RR,LOW(RAMEND)	; Nastavení SP - stack point na RAMEND
OUT	SPL,RR
ldi	RR,HIGH(RAMEND)
OUT	SPH,RR

//SPI
ldi	RR,(1<<SPE)|(1<<MSTR)	; dělička /8 ;Mastr  ; H->L
out	SPCR,RR
ldi	RR,(1<<SPI2X)
out	SPSR,RR
ldi	RR,0b00000001
mov	r12,RR
ldi	RR,0b10100000
mov	r13,RR
clr	r14
clr	r15
inc	r15


//Timer0
ldi	RR,(5<<CS00)
OUT	TCCR0A,RR
LDI	RR,(1<<TOIE0)
STS	TIMSK0,RR

//Timer1
ldi	RR,0x00
sts	OCR1AH,RR
ldi	RR,0x38
sts	OCR1AL,RR
ldi	RR,(1<<WGM12)|(2<<CS10)
sts	TCCR1B,RR
CLR	RR
STS	TCNT1H,RR
STS	TCNT1L,RR
ldi	RR,(1<<OCIE1A)			
sts	TIMSK1,RR
sei

CCKL: ldi RR,0b00001000 ; Rozviť LED4
… Další kód
rjmp CCKL

INT01: …přerušení

reti

INT00: …přerušení

reti
[/code]

[code] .NOLIST
.INCLUDE “tn45def.inc” ; pouzity IC je attiny45 (8mi nozickovy)
.LIST

; -------------------------------------------------------------------
; definice promennych
; -------------------------------------------------------------------

	.def WORK = R16			; pracovní registr

	.equ TLAC1 = PORTB3		; tlacitka jsou pripojena na dotycny pin IC a na zem (o zpracovani se stara interni pull-up)
	.equ TLAC2 = PORTB4
	.equ TLAC3 = PORTB5

	.equ LED1 = PORTB0		; ledky jsou pripojeny pres odpor anodou k plusu, katodou k nozicce pinu IC
	.equ LED2 = PORTB1
	.equ LED3 = PORTB2

; -------------------------------------------------------------------
; nastaveni vseho mozneho okamzite po resetu
; -------------------------------------------------------------------

	.CSEG

reset: ldi WORK,low(RAMEND)
out SPL,WORK ; nastav SP na konec SRAM

inicial:ldi WORK,$07
out DDRB,WORK

	ldi WORK,$3F
	out PORTB,WORK

	nop

; -------------------------------------------------------------------
; hlavni cykl a podprogramy
; -------------------------------------------------------------------

; hlavni cykl
start: sbis PINB,TLAC1 ; pokud neni zmacknuto tlacitko, preskoc rozsviceni (nezapomen, ze zapojeni diod je inverzne, proto nulujeme plusem)
cbi PORTB,LED1 ; nastavi na pinu zem

	sbis PINB,TLAC2				; sbis = tato funkce nacte aktualni stav pinu a preskoci nasledujici instrukci, pokud je v logicke 1
	cbi PORTB,LED2

	sbis PINB,TLAC3
	cbi PORTB,LED3

	sbic PINB,TLAC1				; pokud je zmacknuto tlacitko (pullup je stazen k zemi), preskoc zhasnuti
	sbi PORTB,LED1				; nastavi na pinu plus
	
	sbic PINB,TLAC2				; sbic = tato funkce nacte aktualni stav pinu a preskoci nasledujici instrukci, pokud je v logicke 0
	sbi PORTB,LED2

	sbic PINB,TLAC3
	sbi PORTB,LED3

	rjmp start					; opakuj

[/code]

pokud bys ty tlacitka napojil primo bez IC, tak to bude fungovat stejne :smiley:

Ty jo, dík za program. Zajdu do knihovny a pujčím si knihu která mi řekne, jaká instrukce co dělá. Myslel jsem, že příkazy budou podobné klasickému assembleru. Deklaraci proměnných znám z pascalu ale ještě musím někde vyčíst, co znamená to nastavení všeho možného :smiley:.
Ten ATTinny má svuj vlastní oscilátor, jak jsme se dočetl z datasheetu, ale jak ho spustím abych nemusel použít externí oscilátor?

Díky moc, Honza

Ještě dodám k tomu, že by to šlo i bez IC. Je to do vagonku do kolejiště. Jelikož má skoro všechny adresy obsazený a hlavně chaotický každej vagon zvlášť ovládat multimousem, tak tento obvod bude dělat to, že místo tlačítek budou miniaturní jazýčková relé umístěná ve vagonu na třech různých místech. Při přiložení magetu k relátku se rozsvítí LED a při opětovném přiložení zhasne LED. 3 okruhy proto, že první relé = světlo ve voze, druhé relé = světla na jedné straně a třetí relé = světla na druhé straně

V knihovně mít instrukce nebudou, to by nestačili aktualizovat. To najdeš v datasheetu: atmel.com/images/doc0856.pdf

Pokud nebudeš měnit pojistky, tak procesory mají implicitně zapnutý interní oscilátor (jinak by nešly naprogramovat v obvodu s interním oscilátorem, potřebují k programování hodiny).

jsem si uvedomil, ze tohle je jen prubezny mod. pokud bys chtel aby to delalo ze zmacknutim zapne, zmacknutim vypne, tak bych to musel krapet upravit.

v tom nastaveni vseho mozneho je nastaven konec ramky. v tomto pripade je to zbytecne, ale pouzivam to univerzalne. jde o to, abyses adresaci nedostal pres fyzickou ram.

a dale je tam nastaveni portu. nastavil jsem tam 3 piny jako vystupni s defaultnim stavem v logicke 1 (s napetim) a 3 piny jako vstupni s aktivovanym internim pullupem.