Created
May 9, 2012 12:47
-
-
Save lukecameron/2644258 to your computer and use it in GitHub Desktop.
an AVR assembly program to toggle PORTC when INT0 or INT1 is triggered by falling edge
This file contains hidden or 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
| /* | |
| * toggle.asm | |
| * | |
| * Created: 9/05/2012 9:07:24 PM | |
| * Author: Luke Cameron (lukecameron) | |
| * | |
| * Toggle the led's when pb0 is pressed. | |
| * wire pb0 to pd0, leds to portc | |
| * some code copied from example 3.1 | |
| */ | |
| .include "m64def.inc" | |
| .def temp = r16 | |
| ;; set up the interrupt vector | |
| jmp reset | |
| .org INT0addr ; INT0addr is the address of EXT_INT0 | |
| jmp handle_pb0 | |
| .org INT1addr ; INT1addr is the address of EXT_INT1 | |
| jmp handle_pb1 | |
| /* | |
| by the way, INT0 means External Interrupt 0. | |
| Don't ask me why... | |
| note: it so happens that INT0 is hooked up to the PD0 pin. | |
| Here are the mappings: | |
| INT0: PD0 | |
| INT1: PD1 | |
| INT2: PD2 | |
| INT3: PD3 | |
| INT4: PE4 | |
| INT5: PE5 | |
| INT6: PE6 | |
| INT7: PE7 | |
| (from pg2 of atmega64 datasheet) | |
| */ | |
| reset: | |
| ;; init the stack | |
| ldi temp, low(RAMEND) | |
| out SPL, temp | |
| ldi temp, high(RAMEND) | |
| out SPH, temp | |
| ;; set DDRC to 0xFF. | |
| ;; DDRC is data direction register C | |
| ;; there are 8 pins, so setting 8 bits | |
| ;; to 1 sets the 8 pins for output. | |
| ser temp | |
| out DDRC, temp | |
| ;; set int1 and int0 for falling edge trigger. | |
| ;; this one's gonna need some explanation | |
| ldi temp, (1 << ISC11) | (1 << ISC01) | |
| sts EICRA, temp | |
| ;; so EICRA is the External Interrupt Control | |
| ;; Register A. (Atmega64 datasheet pg 88). | |
| ;; It controls the interrupt mode of INT0-INT3 | |
| ;; each of these four interrupts has two bits | |
| ;; associated with it. The order is like this: | |
| ;; 33221100, where 0 means INT0. | |
| ;; In each pair, the right-most bit is called bit 0, | |
| ;; and the left-most bit is called bit 1. | |
| ;; table 48 on pg89 of the atmega64 datasheet | |
| ;; shows you what they do. we're looking for | |
| ;; falling edge, so we need to set each pair to '10' | |
| ;; however, we're given some handy constants in m64def.inc | |
| ;; that mean we don't have to do this. They store the number | |
| ;; of left-shifts you would need to do to 1 to set only that bit. | |
| ;; for example, to set bit 1 of int3, you would set EICRA to | |
| ;; 1 << ISC31. If you want to set multiple bits, just keep | |
| ;; writing them and ORing them together with "|". | |
| ;; by the way, ISC stands for "interrupt sense control" | |
| ;; | is bitwise Or | |
| ;; << is left shift | |
| ;; that was long.. | |
| ;; enable int0 and int1 | |
| in temp, EIMSK | |
| ori temp, (1<<INT0) | (1<<INT1) | |
| out EIMSK, temp | |
| ;; so EIMSK is the External Interrupt Mask Register | |
| ;; its eight bits are used to enable the eight | |
| ;; external interupts int0-int7. | |
| ;; it's basically the same setup as before. | |
| ;; we use the ori instruction to preserve any previously | |
| ;; enabled interrupts even though there obviously aren't any. | |
| ;; this just enables the interrupt enable bit | |
| ;; of the status register. This is needed. | |
| sei | |
| main: | |
| rjmp main | |
| ;; this is the handler for PushButton0 | |
| handle_pb0: | |
| ;; push conflict registers | |
| push temp | |
| in temp, SREG | |
| push temp | |
| in temp, PORTC | |
| com temp | |
| out PORTC, temp | |
| ;; restore conflict registers | |
| pop temp | |
| out SREG, temp | |
| pop temp | |
| reti | |
| ;; this is exactly the same as the handler for PushButton0 | |
| handle_pb1: | |
| ;; push conflict registers | |
| push temp | |
| in temp, SREG | |
| push temp | |
| in temp, PORTC | |
| com temp | |
| out PORTC, temp | |
| ;; restore conflict registers | |
| pop temp | |
| out SREG, temp | |
| pop temp | |
| reti |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment