První pokus v simulátoru AVR

Z MAM wiki

(Rozdíly mezi verzemi)
Přejít na: navigace, hledání
m
(Aktualizace 2013/14)
 
(Není zobrazeno 6 mezilehlých verzí.)
Řádka 3: Řádka 3:
V AVR Studiu založte nový projekt, napište pár instrukcí v [[assembler]]u dle [[instrukční soubor AVR|instrukčního souboru]] nebo okopírujte vzorový program a program přeložte a zkuste krokovat. Vše je velmi obrázkové a názorné, takže asi pochopíte, jak se podívat do registrů a ověřit, že instrukce dělají to, co jste čekali.
V AVR Studiu založte nový projekt, napište pár instrukcí v [[assembler]]u dle [[instrukční soubor AVR|instrukčního souboru]] nebo okopírujte vzorový program a program přeložte a zkuste krokovat. Vše je velmi obrázkové a názorné, takže asi pochopíte, jak se podívat do registrů a ověřit, že instrukce dělají to, co jste čekali.
-
Jako první úkol zkusíme ovládnout LED připojenou k procesoru [[ATtiny2313]]. Pro nízkopříkonové LED stačí přímo proud dodávaný výstupem procesoru, LED zapojíme podle jednoho z následujících schémat. Trochu lépe spíná výstup k zemi, pro větší proudy nebo při malém napájecím napětí bychom tedy měli preferovat zapojení s LED připojenou k +5 V a spínanou log. L na výstupu. Nezapomeneme nastavit správnou hodnotu sériového rezistoru R1 = (napájecí napětí - úbytek na diodě a na sepnutém výstupu)/požadovaný proud. Pokud potřebujeme vstup z kontaktu, zapojíme ho podle vzoru u vstupu PD5, rezistor R2 nastavuje na vstupu PD5 úroveň H při rozpojeném spínači, ve skutečnosti ho nezapojujeme jako vnější součástku, ale aktivujeme vnitřní pull-up rezistor.  
+
Jako první úkol zkusíme ovládnout LED připojenou k mikrokontroleru. Pro nízkopříkonové LED stačí přímo proud dodávaný výstupem procesoru, LED jde zapojit podle jednoho z následujících schémat. Trochu lépe spíná výstup k zemi, pro větší proudy nebo při malém napájecím napětí bychom tedy měli preferovat zapojení s LED připojenou k +5 V a spínanou log. L na výstupu, tak je LED zapojena i na naší [[Evaluation Board|vývojové destičce]]. Nesmíme zapomenout nastavit správnou hodnotu sériového rezistoru R1 = (napájecí napětí - úbytek na diodě a na sepnutém výstupu)/požadovaný proud. Pokud potřebujeme vstup z kontaktu, zapojíme ho podle vzoru u vstupu PD5, rezistor R2 nastavuje na vstupu PD5 úroveň H při rozpojeném spínači, ve skutečnosti ho nezapojujeme jako vnější součástku, ale aktivujeme vnitřní [[pull-up]] rezistor. Na vývojové destičce k tomu použijeme tlačítka  S1, S2, S3 levého sloupce maticové klávesnice, sloupec aktivujeme propojením kontaktů 1-3 na propojce JP1.  
[[Soubor:AVR-LED.png|300px]]  
[[Soubor:AVR-LED.png|300px]]  
[[Soubor:AVR-1LED.png|300px]]  
[[Soubor:AVR-1LED.png|300px]]  
-
Zajímavé je připojit dvoubarevnou LED, která ma v jednom pouzdře dvě antiparalelně zapojené různobarevné diody. Jak to uděláme je vidět z následujícího schématu, diodu zapojíme mezi dva výstupy a tím řídíme přítomnost a polaritu napětí na diodách. Sériový odpor volíme jako kompromis vzhledem k různým úbytkům na různobarevných LED. Současně je ve schématu nakresleno zjednodušené zapojení spínače na vstupu, vnější rezistor je nahrazen vnitřním pull-up rezistorem v AVR (naznačen čárkovaně), který lze aktivovat vhodnou konfigurací vstupu s měkkou log. H.
+
Zajímavé je připojit dvoubarevnou LED, která ma v jednom pouzdře dvě antiparalelně zapojené různobarevné diody. Jak to uděláme je vidět z následujícího schématu, diodu zapojíme mezi dva výstupy a tím řídíme přítomnost a polaritu napětí na diodách. Sériový odpor volíme jako kompromis vzhledem k různým úbytkům na různobarevných LED. Současně je ve schématu nakresleno zjednodušené zapojení spínače na vstupu, vnější rezistor je nahrazen vnitřním [[pull-up]] rezistorem v AVR (naznačen čárkovaně), který lze aktivovat vhodnou konfigurací vstupu s měkkou log. H.
[[Soubor:AVR-2LED.png|340px]]
[[Soubor:AVR-2LED.png|340px]]
-
K nastavení módu činnosti jednotlivých bitů I/O portu a pro zápis nebo čtení dat slouží trojice registrů DDRx, PORTx a PINx. DDRx určuje směr, PORT nastavuje výstupní data nebo pull-up rezistor a PINx obsahuje ve všech konfiguracích portu data přečtená ze vstupu podle tabulky
+
K nastavení módu činnosti jednotlivých bitů I/O portu a pro zápis nebo čtení dat slouží trojice registrů [[DDRx, PORTx a PINx]]. DDRx určuje směr, PORT nastavuje výstupní data nebo [[pull-up]] rezistor a PINx obsahuje ve všech konfiguracích portu data přečtená ze vstupu podle tabulky
Řádka 54: Řádka 54:
-
Pro úplnost, pull-up rezistory lze globálně zakázat dalším konfiguračním bitem (PUD bit v registru MCUCR).
+
Pro úplnost, pull-up rezistory lze globálně zakázat dalším konfiguračním bitem (PUD bit v registru [[MCUCR]]).
-
Můžete použít třeba tento program:
+
Pro první pokusy můžete použít třeba tento program:
 +
 
<pre>
<pre>
;  
;  
-
; example LED-show program for ATtiny 2313
+
; First ASM Programm for the Evaluation Board
;
;
-
; 2-color LED with 300 Ohm resistor in series is supposed to be
+
; Example of LED blinking program for ATmega168
-
; connected between pins 12 (PB0, LED_X) and 13 (PB1, LED_Y).
+
;
;
-
; Color1 shines when LED_X is high and LED_Y is low
 
-
; Color2 shines when LED_Y is high and LED_X is low
 
-
; LED is off when LED_Y and LED_X are both low or both high
 
 +
.equ DDRD = 0x0A ;DDRD address
 +
.equ PORTD = 0x0B ;PORTD address
 +
.equ LED = 6 ;bit of the output port C with LED
-
.EQU DDRB = $17 ; DDRB address
+
sbi DDRD, LED
-
.EQU PORTB = $18 ; PORTB address
+
-
.EQU LED_X = 0 ; LED_X is on PB0, pin 12 of ATtiny2313
+
Main:
-
.EQU LED_Y = 1 ; LED_Y is on PB1, pin 13 of ATtiny2313
+
sbi PORTD, LED
 +
rcall Delay_06s
 +
cbi PORTD, LED
 +
rcall Delay_06s
 +
rjmp Main
-
; Pins connected to LED are outputs, DDRx=1 (set):
+
Delay_06s:
 +
ldi R16, 3
 +
Delay:
 +
  inc R1
 +
brne Delay
 +
inc R2
 +
brne Delay
 +
dec R16
 +
brne Delay
 +
ret
-
SBI DDRB, LED_X ; SBI - Set Bit in I/O Register
 
-
SBI DDRB, LED_Y
 
-
 
-
SHOW:
 
-
RCALL COLOR1 ; RCALL - Relative Call to Subroutine
 
-
RCALL WAIT
 
-
 
-
RCALL DARK
 
-
RCALL WAIT
 
-
 
-
RCALL COLOR1
 
-
RCALL WAIT
 
-
 
-
RCALL DARK
 
-
RCALL WAIT
 
-
 
-
RCALL COLOR2
 
-
RCALL WAIT
 
-
 
-
RCALL DARK
 
-
RCALL WAIT
 
-
 
-
RCALL COLOR2
 
-
RCALL WAIT
 
-
 
-
RCALL DARK
 
-
RCALL WAIT
 
-
 
-
RCALL COL3W
 
-
 
-
RCALL DARK
 
-
RCALL WAIT
 
-
 
-
RCALL COL3W
 
-
 
-
RCALL DARK
 
-
RCALL WAIT
 
-
 
-
RJMP SHOW ; RJMP - Relative Jump
 
-
 
-
;;;
 
-
;;;
 
-
;;; P R O C E D U R E S
 
-
;;;
 
-
;;;
 
-
 
-
SMALLWAIT:
 
-
INC R1 ; INC - Increment
 
-
BRNE SMALLWAIT ; BRNE - Branch if Not Equal (Z flag)
 
-
RET ; RET - Return from Subroutine
 
-
 
-
WAIT:
 
-
LDI R16, 4 ; LDI - Load Immediate
 
-
WAIT1: INC R1
 
-
BRNE WAIT1
 
-
INC R2
 
-
BRNE WAIT1
 
-
DEC R16
 
-
BRNE WAIT1
 
-
RET
 
-
 
-
COLOR1:
 
-
    SBI PORTB, LED_X
 
-
CBI PORTB, LED_Y ; CBI - Clear Bit in I/O Register
 
-
RET
 
-
 
-
COLOR2:
 
-
    SBI PORTB, LED_Y
 
-
CBI PORTB, LED_X
 
-
RET
 
-
 
-
COL3W:
 
-
LDI R16, 2
 
-
COL3X: RCALL COLOR1
 
-
RCALL SMALLWAIT
 
-
RCALL COLOR2
 
-
RCALL SMALLWAIT
 
-
INC R2
 
-
BRNE COL3X
 
-
DEC R16
 
-
BRNE COL3X
 
-
 
-
DARK:
 
-
    CBI PORTB, LED_X
 
-
CBI PORTB, LED_Y
 
-
RET
 
</pre>
</pre>
 +
Pro přehlednost by měl být program okomentován, navíc zde máme přidanou další funkci:
-
Totéž pro trochu větší procesor [[ATmega88 a ATmega168 |ATmega88, ATmega168]], který budeme též často používat, a který má mj. odlišné adresy portů:
 
<pre>
<pre>
-
 
;  
;  
-
; example LED-show program for ATmega168
+
; First ASM Programm for the Evaluation Board
;
;
-
; 2-color LED with 300 Ohm resistor in series is supposed to be
+
; Example of LED blinking program for ATmega168
-
; connected between pins 15 (PB1, LED_X) and 16 (PB2, LED_Y).
+
;
;
-
; Color1 shines when LED_X is high and LED_Y is low
+
; LED cathode connected to PORT D bit 6, anode to +Ucc,
-
; Color2 shines when LED_Y is high and LED_X is low
+
; 3 switches S1, S2, S3 connected to PORT C bit 1, 2, 3 (PC1, PC2, PC3),
 +
; connect JP1 to GND
 +
;  
-
.EQU DDRB = $04
+
; microcomputer hardware definition
-
.EQU PORTB = $05
+
; it is necessary to say the assembler something about our HW:
-
.EQU LED_X = 1
+
.equ DDRC = 0x07 ;DDRC address
-
.EQU LED_Y = 2
+
.equ PORTC = 0x08 ;PORTC address
 +
.equ PINC = 0x06 ;PIND address
-
; Pins connected to LED are outputs:
+
.equ DDRD = 0x0A ;DDRD address
 +
.equ PORTD = 0x0B ;PORTD address
 +
.equ PIND = 0x09 ;PIND address
 +
 
 +
;normally we use the complete definition from the definition file:
 +
; .INCLUDE "m168def.inc"
 +
 
 +
.equ LED = 6 ;bit of the output port C with LED
 +
.equ S1 = 1 ;bit of the input port D with Switch1
-
SBI DDRB, LED_X
 
-
SBI DDRB, LED_Y
 
-
SHOW:
 
-
RCALL COLOR1
 
-
RCALL WAIT
 
-
RCALL DARK
+
; Initialization
-
RCALL WAIT
+
-
RCALL COLOR1
+
sbi DDRD, LED ;Set Bit Immediately - LED pin is output
-
RCALL WAIT
+
; cbi PORTD, LED ;LED ON (LED is ON when log. 0 on this bit) - not necessary, log. 0 from AVR initialization
-
+
-
RCALL DARK
+
-
RCALL WAIT
+
-
+
-
RCALL COLOR2
+
-
RCALL WAIT
+
-
RCALL DARK
 
-
RCALL WAIT
 
-
 
-
RCALL COLOR2
 
-
RCALL WAIT
 
-
RCALL DARK
+
; cbi DDRC, S1 ;Clear Bit Imm. - not necessary, log. 0 from AVR initialization
-
RCALL WAIT
+
sbi PORTC, S1 ;pull-up resistor on the switch input
-
RCALL COL3W
+
;
 +
; Main program start
 +
;
 +
; blinking LED
 +
;
 +
;
 +
; modification:
 +
; when S1 pressed then LED continuously ON until S1 released
 +
;    (uncomment the first two lines)
 +
;
 +
; To do: when S2 pressed then LED continuously OFF until S2 released
 +
;
 +
Main:
-
RCALL DARK
+
sbis PINC, S1 ;skip next instruction if bit is set
-
RCALL WAIT
+
rjmp S1_ON ;relative jump to Switch on subroutine
-
RCALL COL3W
+
sbi PORTD, LED ;LED OFF
-
+
rcall Delay_06s ;relative call (not very far) to Delay 0,5 s
-
RCALL DARK
+
cbi PORTD, LED ;LED ON
-
RCALL WAIT
+
rcall Delay_06s
-
+
-
RJMP SHOW
+
-
;;;
+
-
;;;
+
-
;;; P R O C E D U R E S
+
-
;;;
+
-
;;;
+
-
+
-
SMALLWAIT:
+
-
INC R1
+
-
BRNE SMALLWAIT
+
-
RET
+
-
WAIT:
+
rjmp Main ;loop to start
-
LDI R16, 4
+
-
WAIT1: INC R1
+
-
BRNE WAIT1
+
-
INC R2
+
-
BRNE WAIT1
+
-
DEC R16
+
-
BRNE WAIT1
+
-
RET
+
-
+
-
COLOR1:
+
-
      SBI PORTB, LED_X
+
-
CBI PORTB, LED_Y
+
-
RET
+
-
COLOR2:
+
S1_ON:
-
      SBI PORTB, LED_Y
+
cbi PORTD, LED ;LED ON
-
CBI PORTB, LED_X
+
rjmp Main
-
RET
+
-
COL3W:
 
-
LDI R16, 2
 
-
COL3X: RCALL COLOR1
 
-
RCALL SMALLWAIT
 
-
RCALL COLOR2
 
-
RCALL SMALLWAIT
 
-
INC R2
 
-
BRNE COL3X
 
-
DEC R16
 
-
BRNE COL3X
 
-
DARK:
+
; Delay loop cca 0,6 s for 1 MHz AVR clock:
-
      CBI PORTB, LED_X
+
;
-
CBI PORTB, LED_Y
+
; based on incrementing/decrementing of the register until 0
-
RET
+
;
 +
Delay_06s:
 +
ldi R16, 3 ;prepare for 3 loops of 256x256 loops (1 Clk)
 +
Delay:
 +
  inc R1 ;256 incrementing of R1 (1 Clk)
 +
brne Delay ;Branch if Not Equal - until 0, then go to R2 (1/2 Clk)
 +
inc R2 ;repeat it 256x (1 Clk)
 +
brne Delay ; (1/2 Clk)
 +
dec R16 ;and that all do 3x (1 Clk)
 +
brne Delay ; (1/2 Clk)
 +
ret ;return after 3+4+(256*256*3+256*3+3)*3-256*3-3 Clk pulses. Why?
 +
 
</pre>
</pre>
-
Vývody [[ATmega168]], ke kterým by LED s odporem v séri šla připojit:
 
-
{| class="wikitable" border="1"
+
 
-
|-  
+
Chceme-li připojit hodně tlačítek (a ne jen jedno či dvě), řešením je [[maticová klávesnice]].
-
! ... ... ...
+
 
-
! ... ... ...
+
[[Category:Kód v assembleru]]
-
! ... ... ...
+
-
! PB2
+
-
! PB1
+
-
|-
+
-
| )
+
-
|-
+
-
! RESET
+
-
! ... ... ...
+
-
! ... ... ...
+
-
! ... ... ...
+
-
! ... ... ...
+
-
|}
+

Aktuální verze z 26. 2. 2014, 19:40

Pro první pokus určitě použijte simulátor zabudovaný v programu AVR Studio. Jste-li ve škole v laboratoři 362, je software již připraven. Jinak si AVR Studio nejprve nainstalujte.

V AVR Studiu založte nový projekt, napište pár instrukcí v assembleru dle instrukčního souboru nebo okopírujte vzorový program a program přeložte a zkuste krokovat. Vše je velmi obrázkové a názorné, takže asi pochopíte, jak se podívat do registrů a ověřit, že instrukce dělají to, co jste čekali.

Jako první úkol zkusíme ovládnout LED připojenou k mikrokontroleru. Pro nízkopříkonové LED stačí přímo proud dodávaný výstupem procesoru, LED jde zapojit podle jednoho z následujících schémat. Trochu lépe spíná výstup k zemi, pro větší proudy nebo při malém napájecím napětí bychom tedy měli preferovat zapojení s LED připojenou k +5 V a spínanou log. L na výstupu, tak je LED zapojena i na naší vývojové destičce. Nesmíme zapomenout nastavit správnou hodnotu sériového rezistoru R1 = (napájecí napětí - úbytek na diodě a na sepnutém výstupu)/požadovaný proud. Pokud potřebujeme vstup z kontaktu, zapojíme ho podle vzoru u vstupu PD5, rezistor R2 nastavuje na vstupu PD5 úroveň H při rozpojeném spínači, ve skutečnosti ho nezapojujeme jako vnější součástku, ale aktivujeme vnitřní pull-up rezistor. Na vývojové destičce k tomu použijeme tlačítka S1, S2, S3 levého sloupce maticové klávesnice, sloupec aktivujeme propojením kontaktů 1-3 na propojce JP1.

Zajímavé je připojit dvoubarevnou LED, která ma v jednom pouzdře dvě antiparalelně zapojené různobarevné diody. Jak to uděláme je vidět z následujícího schématu, diodu zapojíme mezi dva výstupy a tím řídíme přítomnost a polaritu napětí na diodách. Sériový odpor volíme jako kompromis vzhledem k různým úbytkům na různobarevných LED. Současně je ve schématu nakresleno zjednodušené zapojení spínače na vstupu, vnější rezistor je nahrazen vnitřním pull-up rezistorem v AVR (naznačen čárkovaně), který lze aktivovat vhodnou konfigurací vstupu s měkkou log. H.

K nastavení módu činnosti jednotlivých bitů I/O portu a pro zápis nebo čtení dat slouží trojice registrů DDRx, PORTx a PINx. DDRx určuje směr, PORT nastavuje výstupní data nebo pull-up rezistor a PINx obsahuje ve všech konfiguracích portu data přečtená ze vstupu podle tabulky


DDRx PORTx I/O pull-up funkce vývodu PINx
0 0 IN ne vstup bez pull-up rezistoru log. úroveň na vývodu
0 1 IN ano vstup s pull-up rezistorem (PORT=1 zde znamená "měkkou H") log. úroveň na vývodu
1 0 OUT ne výstup ve stavu L log. úroveň na vývodu
1 1 OUT ne výstup ve stavu H log. úroveň na vývodu


Pro úplnost, pull-up rezistory lze globálně zakázat dalším konfiguračním bitem (PUD bit v registru MCUCR).


Pro první pokusy můžete použít třeba tento program:


; 
; First ASM Programm for the Evaluation Board
;
; Example of LED blinking program for ATmega168
;

	.equ DDRD = 0x0A	;DDRD address
	.equ PORTD = 0x0B	;PORTD address
	.equ LED = 6	;bit of the output port C with LED

	sbi DDRD, LED	

Main: 
	sbi PORTD, LED	
	rcall Delay_06s	
	cbi PORTD, LED	
	rcall Delay_06s	
	rjmp Main

Delay_06s:
	ldi R16, 3
Delay:
  	inc R1		
	brne Delay	
	inc R2		
	brne Delay	
	dec R16	
	brne Delay
	ret			

Pro přehlednost by měl být program okomentován, navíc zde máme přidanou další funkci:


; 
; First ASM Programm for the Evaluation Board
;
; Example of LED blinking program for ATmega168
;
; LED cathode connected to PORT D bit 6, anode to +Ucc,
; 3 switches S1, S2, S3 connected to PORT C bit 1, 2, 3 (PC1, PC2, PC3),
; connect JP1 to GND
; 

; microcomputer hardware definition
; it is necessary to say the assembler something about our HW:

	.equ DDRC = 0x07	;DDRC address
	.equ PORTC = 0x08	;PORTC address
	.equ PINC = 0x06	;PIND address

	.equ DDRD = 0x0A	;DDRD address
	.equ PORTD = 0x0B	;PORTD address
	.equ PIND = 0x09	;PIND address

;normally we use the complete definition from the definition file:
;	.INCLUDE "m168def.inc"

	.equ LED = 6	;bit of the output port C with LED
	.equ S1 = 1		;bit of the input port D with Switch1


	
; Initialization
	
	sbi DDRD, LED	;Set Bit Immediately - LED pin is output
;	cbi PORTD, LED	;LED ON (LED is ON when log. 0 on this bit) - not necessary, log. 0 from AVR initialization


;	cbi DDRC, S1	;Clear Bit Imm. - not necessary, log. 0 from AVR initialization
	sbi PORTC, S1	;pull-up resistor on the switch input

;
; Main program start
;
; blinking LED
;
;
; modification:
; when S1 pressed then LED continuously ON until S1 released
;    (uncomment the first two lines)
;
; To do: when S2 pressed then LED continuously OFF until S2 released
;
Main: 
	
	sbis PINC, S1	;skip next instruction if bit is set
	rjmp S1_ON	;relative jump to Switch on subroutine

	sbi PORTD, LED	;LED OFF
	rcall Delay_06s	;relative call (not very far) to Delay 0,5 s
	cbi PORTD, LED	;LED ON
	rcall Delay_06s	

	rjmp Main	;loop to start

S1_ON:
	cbi PORTD, LED	;LED ON
	rjmp Main


; Delay loop cca 0,6 s for 1 MHz AVR clock:
;
; based on incrementing/decrementing of the register until 0
;
Delay_06s:
	ldi R16, 3	;prepare for 3 loops of 256x256 loops (1 Clk)
Delay:
  	inc R1		;256 incrementing of R1 (1 Clk)
	brne Delay	;Branch if Not Equal - until 0, then go to R2 (1/2 Clk)
	inc R2		;repeat it 256x (1 Clk)
	brne Delay	; (1/2 Clk)
	dec R16		;and that all do 3x (1 Clk)
	brne Delay	; (1/2 Clk)
	ret			;return after 3+4+(256*256*3+256*3+3)*3-256*3-3 Clk pulses. Why?


Chceme-li připojit hodně tlačítek (a ne jen jedno či dvě), řešením je maticová klávesnice.

Osobní nástroje