Uživatel:Stepaj20

Z MAM wiki

Přejít na: navigace, hledání

Všechno co dělám, dělám s Helenou Procházkovou


Obsah

[editovat] Sedmisegmentovka v jazyce C

#include <avr/interrupt.h>
#include <avr/sleep.h>

#define SER		PD5
#define SRCLK	PD6
#define RCLK	PD7
#define SRCLR	PB0

// global constants and variables
// static code table used for 7-segment led display decoding (common anode)
/*unsigned char code [] = { 0xC0, 0xF9, 0xA4, 0xB0, 0x9B, 0x92, 0x93, 0xF8, 0x80, 0x98,
				 		  0x88, 0x80, 0xC6, 0xC0, 0x86, 0x8E };*/
unsigned char code [] = { 0x3F, 0x06, 0x5B, 0x4F, 0x64, 0x6D, 0xFC, 0x07, 0x7F, 0x67,
				 		  0xF7, 0x7F, 0x39, 0x3F, 0x79, 0x71 };

// character to show on display
static volatile unsigned char anumber = 0;
// Interrupt vector table is created by compiler
// the ISR macro defines interrupt service handlers

// Pin change interrupt 1
// keyboard handler
ISR(PCINT1_vect)
{
	unsigned char keys[10];
	unsigned char nkeys = 0;
	register unsigned char column;

//    DDRD 	&= 0b00000001;
	DDRD	&= 0b11110001;
	PORTD	&= 0b11110000;		// set keyboard rows at port D to zero
	if (!(PINC & 4))
		keys[nkeys++] = 1;
	if (!(PINC & 8))
		keys[nkeys++] = 2;
	if (!(PINC & 16))
		keys[nkeys++] = 3;

	DDRD	&= 0b11110000;
	DDRD	|= (1 << PD1);
	PORTD	&= 0b11110000;		// set keyboard rows at port D to zero
	if (!(PINC & 4))
		keys[nkeys++] = 4;
	if (!(PINC & 8))
		keys[nkeys++] = 5;
	if (!(PINC & 16))
		keys[nkeys++] = 6;

	DDRD	&= 0b11110000;
	DDRD	|= (1 << PD2);
	PORTD	&= 0b11110000;		// set keyboard rows at port D to zero
	if (!(PINC & 4))
		keys[nkeys++] = 7;
	if (!(PINC & 8))
		keys[nkeys++] = 8;
	if (!(PINC & 16))
		keys[nkeys++] = 9;

	DDRD	&= 0b11110000;
	DDRD	|= (1 << PD3);
	PORTD	&= 0b11110000;		// set keyboard rows at port D to zero
	if (!(PINC & 8))
		keys[nkeys++] = 0;

	DDRD 	|= 0b00001111;		// configure rows as outputs
	PORTD 	&= 0b11110000;		// set keyboard rows at port D to zero

	if (nkeys > 0) {
		OCR1A = keys[0] * 100;
		TCNT1 = 0;
	}
}

// Timer/Counter1 Compare Match A
// the value shown on the display will be updated here
ISR(TIMER1_COMPA_vect)
{
	unsigned char tmp = code[anumber];
	volatile char loopcounter = 8;

	do {
		PORTD &= ~(1 << SRCLK);			// assert 0 on serial clock line
		if (tmp & 0x80)					// test LSB
			PORTD |= (1 << SER);		// if 1, assert 1 on serial data line
		else
			PORTD &= ~(1 << SER);		// assert 0 otherwise
		PORTD |= (1 << SRCLK);			// assert 1 on serial clock line - rising edge writes bit into the serial shift register
		tmp <<=  1;					// shift right to proceed next bit
		loopcounter--;
	} while (loopcounter > 0); 
	PORTD &= ~(1 << RCLK);				// toggle parallel register clock 0-1 to make a rising edge
	PORTD |= (1 << RCLK);
	
	// update value to display for next time
	if (anumber < 15)
	    anumber++;
	else
		anumber = 0;
}

void main(void)
{
	// keyboard (and serial shift register connection) ports init
	DDRD 	|= 0b11101111;		// configure rows as outputs (PD0 ... PD3), serial shift register pins PD5 .. PD7
	PORTD 	= 0;				// set port D to zero
	DDRC	= 0;				// configure port C as input port
	PORTC	|= 0b00011100;		// activate pul-up resistors on three columns

	DDRB	|= (1 << SRCLR);	// configure PB0 as output - serial shoft register clear
	PORTB	|= (1 << SRCLR);	// toggle PB0 1-0-1 to clear the serial shift register
	PORTB	&= ~(1 << SRCLR);
	PORTB	|= (1 << SRCLR);

	// an interrupt masking must be here
	// keyboard interrupt
	PCICR 	= (1 << PCIE1);		// Pin change interrupt control register, Pin change interrupt enable 1
	PCMSK1 	= 0b00011100;		// allow pin change interrupt on portC bits 2,3,4

	// timer configuration
	TCCR1A	= 0;				// OC1A/OC1B disconnected, CTC bits WGM11, WGM10
	TCCR1B 	= (1 << CS12) | (1 << CS10) | (1 << WGM12);
								// CTC mode, prescaler division factor 1024
	OCR1A 	=  976;				// timer compare value

	TIMSK1 = (1 << OCIE1A);		// enable timer interrupt

	set_sleep_mode(SLEEP_MODE_IDLE);
	sei();						// set Global Interrupt Enable!!!

	while (1) {
		sleep_cpu();
	}
}

[editovat] Domácí úkol - řízení osvětlení

Domácí úkol je inspirován Tomášem Fridrichem a uživateli z minulého roku. Funkčnost neověřena, AVR Studio nehlásí žádnou chybu a na zmáčknutí tlačítka reaguje tak jak má.

; nacteni adresoveho souboru

	.include "m88def.inc"

; nastaveni frekvence pwm 

	.equ PWM_dvere = 40	; frekvence 25  kHz pro osvetleni interieru
	.equ PWM_deska = 70	; frekvence 14.3 kHz pro osvetleni palubi desky

; nastaveni vektoru
	
	.org 0x000 
		rjmp Zacatek 		; reseto
	.org 0x00D				; 00D je vektor pro citac/casovac s pretecenim
		rjmp Tim1_Ovf		; preruseni 

Zacatek:

;porty

	ldi	r16, 0b011110		; nastaveni vstupu pro tlacitko (PC 5) a A/D (PC0)
	out	DDRC, r16			
	ldi	r16, 0b100000		; vystupy do 0 a interni pull-up pro tlacitko (PC 5)
	out	PORTC, r16			
	ser	r16				    ; (set registr - R16=0xFF) porty B a D jako vystupy
	out	DDRD, r16			
	out	DDRB, r16			
	clr	r16			    	; (clear registr - R16=0x00) na porty B a D nastavit hodnotu 0
	out	PORTB, r16			
	out	PORTD, r16			

; inicializace PWM

;TMR0 interier
	ldi r16, 0b00100011	; Fast PWM Mode, vystup na OC0B, neinverujici
	out TCCR0A, r16		
	ldi r16, 0b00001001	; WGM2:1 (Fast PWM), CS2..0:001 (internal clock, prescale=1)
	out TCCR0B, r16		; TCC - timer/citaci registr
	ldi r16, PWM_dvere	; pocet pulzu pro jednu periodu
	out OCR0A, r16		; ocra - vystupni porovnavaci registr


;TMR2 budiky
	ldi	r16, 0b00100011	; Fast PWM Mode, vystup na OC0B, neinverujici
	sts	TCCR2A	, r16	; sts - store direct
	ldi	r16, 0b00001001	; WGM2:1 (Fast PWM), CS2..0:001 (internal clock, prescale=1)
	sts	TCCR2B, r16		
	ldi	r16, PWM_deska	; pocet pulzu pro jednu periodu
	sts	OCR2A, r16		; ocra - vystupni porovnavaci registr

; inicializace preruseni

	ldi r26, PCICR 	; PCICR - pin change interrupt control register
 	clr r27 		; load high byte with 0
 	ldi r16,0b00000010 ; aktivace preruseni na pinech PCINT 14-8
 	st X, r16 		; store new PCINT1
 	ldi r26, PCMSK1 ; PCMSK -  pin change mask register
 	clr r27 		; load high byte with 0
 	ldi r16,0b00011100 ; Vyberu na kterych pinech PCINT 14-8 reaguju na preruseni 2,3,4
 	st X, r16 		; store new PCMSK1
 	sei 			; povoleni preruseni

; inicializace A/D prevodniku

	ldi	r16, 0b11100000	; Internal reference, Left adjusted result, ADC0
	sts	ADMUX, r16		
	ldi	r16, 0b10000100	; ADC enabled, int. off, autotriger off, prescaler 16 (62,5kHz)
	sts	ADCSRA, r16		
	clr	r16				; autotriger source -> autotriger je off, takze jen pro poradek
	sts	ADCSRB, r16		
	ldi	r16, 0x01		; disable digital input buffer for pin ADC0 (snizeni spotreby)
	sts	DIDR0, r16	
	
; hlavni program

Main:
rjmp Main     ; cekani na preruseni


; dvere
Tim1_Ovf:


    sbis PINC,2  ; tlacitko rozepnuto - skoc na zacatek, tlacitko sepnuto - skoc na sviceni
	rjmp Tim1_Ovf
	rcall Zap
    sbic PINC,2  ; tlacitko rozepnuto  - skoc na zhasinani, tlacitko sepnuto - skoc na zacatek a zlus to znova
	rjmp Tim1_Ovf
	rcall Vyp
	reti

;rozsviceni

Zap:
	ldi r16,0b00101000
	out OCR0A, r16   ; zapnuti spinace
	sbi PORTB,0   ; nastaveni minuleho stavu jako 1
	ret

; zhasinani

Vyp: 
	sbic PINB,0  ; preskoc jestli i v minulem kroku byl vypli
	rcall Dim    ; 5s cekani + 2s zatemnovani
	sbic PINB,0  
	ldi r16,0b00000000
	out OCR0A, r16   ; vypnuti spinace
	cbi PORTB,0
	ret


Dim:
	ldi r16,0b00101000
	out OCR0A, r16  ; nastaveni vystupu na zapli
	rcall wait5sec
	ldi r16,0b00100111
	ldi r17,0b00000000
	out OCR0A, r16

loop:   ; zatemnovaci smycka
	rcall wait50ms    ;(2s/40 kroku v PWMku = 50ms)
	dec r16
	out OCR0A, r16
	cpse r16,r17 ;porovnej a preskoc jestli jsou si rovni
	rjmp loop
	cbi PORTB,0
	ret

wait50ms:

	ldi r18, 0b00000000    ; horni bit
	ldi r19, 0b00000000    ; spodni bit
	ldi r20, 0b11000011    ; pro porovnani horniho bitu, 50000 cyklu = 50ms
	ldi r21, 0b00000000    ; pro porovnani preteceni spodniho bitu
loop1:
	inc r19;
	cpse r19,r21
	inc r18
	cpse r18,r20
	rjmp loop1


ret

wait5sec:

	ldi r21, 0b00000000  
	ldi r22, 0b01100100  
loop3:
	rcall wait50ms
	inc r21;
	cpse r21,r22
	rjmp loop1

ret

[editovat] Sedmisegmentovak 0-1

.INCLUDE "m168def.inc"

; Pins connected to LED are outputs, DDRx=1 (set):

; D vystupni:
SBI	DDRD,0 ; seriovy vystup
SBI	DDRD,1 ; clk storage
SBI	DDRD,2 ; clk shift
CBI	DDRB,0 ; vstup na tlacitko

; B0 pull-up
SBI	PORTB, 0

; hodiny do 1:
CBI PORTD, 1
CBI PORTD, 2

LDI R16, 0b01010101 ; znak 1
LDI R17, 0b10101010 ; znak 2


smycka:

	MOV R18, R16 ; v R18 je znak ktery budeme vysilat
	IN R20, PORTB ; B --> R20
	SBRS R20, 0 ; stiskle tlacitko --> pouzijeme druhy znak
	MOV R18, R17
	LDI R19, 8; v R5 je cislo 8
posilani_bitu:

	SBRC R18,0
	SBI PORTD,0
	SBRS R18,0
	CBI PORTD,0
	ROR	R18 ; rotujeme bity
	SBI PORTD,2
	RCALL WAIT
	CBI PORTD,2
	dec R19; 
	brne posilani_bitu

	RCALL WAIT
	SBI PORTD,1
	RCALL WAIT
	CBI PORTD,1
	RCALL WAIT
	 


	rjmp smycka

WAIT:
	LDI	R16, 4			; LDI - Load Immediate
WAIT1:	INC	R1
	BRNE	WAIT1
	INC	R21
	BRNE	WAIT1
	DEC	R16
	BRNE	WAIT1
	RET


[editovat] 1. domácí úkol-pokus

Tak nějak netuším, ale pokusila jsme se udělat nástin první části. Mělo by to fungovat tak, že procesor si bude hezky spinkat, pak se zmáčkne tlačítko, na 5 sekund bude svítit maximálně. Po 5 sekundách přejde do části, kde se bude snižovat střída PWM, ta se bude snižovat plynule po jedné 2 sekundy až do nuly. Po tom se procesor odebere opět do postele. Za prvé je to celé pro mě španělská vesnice a za druhé mi nějak nejdou napočítat ty časy. Čistě teoreticky by ta moje myšlenka měla být snad správná, ale ono si to stejně bude dělat, co chce.... (jinak teda ten kód je skoro celý to, co jsme používali v 6. týdnu a vzhledem k tomu, že tak daleko jsem se nedostala, netuším jestli funguje)

.INCLUDE "m168def.inc"

.EQU FREKVENCE=40 ;25kHz

.ORG 0x0000 
	jmp Main ; Reset Handler

.ORG 0x0008 
	jmp isr1 ; PCINT1 Handler

Main:
	ldi r16,high(RAMEND); Main program start
	out SPH,r16 ; Set Stack Pointer to top of RAM
	ldi r16,low(RAMEND)
	out SPL,r16

; tlacitko

	cbi DDRC,0
	sbi DDRC,1

	sbi PORTC,0
	cbi PORTC,1

;PWM
PWM_INIT:
	ldi R17, 0b00100011	; Fast PWM Mode, out on OC0B, non Inverting
	out TCCR0A, R17			; 
	ldi R17, 0b00001001	; WGM2:1 (Fast PWM), CS2..0:001 (internal clock, prescale=1)
	out TCCR0B, R17
	ldi R17, FREKVENCE	; load number of clock pulses for 1 PWM period
	out OCR0A, R17   

	sbi DDRD, 5	; set pin 11 as PWM output OC0B (PD5 pin)

;preruseni
	ldi r26, PCICR ; load address of PCICR in Y low
	clr r27 ; load high byte with 0
	ldi r16,0b00000010 ; activate PCINT1
	st X, r16 ; store new PCINT1

	ldi r26, PCMSK1 ; load address of PCMSK1 in Y low
	clr r27 ; load high byte with 0
	ldi r16,0b00011100 ; allow pin change interrupt on portC bits 2,3,4
	st X, r16 ; store new PCMSK1

	sei ; Enable interrupts

;spani
	ldi r16,0b00000001 ; Idle mode 
	out SMCR,r16 ; Sleep mode set

loop:
	sleep ; now AVR sleeps
	nop ; return from Interrupt to this instruction
	rjmp loop ; and sleep again

isr1:
	sbic PINC,0
	rjmp klesani
	lds R17, 0b00100100 ; maximalni hodnota
	lsl R17
	lsl R17	; multiply key number by 4 for 10 steps in 40 clock pulses of PWM
	out OCR0B, R17  ; output pulse "high" lenght to PWM compare unit 
wait5s:

klesani:
	lds R17, 0b00100100 ; maximalni hodnota
	dec R17
	sbrs R17
	reti
	out OCR0B, R17  ; output pulse "high" lenght to PWM compare unit 
	rjmp klesani

wait: ;tak aby klesani trvalo 2s

[editovat] Větrák fastPWM

; example fan program for ATmega168 with Timer controlled PWM&Interrupt&Sleep
;
; Rotation speed  is controlled by keyboard, 
; keys 0-9 represent the speed between 0 and 100 %
;
; Fan starts to rotate with the first valid key press
;
; To do: *** Catch only the key press, not key release
;
; To do: *** Set higher value of PWM (=higher fan rpm) for 
; a few first periods to start the fan reliably
;
;
; P4 CPU fan Ucc pin is supposed to be connected 
; to +15 V, GND pin is supposed to be connected 
; to NMOS Drain,, Source on GND, Gate on 
; pin 11 (OC0B, PD5). Fan runs when pin 11 is high.


.INCLUDE "m168def.inc"

.EQU PWM_PULSES = 36	; value for 27.8 kHz PWM
;.EQU PWM_PULSES = 45	; value for 22.2 kHz PWM


.ORG 0x0000 
	jmp Main ; Reset Handler

.ORG 0x0008 
	jmp isr1 ; PCINT1 Handler



; Main program start

Main: 

; Stack pointer init:
	ldi r16,high(RAMEND); Main program start
	out SPH,r16 ; Set Stack Pointer to top of RAM
	ldi r16,low(RAMEND)
	out SPL,r16


; Hardware initialization

; Keyboard init:
; D vystupni:
	SBI	DDRB,0
	SBI	DDRB,1
	SBI	DDRB,2
	SBI	DDRB,3

;D = 11101110
	CBI	PORTB, 0
	SBI	PORTB, 1
	SBI	PORTB, 2
	SBI	PORTB, 3
	CBI	PORTB, 4
	SBI	PORTB, 5
	SBI	PORTB, 6
	SBI	PORTB, 7

; B vstupni:
	CBI	DDRC, 0
	CBI	DDRC, 1
	CBI	DDRC, 2
	CBI	DDRC, 3

; B pull-up
	SBI	PORTC, 0
	SBI	PORTC, 1
	SBI	PORTC, 2
	SBI	PORTC, 3


; Timer controlled PWM init:
;
; There are registers TCCR0A and TCCR0B for config, DDRD for output bit
; enabling, OCR0A for counter lenght and OCR0A for pulse "high" lenght.
; Register TIMSK0 controlls interrupts - not used, 0x00 by default 

PWM_INIT:
	ldi R17, 0b00100011	; Fast PWM Mode, out on OC0B, non Inverting
	out TCCR0A, R17			; 
	ldi R17, 0b00001001	; WGM2:1 (Fast PWM), CS2..0:001 (internal clock, prescale=1)
	out TCCR0B, R17
	ldi R17, PWM_PULSES	; load number of clock pulses for 1 PWM period
	out OCR0A, R17   

	sbi DDRD, 5	; set pin 11 as PWM output OC0B (PD5 pin)


; Keyboard interrupt setup
;
; Activation of pin change interrupt - PROBLEM!!! PCICR and PCIMSK are 
; extended I/O registers (0x68 and 0x6C), and must be handled as 
; a memory location

	ldi r26, PCICR ; load address of PCICR in Y low
	clr r27 ; load high byte with 0
	ldi r16,0b00000010 ; activate PCINT1
	st X, r16 ; store new PCINT1

	ldi r26, PCMSK1 ; load address of PCMSK1 in Y low
	clr r27 ; load high byte with 0
	ldi r16,0b00011100 ; allow pin change interrupt on portC bits 2,3,4
	st X, r16 ; store new PCMSK1

	sei ; Enable interrupts


; Set sleep mode of the CPU
; SMCR: 0,0,0,0,SM2,SM1,SM0,SE   SM2..0: Sleep Mode Select Bits, SE: Sleep enabled)

	ldi r16,0b00000001 ; Idle mode 
	out SMCR,r16 ; Sleep mode set


; Sleep loop, wake up by the Interrupt, return with RETI back to sleep loop

loop:
	sleep ; now AVR sleeps
	nop ; return from Interrupt to this instruction
	rjmp loop ; and sleep again


; PCINT0 Service Routine:
;
; To do: *** rpm reading, regulation, etc.


isr1:
	rcall KEYPRESS

	cpi R17,0
	breq vypnuto

	lsl R17
	lsl R17	; multiply key number by 4 for 10 steps in 40 clock pulses of PWM
	out OCR0B, R17  ; output pulse "high" lenght to PWM compare unit 

	reti ; return from Interrupt

vypnuto:
	 ldi R17, 0b0001100 ;odpojeni OCR0B
  	 out TCCR0A, R17
 	; ocr0b se odpojí
	ret
KEYPRESS:
JEDNA:	
	SBIC	PINC, 2
	RJMP	DVA
	LDI	R17, 1		;pressed key 1
	RCALL	KEYRET
DVA:
	SBIC	PINC, 3
	RJMP	TRI
	LDI	R17, 2
	RCALL	KEYRET
TRI:
	SBIC	PINC, 4
	RJMP	A
	LDI	R17, 3
	RCALL	KEYRET
A:
	SBIC	PINC, 4
	RCALL	ROTACE
	LDI	R17, 10
	RCALL	KEYRET


	
CTYRI:
	SBIC	PINC, 2
	RJMP	PET
	LDI	R17, 4	
	RCALL	KEYRET
PET:
	SBIC	PINC, 3
	RJMP	SEST
	LDI	R17, 5
	RCALL	KEYRET
SEST:
	SBIC	PINC, 4
	RJMP	B
	LDI	R17, 6
	RCALL	KEYRET
B:
	SBIC	PINC, 4
	RCALL	ROTACE
	LDI	R17, 11
	RCALL	KEYRET


SEDUM:
	SBIC	PINC, 2
	RJMP	OSUM
	LDI	R17, 7
	RCALL	KEYRET
OSUM:
	SBIC	PINC, 3
	RJMP	DEVET
	LDI	R17, 8
	RCALL	KEYRET
DEVET:
	SBIC	PINC, 4
	RJMP	C
	LDI	R17, 9
	RCALL	KEYRET
C:
	SBIC	PINC, 4
	RCALL	ROTACE
	LDI	R17, 12
	RCALL	KEYRET

HVEZDA:
	SBIC	PINC, 2
	RJMP	NULA
	LDI	R17, 15
	RCALL	KEYRET
NULA:
	SBIC	PINC, 3
	RJMP	KRIZ
	LDI	R17, 0
	RCALL	KEYRET
KRIZ:
	SBIC	PINC, 4
	RJMP	D
	LDI	R17, 16
	RCALL	KEYRET
D:
	SBIC	PINC, 4
	RCALL	ROTACE
	LDI	R17, 14
	RCALL	KEYRET


ROTACE:
	IN	R16, PORTB
	ROL	R16 ; rotujeme radky
	; C bit do R1, 0:
	CBR	R16, 1 ; R1, 0 se nastavi do nuly
	BRCS SET_R1_0
SET_R1_0: ; pomocna procedura pro presun Carry do registru (kvuli rotaci)
	BRCC SMYCKA2
	SBR	R16, 1; R1 se nastavi do jednicky
	RJMP SMYCKA2
	RET
SMYCKA2:
	OUT PORTB, R16 ; zrotovane radky zpatky na vystup
	RET

KEYRET:
	RET

[editovat] Větrák softwarově (snad funkční)

.INCLUDE "m88def.inc" 
.EQU FAN = 2

	SBI	DDRB, FAN
; D vystupni:
	SBI	DDRD,0
	SBI	DDRD,1
	SBI	DDRD,2
	SBI	DDRD,3

;D = 11101110
	CBI	PORTD, 0
	SBI	PORTD, 1
	SBI	PORTD, 2
	SBI	PORTD, 3
	CBI	PORTD, 4
	SBI	PORTD, 5
	SBI	PORTD, 6
	SBI	PORTD, 7

; B vstupni:
	CBI	DDRC, 2
	CBI	DDRC, 3
	CBI	DDRC, 4
	CBI	DDRC, 5

; B pull-up
	SBI	PORTC, 2
	SBI	PORTC, 3
	SBI	PORTC, 4
	SBI	PORTC, 5

JEDNA:	
	SBIC	PINC, 2
	RJMP	DVA
	LDI	R17, 1		;pressed key 1
	RCALL	PWM
DVA:
	SBIC	PINC, 3
	RJMP	TRI
	LDI	R17, 2
	RCALL	PWM
TRI:
	SBIC	PINC, 4
	RJMP	A
	LDI	R17, 3
	RCALL	PWM
A:
	SBIC	PINC, 4
	RCALL	ROTACE
	LDI	R17, 10
	RCALL	PWM


	
CTYRI:
	SBIC	PINC, 2
	RJMP	PET
	LDI	R17, 4	
	RCALL	PWM
PET:
	SBIC	PINC, 3
	RJMP	SEST
	LDI	R17, 5
	RCALL	PWM
SEST:
	SBIC	PINC, 4
	RJMP	B
	LDI	R17, 6
	RCALL	PWM
B:
	SBIC	PINC, 4
	RCALL	ROTACE
	LDI	R17, 11
	RCALL	PWM


SEDUM:
	SBIC	PINC, 2
	RJMP	OSUM
	LDI	R17, 7
	RCALL	PWM
OSUM:
	SBIC	PINC, 3
	RJMP	DEVET
	LDI	R17, 8
	RCALL	PWM
DEVET:
	SBIC	PINC, 4
	RJMP	C
	LDI	R17, 9
	RCALL	PWM
C:
	SBIC	PINC, 4
	RCALL	ROTACE
	LDI	R17, 12
	RCALL	PWM

HVEZDA:
	SBIC	PINC, 2
	RJMP	NULA
	LDI	R17, 15
	RCALL	PWM
NULA:
	SBIC	PINC, 3
	RJMP	KRIZ
	LDI	R17, 0
	RCALL	PWM
KRIZ:
	SBIC	PINC, 4
	RJMP	D
	LDI	R17, 16
	RCALL	PWM
D:
	SBIC	PINC, 4
	RCALL	ROTACE
	LDI	R17, 14
	RCALL	PWM


ROTACE:
	IN	R16, PORTD
	ROL	R16 ; rotujeme radky
	; C bit do R1, 0:
	CBR	R16, 1 ; R1, 0 se nastavi do nuly
	BRCS SET_R1_0
SET_R1_0: ; pomocna procedura pro presun Carry do registru (kvuli rotaci)
	BRCC SMYCKA2
	SBR	R16, 1; R1 se nastavi do jednicky
	RJMP SMYCKA2
	RET
SMYCKA2:
	OUT PORTD, R16 ; zrotovane radky zpatky na vystup
	RET

PWM:
	MOV 	R17, R16
	INC		R17
	LDI		R18, 0xF8
	OR		R18, R16
PWM_ON:
	DEC		R17
	BREQ	PWM_OFF
	SBI		PORTB, FAN
	RCALL 	VERYSMALLWAIT
	RJMP	PWM_ON
PWM_OFF:
	INC		R18
	BREQ	PWM_RET
	CBI		PORTB, FAN
	RCALL 	VERYSMALLWAIT
	RJMP	PWM_OFF
PWM_RET:
	RET

VERYSMALLWAIT:
	LDI R22, 0xFC
	MOV R1, R20
SMALLWAIT:
	INC	R1
	BRNE	SMALLWAIT
	RET


[editovat] Nová lepší a snad fungující klávesnice ;-)

.INCLUDE "m88def.inc" 

; D vystupni:
	SBI	DDRD,0
	SBI	DDRD,1
	SBI	DDRD,2
	SBI	DDRD,3

;D = 11101110
	CBI	PORTD, 0
	SBI	PORTD, 1
	SBI	PORTD, 2
	SBI	PORTD, 3
	CBI	PORTD, 4
	SBI	PORTD, 5
	SBI	PORTD, 6
	SBI	PORTD, 7

; B vstupni:
	CBI	DDRC, 0
	CBI	DDRC, 1
	CBI	DDRC, 2
	CBI	DDRC, 3

; B pull-up
	SBI	PORTC, 0
	SBI	PORTC, 1
	SBI	PORTC, 2
	SBI	PORTC, 3

JEDNA:	
	SBIC	PINC, 2
	RJMP	DVA
	LDI	R17, 1		;pressed key 1
	RCALL	KEYRET
DVA:
	SBIC	PINC, 3
	RJMP	TRI
	LDI	R17, 2
	RCALL	KEYRET
TRI:
	SBIC	PINC, 4
	RJMP	A
	LDI	R17, 3
	RCALL	KEYRET
A:
	SBIC	PINC, 4
	RCALL	ROTACE
	LDI	R17, 10
	RCALL	KEYRET


	
CTYRI:
	SBIC	PINC, 2
	RJMP	PET
	LDI	R17, 4	
	RCALL	KEYRET
PET:
	SBIC	PINC, 3
	RJMP	SEST
	LDI	R17, 5
	RCALL	KEYRET
SEST:
	SBIC	PINC, 4
	RJMP	B
	LDI	R17, 6
	RCALL	KEYRET
B:
	SBIC	PINC, 4
	RCALL	ROTACE
	LDI	R17, 11
	RCALL	KEYRET


SEDUM:
	SBIC	PINC, 2
	RJMP	OSUM
	LDI	R17, 7
	RCALL	KEYRET
OSUM:
	SBIC	PINC, 3
	RJMP	DEVET
	LDI	R17, 8
	RCALL	KEYRET
DEVET:
	SBIC	PINC, 4
	RJMP	C
	LDI	R17, 9
	RCALL	KEYRET
C:
	SBIC	PINC, 4
	RCALL	ROTACE
	LDI	R17, 12
	RCALL	KEYRET

HVEZDA:
	SBIC	PINC, 2
	RJMP	NULA
	LDI	R17, 15
	RCALL	KEYRET
NULA:
	SBIC	PINC, 3
	RJMP	KRIZ
	LDI	R17, 0
	RCALL	KEYRET
KRIZ:
	SBIC	PINC, 4
	RJMP	D
	LDI	R17, 16
	RCALL	KEYRET
D:
	SBIC	PINC, 4
	RCALL	ROTACE
	LDI	R17, 14
	RCALL	KEYRET


ROTACE:
	IN	R16, PORTD
	ROL	R16 ; rotujeme radky
	; C bit do R1, 0:
	CBR	R16, 1 ; R1, 0 se nastavi do nuly
	BRCS SET_R1_0
SET_R1_0: ; pomocna procedura pro presun Carry do registru (kvuli rotaci)
	BRCC SMYCKA2
	SBR	R16, 1; R1 se nastavi do jednicky
	RJMP SMYCKA2
	RET
SMYCKA2:
	OUT PORTD, R16 ; zrotovane radky zpatky na vystup
	RET

KEYRET:
	RET

[editovat] Větrák - 2. a stále nefunkční pokus

	.INCLUDE "m88def.inc"  ; replaces previous lines of the program

	.EQU FAN = 2


; Pin driving FAN is set as output:

	SBI	DDRC, FAN


; D vystupni:
	SBI	DDRD,0
	SBI	DDRD,1
	SBI	DDRD,2
	SBI	DDRD,3

;D = 11101110
	CBI	PORTD, 0
	SBI	PORTD, 1
	SBI	PORTD, 2
	SBI	PORTD, 3
	CBI	PORTD, 4
	SBI	PORTD, 5
	SBI	PORTD, 6
	SBI	PORTD, 7

; B vstupni:
	CBI	DDRB, 0
	CBI	DDRB, 1
	CBI	DDRB, 2
	CBI	DDRB, 3

; B pull-up
	SBI	PORTB, 0
	SBI	PORTB, 1
	SBI	PORTB, 2
	SBI	PORTB, 3

SMYCKA:
	LDI	R16, 0b11101110
	ROL	R16 ; rotujeme radky
	; C bit do R1, 0:
	CBR	R16, 1 ; R1, 0 se nastavi do nuly
	BRCS SET_R1_0
SMYCKA2:
	OUT PORTD, R16 ; zrotovane radky zpatky na vystup

	; urceni tlacitka:
	SBRS R16, 0
	LDI	R17, 0
	SBRS R16, 1 ; radek 1 --> budeme k cislu tlacitka pricitat 3
	LDI	R17, 4
	SBRS R16, 2 ; atd...
	LDI	R17, 8
	SBRS R16, 3
	LDI	R17, 12

	IN	R16, PINB ; zpracujeme vstup -- sloupce
	CPI R16, 0XFF ; stisklo se neco?
	BREQ SMYCKA ; ne (byly same jednicky) --> nova iterace
	
	; neco se stiRklo -- vypocteme cislo tlacitka
	; k cislu v R17 pricteme cislo sloupce:
	SBRS R16, 0
	LDI	R18, 0
	SBRS R16, 1
	LDI	R18, 1
	SBRS R16, 2
	LDI	R18, 2
	SBRS R16, 3
	LDI	R18, 3

	ADD R17, R18

	RCALL STISK

	RJMP SMYCKA ; nova iterace


STISK:
	; R17 obsahuje cislo stisknuteho tlacitka (0 az 15)
	CPI R17,9
	BRSH SMYCKA
	CPI R17,0
	BREQ PWM
	CPI R17,1
	BREQ PWM
	CPI R17,2
	BREQ PWM
	CPI R17,3
	BREQ PWM;
	CPI R17,4
	BREQ PWM;
	CPI R17,5;
	BREQ PWM
	CPI R17,6
	BREQ PWM
	CPI R17,7
	BREQ PWM
	CPI R17,8
	BREQ PWM
; OVLÁDA SE TLAČÍTKAMA 1 2 3 A 4 5 6 B
	RET

SET_R1_0: ; pomocna procedura pro presun Carry do registru (kvuli rotaci)
	SBR	R16, 1; R1 se nastavi do jednicky
	RJMP SMYCKA2
PWM:
	;MOV 	R17, R16
	INC		R17
	LDI		R18, 0xF8
	OR		R18, R16
PWM_ON:
	DEC		R17
	BREQ	PWM_OFF
	SBI		PORTB, FAN
	RCALL 	VERYSMALLWAIT
	RJMP	PWM_ON
PWM_OFF:
	INC		R18
	BREQ	PWM_RET
	CBI		PORTB, FAN
	RCALL 	VERYSMALLWAIT
	RJMP	PWM_OFF
PWM_RET:
	RET

VERYSMALLWAIT:
	LDI R22, 0xFC
	MOV R1, R20
