Created
November 27, 2014 00:02
-
-
Save BobBurns/297a090eb7a5e2db984b to your computer and use it in GitHub Desktop.
example program using pin change interrupts from AVR Programming by Elliot Williams
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;Capacitive sensor demo in avr assembly | |
;compile with gavrasm capSense.asm | |
;flash with avrdude -c avrisp -p m168 -P /dev/tty.usbmodem1411 -b 19200 -U flash:w:capSense.hex | |
; | |
; | |
;what I learned from this program: | |
; always save the status reg when using interrupts | |
; and use the right jump vector for interrupt calls | |
; and keep track of registers used in subroutines | |
; | |
;1mhz clock speed X2, 9600 baud UBBR = 12 | |
.equ UBBRvalue = 12 | |
.equ UCSR0C = 0xc2 ;SRAM address of UCSR0C | |
.def temp = r16 | |
.def temp2 = r17 | |
.def trans_t = r18 | |
.def I_temp = r19 | |
.def xL = r26 ;x reg used as global counter | |
.def xH = r27 | |
.def zL = r30 | |
.def zH = r31 | |
.device atmega168 | |
;---- global variables ---- | |
.dseg | |
cc_count: .byte 2 ;remember this is big endian | |
.cseg | |
.org 0 | |
jmp reset | |
.org 0x0008 ;PCINT1 vector | |
jmp c_change ;pcint1 | |
c_change: | |
in temp,SREG ;save status register | |
adiw xH:xL,1 | |
sbi DDRC,PC1 | |
ldi I_temp,4 | |
i_lp: dec I_temp | |
brne i_lp ;8mhz clock for 1us delay | |
cbi DDRC,PC1 | |
in I_temp,PCIFR | |
sbr I_temp,(1 << PCIF1) | |
out PCIFR,I_temp | |
out SREG,temp | |
reti | |
.undef I_temp | |
;----- Main ----- | |
.org 0x0034 | |
reset: | |
cli | |
lds temp,CLKPR ;clock_prescale_set | |
sbr temp,(1 << CLKPCE) | |
sts CLKPR,temp | |
ldi temp,0x00 | |
sts CLKPR,temp ;set full speed = 8Mhz | |
;inittialize Stack | |
ldi temp,low(RAMEND) | |
out SPL,temp | |
ldi temp,high(RAMEND) | |
ldi temp,high(RAMEND) | |
out SPH,temp | |
;initialize USART | |
ldi temp,high(UBBRvalue) ;baud rate param | |
sts UBRR0H,temp | |
ldi temp,low(UBBRvalue) | |
sts UBRR0L,temp | |
lds temp,UCSR0A | |
ori temp,(1 << U2X0) ;set use 2x because %error actual baud > .5 | |
sts UCSR0A,temp | |
;--- USART register values | |
ldi temp,(1 << TXEN0) | (1 << RXEN0) ;enable transmit and receive | |
sts UCSR0B,temp | |
ldi temp,(1 << UCSZ01) | (1 << UCSZ00) ;8 data bits, 1 stop bit | |
sts UCSR0C,temp | |
;--- send a message | |
ldi zH, high(cap_str * 2) | |
ldi zL, low(cap_str * 2) | |
rcall print_s | |
;--- set ddr --- | |
ldi temp,0xff | |
out DDRB,temp ;set output on leds | |
;--- disable all pullups | |
in temp,MCUCR | |
sbr temp,(1 << PUD) | |
out MCUCR,temp | |
sbi PORTC,PC1 ;leave output high on pc1 | |
;--- init pin change interrupt --- | |
lds temp,PCICR | |
sbr temp,(1 << PCIE1) | |
sts PCICR,temp | |
lds temp,PCMSK1 | |
sbr temp,(1 << PC1) ;enable pin-change interrupts for 1 (bank C) | |
sts PCMSK1,temp ;enable specific interupt for pin PC1 | |
;--- event loop --- | |
loop: | |
ldi temp,0x00 | |
ldi xH,0x00 | |
ldi xL,0x00 ;xReg is counter | |
sbi DDRC,PC1 ;start with cap charged | |
sei ;set global interupt | |
.equ d_cnt = 50000 ;inline delay | |
ldi temp2,1 | |
outer: ldi r24,low(d_cnt) | |
ldi r25,high(d_cnt) | |
delay: sbiw r25:r24,1 | |
nop ;this makes four clock cycles = 200,000 us | |
brne delay | |
dec temp2 | |
brne outer | |
cli ;clear global interrupt | |
.equ thresh = 12000 | |
;compare threshhold with count / should work with just high bytes | |
cpi xH,high(thresh) | |
brlt led_on | |
ldi temp,0x00 | |
out PORTB,temp | |
out PORTB,temp | |
rjmp msg | |
led_on: ldi temp,0xff | |
out PORTB,temp | |
msg: | |
mov r24,xH | |
rcall transmit | |
mov r24,xL | |
rcall transmit | |
ldi r24,0x0d | |
rcall transmit | |
ldi r24,0x0a | |
rcall transmit | |
rjmp loop | |
; | |
;--- Subroutines --- | |
;print string function | |
;takes Z loaded with pointer to string with first byte being length | |
;uses r16,r18,r24 | |
.def byte_tx = r24 | |
.def count = r18 | |
print_s: | |
lpm count,Z+ | |
for1: lpm byte_tx,Z+ | |
wait: lds temp,UCSR0A | |
sbis temp,UDRE0 ;wait for Tx buffer to be empty | |
rjmp wait ;not ready | |
sts UDR0,byte_tx; | |
dec count | |
brne for1 | |
ret | |
;send one byte | |
;uses r24 as byte to send | |
transmit: | |
lds trans_t,UCSR0A | |
sbis trans_t,UDRE0 | |
rjmp transmit | |
sts UDR0,r24 | |
ret | |
cap_str: .db 22,"==[ Cap sensor ]==",0x0d,0x0a,0x0d,0x0a,0x00 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment