; ; Whippleway Experiment 8 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 exmp0_0 ;TARGET JUMP - Change try different examples. ; ; Experiment 1 Example 0 - Load a register with an 8-bit value and output to Data LEDS ; exmp0_0: call ssinp ;get sense switches call LEDout ;display in LEDs rjmp exmp0_0 ; ; Experiment 1 Example 1 - Load a register with an 8-bit value and output to Data LEDS ; exmp1_1: ldi r16, 0b00001010 ;012Q -> r16 call LEDout ;r16 -> LEDS jmp exmp1_1 ; ; Experiment 1 Example 2 - Load a register (r17) with 125Q, move it another register (r16), and output to Data LEDS ; exmp1_2: ldi r17, 0b01010101 ;125Q -> r17 mov r16, r17 ;r17 -> r16 call LEDout ;r16 -> LEDS rjmp exmp1_2 ; ; Experiment 2 Example 1 - Add 25 and 12 then display. The answer is 37 or 045Q. ; ; Using subtract immediate ; exmp2_1a: ldi r16, 25 ;25 -> r16 subi r16, -12 ;r16 - (-12) -> r16 call LEDout ;r16 -> LEDs rjmp exmp2_1a ; ; Experiment 2 Example 1 - Add 25 and 12 then display. The answer is 37 or 045Q. ; ; Using add immediate macro ; exmp2_1b: ldi r16, 25 ;25 -> r16 addi r16, 12 ;r16 + 12 -> r16 call LEDout ;r16 -> LEDs rjmp exmp2_1b ; ; Experiment 2 Example 2 - Add 25 and 12 with Carry then display. The answer is 38 or 046Q. ; ; Using additional register ; exmp2_2: sec ;Set Carry ldi r16, 25 ;25 -> r16 ldi r17, 12 ;12 -> r17 adc r16, r17 ;r16 + r17 -> r16 call LEDout ;r16 -> LEDs rjmp exmp2_2 ; ; Experiment 2 Example 3 - Subtract 12 from 25 then display. The answer is 13 or 015Q. ; ; Using subtract immediate ; exmp2_3: ldi r16,25 ;25 -> r16 subi r16,12 ;r16 - 12 -> r16 call LEDout ;r16 -> LEDs rjmp exmp2_3 ; ; Experiment 2 Example 4 - subtract 12 from 25 with borrow then display. The answer is 12 or 014Q. ; ; Using subtract immediate ; exmp2_4: sec ;Set Carry ldi r16,25 ;25 -> r16 sbci r16,12 ;12 -> r17 call LEDout ;r16 -> LEDs rjmp exmp2_4 ; ; Experiment 2 Example 5 - Show that -(-25) = 25. ; ; Using the ATmega328 negation instruction (NEG) ; exmp2_5: ldi r16,-25 ;-25 -> r16 neg r16 ;-(-25) -> r16 call LEDout ;r16 -> LEDs rjmp exmp2_5 ; ; Experiment 2 Example 6a - Add two values then display. The answer is 43 or 053Q for first values in table. ; ; Using two registers ; exmp2_6a: ldi r16,25 ;25 -> r16 ldi r17,18 ;18 -> r17 add r16,r17 ;r16 + r17 -> r16 call LEDout ;r16 -> LEDs rjmp exmp2_6a ; ; Experiment 2 Example 6b - Subtract two values then display. The answer is 7 or 007Q for first values in table. ; ; Using two registers ; exmp2_6b: ldi r16,25 ;25 -> r16 ldi r17,18 ;18 -> r17 sub r16,r17 ;r16 - r17 -> r16 call LEDout ;r16 -> LEDs rjmp exmp2_6b ; ; Experiment 3 Example 1a - Basic logical operations OR. The result is 0b10101111. ; ; Using OR immediate to set bits ; ; Turns on lower four bits and leaves upper four bits unchanged. ; exmp3_1a: ldi r16,0b10101010 ;0b010101010 -> r16 ori r16,0b00001111 ;r16 OR 0b00001111 -> r16 call LEDout ;r16 -> LEDs rjmp exmp3_1a ; ; Experiment 3 Example 1b - Basic logical operations AND. The result is 0b00001010. ; ; Using AND immediate to clear bits ; ; Turns off upper four bits and leaves lower four bits unchanged; i.e., masks the lower four bits. ; exmp3_1b: ldi r16,0b10101010 ;0b010101010 -> r16 andi r16,0b00001111 ;r16 AND 0b00001111 -> r16 call LEDout ;r16 -> LEDs rjmp exmp3_1b ; ; Experiment 3 Example 1c - Basic logical operations EOR (Exclusive-Or). The result is 0b10100101. ; ; Using register to register excluisive-or (EOR) to negate (flip) bits ; ; Flips the lower four bits and leaves the upper four bits unchanged. ; exmp3_1c: ldi r16,0b10101010 ;0b10101010 -> r16 ldi r17,0b00001111 ;0b00001111 -> r17 eor r16,r17 ;r16 EOR r17 -> r16 call LEDout ;r16 -> LEDs rjmp exmp3_1c ; ; Experiment 3 Example 2 ; ; Assign lights to bit positions in portd ; .equ Front_Porch = 1 .equ Back_Porch = 1<<1 .equ West_Front_Flood = 1<<2 .equ East_Front_Flood = 1<<3 .equ West_Back_Flood = 1<<4 .equ East_Back_Flood = 1<<5 .equ All_Lights = East_Back_Flood | West_Back_Flood | East_Front_Flood | West_Front_Flood | Back_Porch | Front_Porch ; ; Experiment 3 Example 2 Part a - Bit Manipulation ; ; Using OR and AND immediate as in Intel 8080 experiment ; ; Turn all lights off. Turn all lights on. Turn off all except front and back porch. Repeat. ; ; exmp3_2a: ldi r16,0 ;clear r16 exmp3_2a_loop: andi r16,0 ;turn off any lights that are on out portd,r16 ;update portd call delay ;wait 2 seconds ori r16,All_Lights ;turn on all lights out portd,r16 ;update portd call delay ;wait 2 seconds andi r16,(Front_Porch | Back_Porch) ;clear all bits except 0 and 1 out portd,r16 ;turn off all lights except front and back porch call delay ;wait 2 seconds rjmp exmp3_2a_loop ;repeat ; ; Experiment 3 Example 2 Part b - Bit Manipulation ; ; Using ATmega328 bit level instructions ; ; Turn all lights off. Turn all lights on. Turn off all except front and back porch. Repeat. ; .def Lights = r16 ; exmp3_2b: clr Lights ;clear lights register exmp3_2b_loop: cbr Lights,All_Lights ;turn off any lights that are on out portd,Lights ;update portd call delay ;wait 2 seconds sbr Lights,All_Lights ;turn on all lights out portd,Lights ;update portd call delay ;wait 2 second clr Lights ;clear light register sbr Lights,Front_Porch | Back_Porch ;turn on front and back porch lights out portd,Lights ;update portd call delay ;wait 2 second rjmp exmp3_2b_loop ;repeat full sequence ; ; Experiment 3 Example 2a Part c- Bit Manipulation ; ; Using ATmega328 I/O port direct bit level instructions ; ; Turn on and off back porch. ; exmp3_2c: clr r16 ;clear r16 exmp3_2c_loop: cbi portd,1 ;turn off back porch (bit 1) call delay ;wait 2 seconds sbi portd,1 ;turn on back porch (bit 1) call delay ;wait 2 second rjmp exmp3_2c_loop ;repeat full sequence ; ; Experiment 3 Example 3 Part a - Masking ; ; Using AND immediate ; ; Masks off upper three bits leaving lower five bits as temperature. ; exmp3_3a: ldi r16,0b01011011 ;preset room and temperature out portd,r16 ;update portd call delay ;wait 2 seconds andi r16,0b00011111 ;mask off upper three bits leaving temperature out portd,r16 ;update port d call delay ;wait 2 seconds rjmp exmp3_3a ; ; Experiment 3 Example 3 Part b - Masking ; ; Using CBR bit level instruction ; ; Masks off (clear) upper three bits leaving lower five bits as temperature. ; exmp3_3b: ldi r16,0b01011011 ;preset room and temperature out portd,r16 ;update portd call delay ;wait 2 seconds cbr r16,0b11100000 ;mask off (clear) upper three bits leaving temperature out portd,r16 ;update port d call delay ;wait 2 seconds rjmp exmp3_3b ; ; Experiment 3 Example 3 Part c - Masking ; ; Using CBR bit level and rotate ; ; Masks off (clear) lower five bits leaving upper three bits. Rotate five right to get room number. ; exmp3_3c: ldi r16,0b01011011 ;preset room and temperature out portd,r16 ;update portd call delay ;wait 2 seconds cbr r16,0b00011111 ;mask off (clear) lower five bits leaving room number ror r16 ;rotate right ror r16 ;rotate right ror r16 ;rotate right ror r16 ;rotate right ror r16 ;rotate right out portd,r16 ;update port d call delay ;wait 2 seconds rjmp exmp3_3c ; ; Experiment 3 Example 3 Part d - Masking ; ; Using CBR bit level, swap, and rotate ; ; Masks off lower five bits leaving upper three bits. Swap nibbles and one rotate right. ; exmp3_3d: ldi r16,0b01011011 ;preset room and temperature out portd,r16 ;update portd call delay ;wait 2 seconds cbr r16,0b00011111 ;mask off (clear) lower five bits leaving room number swap r16 ;swap upper and lower nibble ror r16 ;rotate right out portd,r16 ;update port d call delay ;wait 2 seconds rjmp exmp3_3d ; ; Experiment 3 Example 3 Part e - Masking ; ; Using CBR bit level and fractional multiply ; ; Masks off (clear) lower five bits leaving upper three bits. Multiply by 1/32 to get room number. ; exmp3_3e: ldi r16,0b01011011 ;preset room and temperature out portd,r16 ;update LEDs call delay ;wait 2 seconds cbr r16,0b00011111 ;mask off (clear) lower five bits leaving room number ldi r17,0b00000100 ;prepare to multiply by 1/32 (assumes 1.7 binary format i.e. 0.0000100) fmul r16,r17 ;fractional unsigned multiply out portd,r1 ;MSB of product is room number call delay ;Wait 2 seconds rjmp exmp3_3e ; ; Experiment 3 Example 4 ; ; Assign door switches to bit positions in portb (bit = 1 door closed) ; .equ Front_Driver = 0 .equ Front_Passenger = 1 .equ Rear_Driver = 2 .equ Rear_Passenger = 3 .equ Cargo = 4 .equ Hood = 5 .equ All_Doors = 1<= 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