Input Buffer
Output Buffer
Tri-State Output Buffer
Pull-Up with Enable
Exerpt from "m169Pdef.inc"
.equ PINB = 0x03
.equ DDRB = 0x04
.equ PORTB = 0x05
in r16, PORTA
ori r16, 0b00000110
out PORTA, r16
in r16, PORTA
andi r16, 0b11111001
out PORTA, r16
in r16, PINA
andi r16, 0b00000110
breq botharelow
in r16, PINA
andi r16, 0b00000110
cpi r16, 0b00000110
breq botharehigh
Single-cycle manipulation of individual output port pins is a specialty of AVR
Ex: Thermo up/down
sbi PORTA, 0 ; .......*
sbi PORTA, 1 ; ......**
sbi PORTA, 2 ; .....***
sbi PORTA, 3 ; ....****
sbi PORTA, 4 ; ...*****
sbi PORTA, 5 ; ..******
sbi PORTA, 6 ; .*******
sbi PORTA, 7 ; ********
cbi PORTA, 7 ; .*******
cbi PORTA, 6 ; ..******
cbi PORTA, 5 ; ...*****
cbi PORTA, 4 ; ....****
cbi PORTA, 3 ; .....***
cbi PORTA, 2 ; ......**
cbi PORTA, 1 ; .......*
cbi PORTA, 0 ; ........
Preliminaries: Jumping
Combining skip and jump
.def=JOYSTICK_INPORT = PINB
.equ UP_BUTTON_BIT = 5;
.equ UP_BUTTON_MASK=(1<<UP_BUTTON_BIT);
.equ UP_BUTTON_MASK_CMP=(0xFF-UP_BUTTON_MASK);
.def RTEMP = r16;
;skip if bit in registger set followed by branch
; branch occurs if button was pressed
sbis JOYSTICK_INPORT, UP_BUTTON_BIT
rjump LABEL_BUTTON_RESPONSE
longer/slower alternative
in RETEMP, JOYSTICK_INPORT
andi RTEMP,UP_BUTTON_MASK
brne LABEL_BUTTON_RESPONSE
;Using CBI and SBI to write to ports
SBI DDRB, 1 ;make bit 1 as output bit on PORTB
CBI PORTB, 1 ;make PORTB bit 1 as "0"
SBI PORTB, 1 ;make PORTB bit 1 as "1"
Slow Alternative:
;Using OUT instruction to write to ports
LDI R18, 0b00010000
OUT DDRB, R18 ;make bit 1 as output bit on PORTB
LDI R18, 0b00000000
OUT PORTB, R18 ;make PORTB bit 1 as "0"
LDI R18, 0b00010000
OUT PORTB, R18 ;make PORTB bit 1 as "1“
Novice Note: A common error is that OUT DDRB, R18 doesn't just set bit 1 to a "1", it also sets all of the other bits to 0, so please favor the following methods to set bits
;simple input
IN R18,PINB
;set pin 5 of B port as output
; without affecting other bits
IN R18,DDRB
ORI R18, 0b00010000
OUT DDRB, R18
;set pin 5 of B port to 1
; without affecting other bits
IN R18,PORTB
ORI R18, 0b00100000
OUT PORTB, R18
;clear pin 5 of B port to 0
; without affecting other bits
IN R18,PORTB
ANDI R18, 0b11101111
OUT PORTB, R18
sbi and cbi are more convenient and allowed if only changing one bit at a time. If multiple bits need to be set at the same you can't use sbi/cbi
;set pin 7,3 of B port to 1 at same time
; without affecting other bits
IN R18,PORTB
ORI R18, 0b10001000
OUT DDRB, R18
Ex Cycle output pin 1 quickly:
sbi PORTB, 1
cbi PORTB, 1
sbi PORTB, 1
;toggle pin 1 of B using PINB "write-to-input trick"
OUT PINB, 0b00000010
Slow Alternative
;toggle pin 1 of B (no eori available)
; without affecting other bits
IN R18,PORTB
LDI R19,0b00000010
EOR R18, R19
OUT PORTB, R18
The common line of all directions is GND on the board. This means internal pull-up must be enabled on ATmega169P to detect the input.
Part:SKRHABE010
Schematic Drawing:

Mechanical Drawing:

Landing Drawing (Bottom View into mounting face):
https://tech.alpsalpine.com/prod/e/html/multicontrol/switch/skrh/skrhabe010.html
Board Schematic:
https://www.csee.umbc.edu/~alnel1/cmpe311/assignments/UserGuide.pdf
Can mention in-class and step through in discussion session
Can draw state machine with reference to numbers/labels from code
Code Was Developed Some Time ago on another plaform, may need syntax and other minor updates
/* test . asm
Created : 9/4/2012 10:50:44 AM
Author : rrobucci
*/
// above is the file header comment created by the tool
// . INCLUDE " m169Pdef.inc "
// optional , file was included by
// default when device was selected on project creation
// normally here we would define alias for ports , pins , and
// registers used instead of using magic numbers in the code
// LED on PB7 , button on PB6
// LED is " ON " when PB7 is high
// PB6 is low when button is pressed
// Will use R16 as temporary register
.ORG 0x00000
// * may press F1 with cursor over any instruction to see help
// * use F10 to step through code , note IO values that change
// * are highlighted in red
CBI DDRB , 6 // set direction for button
SBI PORTB , 6 // enable pull - up
// * in simulator , use the IOVIEW here and set PINB6 to
// * high to emulate button not being pressed
SBI DDRB , 7 // set direction for LED
// * in the simulator this loop should repeat until PINB6 is
// set low using the IOVIEW ;
CHECK_BUTTON : ; <<<<\
// skips jump back if bit 6 of port B input is set ; ^
SBIC PINB , 6 ; ^
JMP CHECK_BUTTON ; >>>>/
;
LED_BLINK : ; <<<<<<<<<<<<<<\
// Turn LED ON ; ^
SBI PORTB , 7 // sets bit of I / O ; ^
; ^
// Pause LOOP ; ^
// step through a few iterations using F10 and observe ; ^
// R16 changing in the processor tab ( highlighted with red ; ^
// upon change ) ; ^
LDI R16 , 255 // load immediate ; ^
; <<<<\ ^
BLINK_LOOP_ON : ; ^ ^
DEC R16 // decrement R16 , set zero flag if zero reached ; ^ ^
BRNE BLINK_LOOP_ON // * set breakpoint here using F9 ; >>>>/ ^
// * and press F5 to avoid stepping through all loop ; ^
// iterations ; ^
// Turn LED OFF ; ^
CBI PORTB , 7 // clears bit of I / O ; ^
; ^
LDI R16 ,127 // Pause ; ^
BLINK_LOOP_OFF : ; <<<<\ ^
DEC R16 ; ^ ^
BRNE BLINK_LOOP_OFF ; >>>>/ ^
JMP LED_BLINK // * using F9 , set breakpoints on the SBI and ; >>>>>>>>>>>>>>/
// CBI code lines above and repeatedly
// press F5 to see the LED pin toggle
Possible Organization of FSM Code
Additional Concepts:
substates
extended state variables
Triggers (when to perform FSM iterations)
Illusion of parallelism
Modify the Provide Code Detect an Input Sequence, while the lights are blinking