; ; Whippleway Experiment 9 for the ATmega328 ; ; Created: 3/28/2017 8:06:37 PM ; Author : Dick Whipple ; ; Add Immediate Macro ; .macro addi subi @0, -@1 ;subtract the negative of an immediate value .endmacro ; start: ldi r16,0b00000000 ;set all bits of port b to input out ddrb,r16 ldi r16,0b11111111 ;turn on pull-up resistors on all bits of portb out portb,r16 ldi r16,0b00000000 ;set all bits of port c to input out ddrc,r16 ldi r16,0b11111111 ;turn on pull-up resistors on all bits of port c out portc,r16 ldi r16,0b11111111 ;set all bits of port d to output out ddrd,r16 ; jmp exmp4_1 ;TARGET JUMP - Change try different examples. ; ; Experiment 4 Example 1 - Basic I/O ; ; Using IN and OUT instructions ; ; Set sense switches to 0b00xxxxxx (any one or more x's set and all others closed) ; ; Data LEDs display complement pattern ; ; Note: (1) Bits 0 to 5 of portb connect directly to senses switches 1 to 6. Sense switches 7 and 8 are connected ; to bits 1 and 2 of portc. (2) When inputting sense switch portb directly, "up" produces cleared (0) bit while "down" a ; set (1) bit. ; exmp4_1: in r16,pinb ;get lower six bits of sense switches out portd,r16 ;update LEDs rjmp exmp4_1 ; ; Experiment 4 Example 2 - Two Way Selection (mask condition) ; ; Setting sense switch bit 7 = 1 displays a one (true) in Data LEDs. Otherwise, zero (false) is displayed. ; exmp4_2: call ssinp ;get sense switches into R16 andi r16,0b10000000 ;mask r16 to test bit 7 brne exmp4_2_true ;if r16 bit 7 = 1, branch to true sequence ; ; False sequence ; ldi r16,0 ;load zero (false) in r16 rjmp exmp4_2_exit ;branch to exit ; ; True sequence ; exmp4_2_true: ldi r16,1 ;load one (true) in r16 ; ; Exit ; exmp4_2_exit: call LEDout ;display r16 in Data LEDs rjmp exmp4_2 ;repeat ; ; Experiment 4 Example 3a - One Way Selection (mask condition) ; ; Sense switch bit 7 = 1 will produce a one (true) in Data LEDs ; exmp4_3a: call ssinp ;get sense switches into R16 andi r16,0b10000000 ;mask r16 to test bit 7 ldi r16,0 ;preload r16 with zero (false) breq exmp4_3a_exit ;if r16 bit 7 = 0, branch to exit ; ; True sequence ; ldi r16,1 ;load one (true) in r16 ; ; Exit ; exmp4_3a_exit: call LEDout ;display r16 in Data LEDs rjmp exmp4_3a ;repeat ; ; Experiment 4 Example 3b - One Way Selection (mask condition using skip instruction) ; ; Sense switch bit 7 = 1 will produce a one (true) in Data LEDs ; ; Reads I/O port c pin (bit) 1 directly. Recall that Sense Switch 7 up produces a zero on portc bit 1 ;. exmp4_3b: ldi r16,0 ;preload r16 with zero (false) sbis pinc,1 ;if portc pin (bit) 1 = 1 (sense switch down), branch to exit ; ; True sequence ; ldi r16,1 ;load one (true) in r16 ; ; Exit ; exmp4_3b_exit: call LEDout ;display r16 in Data LEDs rjmp exmp4_3b ;repeat ; ; Experiment 4 Example 4a - Two Way Selection (unsigned comparison) ; ; Any sense switch input equal or greater than 120Q will produce a one (true) ; exmp4_4a: call ssinp ;get sense switches into R16 cpi r16,80 ;compare r16 to 80 (r16 - 80) brsh exmp4_4a_true ;if r16 >= 80 branch to true sequence ; ; False sequence ; ldi r16,0 ;zero (false) -> r16 rjmp exmp4_4a_exit ;branch to exit ; ; True sequence ; exmp4_4a_true: ldi r16,1 ;one (true) -> r16 ; ; Exit ; exmp4_4a_exit: call LEDout ;display r16 in Data LEDs rjmp exmp4_4a ;repeat ; ; Experiment 4 Example 4b - Two Way Selection (signed comparison) ; ; Try these sense switch settings: (1) 000Q = 0 >= -80 LEDs = 1 (True) ; (2) 261Q = -79 >= -80 LEDs = 1 (True) ; (3) 260Q = -80 >= -80 LEDs = 1 (True) ; (4) 257Q = -81 < -80 LEDs = 0 (False) ; exmp4_4b: call ssinp ;get sense switches into R16 cpi r16,-80 ;compare r16 to 80 (r16 - 80) brge exmp4_4b_true ;if r16 >= 80 branch to true sequence ; ; False sequence ; ldi r16,0 ;zero (false) -> r16 rjmp exmp4_4b_exit ;branch to exit ; ; True sequence ; exmp4_4b_true: ldi r16,1 ;one (true) ->r16 ; ; Exit ; exmp4_4b_exit: call LEDout ;display r16 in Data LEDs rjmp exmp4_4b ;repeat ; ; Experiment 4 Example 4c - One Way Selection (unsigned comparison) ; ; Any sense switch input less than 80 will produce a zero (false) ; exmp4_4c: call ssinp ;get sense switches into R16 cpi r16,80 ;compare r16 to 80 (r16 - 80) ldi r16,0 ;preload r16 with zero (false) brlo exmp4_4c_exit ;if r16 < 80 branch to exit ; ; True sequence ; ldi r16,1 ;load r16 with one (true) ; ; Exit ; exmp4_4c_exit: call LEDout rjmp exmp4_4c ;repeat ; ; Experiment 4 Example 5 - One Way Selection (arithmetic comparison - unsigned) ; ; Display the larger of 120 (170Q) and the value in the sense switches ; exmp4_5: ldi r17,120 ;load r17 with 120 call ssinp ;load r16 with sense switch value cp r17,r16 ;compare r17 to r16 (120 - r16) brlo exmp4_5_exit ;if r16 < 80 branch to exit ; ; True sequence - Switch registers ; mov r1,r16 ;r16 -> r1 (temporary register) mov r16,r17 ;r17 -> r16 mov r17,r1 ;r1 -> r17 ; ; Exit ; exmp4_5_exit: call LEDout ;display r16 in Data LEDs rjmp exmp4_5 ;repeat ; ; Experiment 4 Example 6 - One Way Selection ; ; Convert the low nibble of the sense switches from hex to ASCII ; exmp4_6: call ssinp ;load r16 with sense switch value andi r16, 0x0f ;mask off upper nibble addi r16,48 ;assume 0 to 9 and add 48 ASCII bias cpi r16,57 ;if r16 < 57, branch to exit brlo exmp4_6_exit ; ; True sequence ; addi r16,7 ;add additional 7 ASCII bias for 10 to 15 ; ; Exit ; exmp4_6_exit: call LEDout ;display r16 in Data LEDs ;0000 - ASCII 0 or 060Q to 1001 - ASCII 9 or 101Q ;1010 - ASCII A or 101Q to 1111 - ASCII F or 106Q rjmp exmp4_6 ;repeat ; ; LED Output Subroutine ; ; Outputs r16 to Data LEDS ; ; Registers Used: r5,r16 ; LEDout: in r5,pinc ;check status register button sbrs r5,2 ;if set, skip next instruction in r16,sreg ;otherwise replace contents of r16 with status register out portd,r16 ;output r16 to port d ret ; ; Sense Switch Input ; ; Inputs Sense Switches to r16 ; ; Registers Used: r5,r16,sreg ; ; Note. (1) Uses 6 bits of portb (bits 0 to 5) and 2 bits of portc (bits 0 to 1) (2) "Up" produces a set bit awhile "down" produces a cleard bit. ; ssinp: in r16,pinb ;get bits from port b into r16 andi r16,0x3f ;mask of bits 6 and 7 mov r5,r16 ;move r16 to r5 in r16,pinc ;get bits from port c into r16 andi r16,0b00000011 ;mask of bit 2 to 6 clc ;clear carry ror r16 ;rotate r16 right 3 times to get bits 0 and 1 into bits 6 and 7 ror r16 ror r16 or r16,r5 ;or r5 with r16 to merge the bits into r16 com r16 ;complement to correct for switch configuration ret ; ; 2 Second Delay ; ; Registers Used: r29,r30,r31 ; delay: ldi r29,120 ;use r29 to control number of full 16-bit count downs loop: sbiw r30,1 ;count down combined r30:r31 registers to zero brne loop ;if not zero, repeat count down dec r29 ;decrement r29 until zero brne loop ;if not zero, count down r30:r31 again. ret ;done and return