SMALLWAIT:
	INC	R1
	BRNE	SMALLWAIT
	RET

[editovat] Větrák-softwarové

;
; P4 CPU fan Ucc pin is supposed to be connected 
; to +12 V, GND pin is supposed to be connected 
; to FET Drain, Source on GND, Gate on 
; pin 16 (PB2, FAN). Fan runs when FAN output is log. H.
;
; FAN is switched ON with switch between PC2 and PD2

	.INCLUDE "m88def.inc"  ; replaces previous lines of the program

	.EQU FAN = 2


; Pin driving FAN is set as output:

	SBI	DDRC, FAN


; D vystupni:
	SBI	DDRD,0
	SBI	DDRD,1
	SBI	DDRD,2
	SBI	DDRD,3

;D = 11101110
	CBI	PORTD, 0
	SBI	PORTD, 1
	SBI	PORTD, 2
	SBI	PORTD, 3
	CBI	PORTD, 4
	SBI	PORTD, 5
	SBI	PORTD, 6
	SBI	PORTD, 7

; B vstupni:
	CBI	DDRB, 0
	CBI	DDRB, 1
	CBI	DDRB, 2
	CBI	DDRB, 3

; B pull-up
	SBI	PORTB, 0
	SBI	PORTB, 1
	SBI	PORTB, 2
	SBI	PORTB, 3

SMYCKA:
	LDS	R16, 0b11101110
	ROL	R16 ; rotujeme radky
	; C bit do R1, 0:
	CBR	R16, 1 ; R1, 0 se nastavi do nuly
	BRCS SET_R1_0
SMYCKA2:
	OUT PORTD, R16 ; zrotovane radky zpatky na vystup

	; urceni tlacitka:
	SBRS R16, 0
	LDI	R17, 0
	SBRS R16, 1 ; radek 1 --> budeme k cislu tlacitka pricitat 3
	LDI	R17, 4
	SBRS R16, 2 ; atd...
	LDI	R17, 8
	SBRS R16, 3
	LDI	R17, 12

	LDS	R16, PORTB ; zpracujeme vstup -- sloupce
	ORI R16, PORTB ; vyssi pulku bytu dame do 1
	CPI R16, 255 ; stisklo se neco?
	BREQ SMYCKA ; ne (byly same jednicky) --> nova iterace
	
	; neco se stiRklo -- vypocteme cislo tlacitka
	; k cislu v R17 pricteme cislo sloupce:
	SBRS R16, 0
	LDI	R18, 0
	SBRS R16, 1
	LDI	R18, 1
	SBRS R16, 2
	LDI	R18, 2
	SBRS R16, 3
	LDI	R18, 3

	ADD R17, R18

	RCALL STISK

	RJMP SMYCKA ; nova iterace


STISK:
	; R17 obsahuje cislo stisknuteho tlacitka (0 az 15)
	LDI R17, 8 ;SMAZAT!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
	CPI R17,9
	BRSH SMYCKA
	CPI R17,0
	BREQ PWM
	CPI R17,1
	BREQ PWM
	CPI R17,2
	BREQ PWM
	CPI R17,3
	BREQ PWM;
	CPI R17,4
	BREQ PWM;
	CPI R17,5;
	BREQ PWM
	CPI R17,6
	BREQ PWM
	CPI R17,7
	BREQ PWM
	CPI R17,8
	BREQ PWM
; OVLÁDA SE TLAČÍTKAMA 1 2 3 A 4 5 6 B
	RET

SET_R1_0: ; pomocna procedura pro presun Carry do registru (kvuli rotaci)
	SBR	R16, 1; R1 se nastavi do jednicky
	RJMP SMYCKA2

PWM:
	MOV 	R20, R17
	INC		R20
	LDI		R21, 0xF8
	OR		R21, R1
PWM_ON:
	DEC		R20
	BREQ	PWM_OFF
	SBI		PORTC, FAN
	RCALL 	VERYSMALLWAIT
	RJMP	PWM_ON
PWM_OFF:
	INC		R21
	BREQ	PWM_RET
	CBI		PORTC, FAN
	RCALL 	VERYSMALLWAIT
	RJMP	PWM_OFF
PWM_RET:
	RET

VERYSMALLWAIT:
	LDI R22, 0xFC
	MOV R1, R20
SMALLWAIT:
	INC	R1
	BRNE	SMALLWAIT
	RET

[editovat] Klávesnice


	.EQU DDRB = $17		; DDRB address
	.EQU PORTB = $18	; PORTB address
	.EQU PINB = 0x16

	.EQU DDRD = $11
	.EQU PORTD = $12
	.EQU PIND = $10

; Pins connected to LED are outputs, DDRx=1 (set):

; D vystupni:
	SBI	DDRD,0
	SBI	DDRD,1
	SBI	DDRD,2
	SBI	DDRD,3

;D = 11101110
	CBI	PORTD, 0
	SBI	PORTD, 1
	SBI	PORTD, 2
	SBI	PORTD, 3
	CBI	PORTD, 4
	SBI	PORTD, 5
	SBI	PORTD, 6
	SBI	PORTD, 7

; B vstupni:
	CBI	DDRB, 0
	CBI	DDRB, 1
	CBI	DDRB, 2
	CBI	DDRB, 3

; B pull-up
	SBI	PORTB, 0
	SBI	PORTB, 1
	SBI	PORTB, 2
	SBI	PORTB, 3

SMYCKA:
	LDS	R16, 0b11101110
	ROL	R16 ; rotujeme radky
	; C bit do R1, 0:
	CBR	R16, 1 ; R1, 0 se nastavi do nuly
	BRCS SET_R1_0
SMYCKA2:
	OUT PORTD, R16 ; zrotovane radky zpatky na vystup

	; urceni tlacitka:
	SBRS R16, 0
	LDI	R17, 0
	SBRS R16, 1 ; radek 1 --> budeme k cislu tlacitka pricitat 3
	LDI	R17, 4
	SBRS R16, 2 ; atd...
	LDI	R17, 8
	SBRS R16, 3
	LDI	R17, 12

	LDS	R16, PORTB ; zpracujeme vstup -- sloupce
	ORI R16, PORTB ; vyssi pulku bytu dame do 1
	CPI R16, 255 ; stisklo se neco?
	BREQ SMYCKA ; ne (byly same jednicky) --> nova iterace
	
	; neco se stiRklo -- vypocteme cislo tlacitka
	; k cislu v R17 pricteme cislo sloupce:
	SBRS R16, 0
	LDI	R18, 0
	SBRS R16, 1
	LDI	R18, 1
	SBRS R16, 2
	LDI	R18, 2
	SBRS R16, 3
	LDI	R18, 3

	ADD R17, R18

	RCALL STISK

	RJMP SMYCKA ; nova iterace


STISK:
	; R17 obsahuje cislo stisknuteho tlacitka (0 az 15)
	CPI R17,16
	BRSH SMYCKA
	CPI R17,0
	BREQ JEDNA
	CPI R17,1
	BREQ JEDNA
	CPI R17,2
	BREQ JEDNA
	CPI R17,3
	BREQ JEDNA;
	CPI R17,4
	BREQ JEDNA;
	CPI R17,5;
	BREQ JEDNA
	CPI R17,6
	BREQ JEDNA
	CPI R17,7
	BREQ JEDNA
	CPI R17,8
	BREQ JEDNA
	CPI R17,9
	BREQ JEDNA
	CPI R17,10
	BREQ JEDNA
	CPI R17,11
	BREQ JEDNA
	CPI R17,12
	BREQ JEDNA
	CPI R17,13
	BREQ JEDNA
	CPI R17,14
	BREQ JEDNA
	CPI R17,15
	BREQ JEDNA

	RET

SET_R1_0: ; pomocna procedura pro presun Carry do registru (kvuli rotaci)
	SBR	R16, 1; R1 se nastavi do jednicky
	RJMP SMYCKA2

JEDNA:
	RJMP SMYCKA

[editovat] Větrák jedna

; 
; example fan program for ATmega88
;
; P4 CPU fan Ucc pin is supposed to be connected 
; to +12 V, GND pin is supposed to be connected 
; to FET Drain, Source on GND, Gate on 
; pin 16 (PB2, FAN). Fan runs when FAN output is log. H.
;
; FAN is switched ON with switch between PC2 and PD2


	.EQU DDRB = $04
	.EQU PORTB = $05

	.EQU DDRC = $07
	.EQU PORTC = $08
	.EQU PINC = $06

	.EQU DDRD = $0A
	.EQU PORTD = $0B
	.EQU PIND = $09

;	.INCLUDE "m88def.inc"  ; replaces previous lines of the program

	.EQU FAN = 2


; Pin driving FAN is set as output:

	SBI	DDRB, FAN

; Basic keyboard init:

; One switch of matrix keyboard is connected between PINC 2 a PIND 2
; Zero values of DDRC, 2 and PORTB, 2 are implicit

	SBI DDRD, 2
	SBI PORTC, 2


; Init:
	RCALL   FAN_OFF

GO:	SBIS	PINC, 2
	RCALL	FAN_PWM   ; Simple PWM control of the FAN, if the key is pressed
	RJMP	GO


;;;
;;;
;;; P R O C E D U R E S
;;;
;;;
	
VERYSMALLWAIT:
	LDI R20, 0xFC
	MOV R1, R20
SMALLWAIT:
	INC	R1
	BRNE	SMALLWAIT
	RET

	
FAN_ON:
	SBI	PORTB, FAN
	RET

FAN_OFF:
	CBI	PORTB, FAN
	RET

FAN_PWM:
	RCALL	FAN_ON
	RCALL	VERYSMALLWAIT  ; pulse ratio controlled by number of waits
	RCALL	VERYSMALLWAIT  ; 4:1 in this case
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	FAN_OFF
	RCALL	VERYSMALLWAIT 

	RET

[editovat] Led dioda s talčítkem

example LED-show program for ATtiny 2313
;
; 2-color LED with 300 Ohm resistor in series is supposed to be
; 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 DDRB = $17		; DDRB address
	.EQU PORTB = $18	; PORTB address
	.EQU PINB = 0x16

	.EQU LED_X = 0		; LED_X is on PB0, pin 12 of ATtiny2313
	.EQU LED_Y = 1		; LED_Y is on PB1, pin 13 of ATtiny2313


	.EQU DDRD = $11
	.EQU PORTD = $12
	.EQU PIND = $10

; Pins connected to LED are outputs, DDRx=1 (set):

	SBI	DDRB, LED_X	; SBI - Set Bit in I/O Register
	SBI	DDRB, LED_Y
	SBI DDRD, 3  ; PD2 is output - ROW
	CBI PORTD, 3  ; PD2=0
	CBI DDRB, 2   ; PC2 is input - COLUMN
	SBI PORTB, 2 ; enables pull-up resistor on this pin
	SBI DDRD, 5  ; PD2 is output - ROW
	CBI PORTD, 5  ; PD2=0
	CBI DDRB, 0   ; PC2 is input - COLUMN
	SBI PORTB, 0 ; enables pull-up resistor on this

SHOW:	
	SBIS	PINB, 2
	SBIS 	PINB, 0
	RJMP HVEZDICKA
	RJMP ACKO
	
	RJMP SHOW		; RJMP - Relative Jump 

;;;
;;;
;;; P R O C E D U R E S
;;;
;;;
HVEZDICKA:
	RCALL	COLOR2
	RCALL	WAIT
	RET
ACKO:
	RCALL   COLOR1
	RCALL	WAIT
	RET

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
Osobní nástroje