Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- Copyright 2011 Dustin L. Westaby
- ----------------------------------------------------------------------
- Rotary Encoder Code for ATtiny2313
- ----------------------------------------------------------------------
- Title: pb.c
- Author: Dustin Westaby
- Date Created: 08/08/11
- Last Modified: 08/08/11
- Purpose: Decodes two Rotary Encoders and three Pushbutton input controls
- simultaniously.
- Compiled with AVR-GCC WinAVR
- Revisions List:
- August 08, 2011 - Draft code written
- August 10, 2011 - Code now compiles
- ----------------------------------------------------------------------
- ----------------------------------------------------------------------
- Operating notes from the Rotary Encoder Datasheet
- AB A = A channel, B = B Channel
- 00 |
- 10 | Clockwise
- 11 V
- 01
- 00
- 10 ^
- 11 | Counter-Clockwise
- 01 |
- 00
- ATTiny2313 Pinouts
- +----v---+
- (RST)| 20 1 |(VCC)
- PD0 | 19 2 | PB7 (SCL)
- PD1 | 18 3 | PB6 (MISO)
- PA1 | 17 4 | PB5 (MOSI)
- PA0 | 16 5 | PB4
- PD2 | 15 6 | PB3
- PD3 | 14 7 | PB2
- PD4 | 13 8 | PB1
- PD5 | 12 9 | PB0
- (GND)| 11 10| PD6
- +--------+
- 17 Total
- Port A 0-1 Debug Output
- Port B 0-7 Inputs
- Port C N/A
- Port D 0-6 Outputs
- ---------------------------------------------------------------------- */
- //--------------------------------------
- // Global Variables |
- //--------------------------------------
- /* 8 MHz Internal Oscillator */
- #define F_CPU 8000000UL
- //Init some enumerated constants
- enum { knobA, knobB, wheelA, wheelB };
- enum { NONE, FORWARD, BACKWARD };
- enum { KNOB, WHEEL, LEDS };
- enum { PRESSED, NOTPRESSED };
- enum { LEDA, LEDB, LEDC };
- #define ON 0
- #define OFF 1
- //--------------------------------------
- // Includes |
- //--------------------------------------
- #include <avr/io.h>
- #include <util/delay.h>
- #include <avr/sleep.h>
- #include <avr/interrupt.h>
- #include <inttypes.h>
- //--------------------------------------
- // Delay Subroutines |
- //--------------------------------------
- void delay_ms(uint16_t ms) {
- while ( ms )
- {
- _delay_ms(1);
- ms--;
- }
- }
- void delay_us(uint16_t us) {
- while ( us )
- {
- _delay_us(1);
- us--;
- }
- }
- //--------------------------------------
- // Functions |
- //--------------------------------------
- void TurnOnOffLEDs(int Selection)
- {
- //Exit function if no Light change needed
- if (Selection == NONE) return;
- //turn on the selected LED, turn off others
- if (Selection == OFF)
- PORTB = 0b11111111;
- else if (Selection == LEDA)
- PORTB = 0b01111111;
- else if (Selection == LEDB)
- PORTB = 0b10111111;
- else if (Selection == LEDC)
- PORTB = 0b11011111;
- else
- PORTB = 0b01111111;
- }
- void startkeypress_timer(int KnobWheelLED, int TurnDirection)
- {
- //Exit function if no movement detected
- if (TurnDirection == NONE) return;
- //Determine what keypress is needed (ONE AT A TIME PLEASE!!!)
- if (KnobWheelLED == KNOB)
- {
- if (TurnDirection == FORWARD)
- {
- // Knob Forward
- // Set Keypress and Debug LED
- PORTD = 0b011101111;
- }
- else
- {
- // Knob Backward
- // Set Keypress and Debug LED
- PORTD = 0b10111011;
- }
- }
- else if (KnobWheelLED == WHEEL)
- {
- if (TurnDirection == FORWARD)
- {
- // Wheel Forward
- // Set Keypress and Debug LED
- PORTD = 0b11011101;
- }
- else
- {
- // Wheel Backward
- // Set Keypress and Debug LED
- PORTD = 0b11101110;
- }
- }
- else //Must be LED input
- {
- if (TurnDirection == LEDA)
- {
- // LED A
- // Set Keypress and Debug LED
- //PORTC = 0b01110111;
- }
- else if (TurnDirection == LEDB)
- {
- // LED B
- // Set Keypress and Debug LED
- //PORTC = 0b10111011;
- }
- else
- {
- // LED C
- // Set Keypress and Debug LED
- //PORTC = 0b11011101;
- }
- }
- //Hold key down for a while (Debug LED will blink)
- delay_ms(100);
- //Clear all Keypresses and blank Debug LEDs
- PORTA = 0b11111111;
- //PORTC = 0b11111111;
- //Don't allow another keypress for a while
- delay_ms(100);
- }
- void init()
- {
- //Debug output will be on Port A 0&1
- //Port A & D are outputs for Keypress & Debug
- DDRA = 0b11111111;
- PORTA = 0b00000000;
- DDRD = 0b11111111;
- PORTD = 0b00000000;
- //seven inputs for (two for each rotary encoder, three for the LED inputs)
- DDRB = 0b00000000;
- PORTB = 0b11111111;
- }
- //--------------------------------------
- // Main |
- //--------------------------------------
- int main(void)
- {
- int OldState[7]; //Old Status
- int NewState[7]; //New Status
- int TurnDirectionKnob;
- int TurnDirectionWheel;
- int LED_Select;
- int i;
- //Setup IO
- init();
- //Get First Input State
- OldState[knobA] = bit_is_clear(PINB, PB0);
- OldState[knobB] = bit_is_clear(PINB, PB1);
- OldState[wheelA] = bit_is_clear(PINB, PB2);
- OldState[wheelB] = bit_is_clear(PINB, PB3);
- OldState[LEDA] = bit_is_clear(PINA, PA0);
- OldState[LEDB] = bit_is_clear(PINA, PA1);
- OldState[LEDC] = bit_is_clear(PINA, PA2);
- NewState[knobA] = bit_is_clear(PINB, PB0);
- NewState[knobB] = bit_is_clear(PINB, PB1);
- NewState[wheelA] = bit_is_clear(PINB, PB2);
- NewState[wheelB] = bit_is_clear(PINB, PB3);
- NewState[LEDA] = bit_is_clear(PINA, PA0);
- NewState[LEDB] = bit_is_clear(PINA, PA1);
- NewState[LEDC] = bit_is_clear(PINA, PA2);
- //Setup LED lights
- TurnOnOffLEDs(LEDA);
- while(1)
- {
- //--------------------------------------------------------------------------
- // Setup for next Input State Change
- //--------------------------------------------------------------------------
- TurnDirectionKnob = NONE;
- TurnDirectionWheel = NONE;
- LED_Select = NONE;
- //Wait for Input State Change
- while(NewState == OldState)
- {
- NewState[knobA] = bit_is_clear(PINB, PB0);
- NewState[knobB] = bit_is_clear(PINB, PB1);
- NewState[wheelA] = bit_is_clear(PINB, PB2);
- NewState[wheelB] = bit_is_clear(PINB, PB3);
- NewState[LEDA] = bit_is_clear(PINA, PA0);
- NewState[LEDB] = bit_is_clear(PINA, PA1);
- NewState[LEDC] = bit_is_clear(PINA, PA2);
- }
- //--------------------------------------------------------------------------
- // Check for Knob movement and determine direction
- //--------------------------------------------------------------------------
- if((OldState[knobA]==0 && NewState[knobA]==1 && OldState[knobB]==0 && NewState[knobB]==0)|| //PHASE1
- (OldState[knobA]==1 && NewState[knobA]==1 && OldState[knobB]==0 && NewState[knobB]==1)|| //PHASE2
- (OldState[knobA]==1 && NewState[knobA]==0 && OldState[knobB]==1 && NewState[knobB]==1)|| //PHASE3
- (OldState[knobA]==0 && NewState[knobA]==0 && OldState[knobB]==1 && NewState[knobB]==0)|| //PHASE4
- (OldState[knobA]==0 && NewState[knobA]==1 && OldState[knobB]==0 && NewState[knobB]==0)) //PHASE5
- {
- TurnDirectionKnob = FORWARD;
- }
- else if((OldState[knobA]==0 && NewState[knobA]==0 && OldState[knobB]==0 && NewState[knobB]==1)|| //PHASE1
- (OldState[knobA]==0 && NewState[knobA]==1 && OldState[knobB]==1 && NewState[knobB]==1)|| //PHASE2
- (OldState[knobA]==1 && NewState[knobA]==1 && OldState[knobB]==1 && NewState[knobB]==0)|| //PHASE3
- (OldState[knobA]==1 && NewState[knobA]==0 && OldState[knobB]==0 && NewState[knobB]==0)|| //PHASE4
- (OldState[knobA]==0 && NewState[knobA]==0 && OldState[knobB]==0 && NewState[knobB]==1)) //PHASE5
- {
- TurnDirectionKnob = BACKWARD;
- }
- else //No movement detected for Knob
- TurnDirectionKnob = NONE;
- //Send Keypress
- startkeypress_timer(KNOB, TurnDirectionKnob);
- //--------------------------------------------------------------------------
- // Check for Wheel movement and determine direction
- //--------------------------------------------------------------------------
- if((OldState[wheelA]==0 && NewState[wheelA]==1 && OldState[wheelB]==0 && NewState[wheelB]==0)|| //PHASE1
- (OldState[wheelA]==1 && NewState[wheelA]==1 && OldState[wheelB]==0 && NewState[wheelB]==1)|| //PHASE2
- (OldState[wheelA]==1 && NewState[wheelA]==0 && OldState[wheelB]==1 && NewState[wheelB]==1)|| //PHASE3
- (OldState[wheelA]==0 && NewState[wheelA]==0 && OldState[wheelB]==1 && NewState[wheelB]==0)|| //PHASE4
- (OldState[wheelA]==0 && NewState[wheelA]==1 && OldState[wheelB]==0 && NewState[wheelB]==0)) //PHASE5
- {
- TurnDirectionWheel = FORWARD;
- }
- else if((OldState[wheelA]==0 && NewState[wheelA]==0 && OldState[wheelB]==0 && NewState[wheelB]==1)|| //PHASE1
- (OldState[wheelA]==0 && NewState[wheelA]==1 && OldState[wheelB]==1 && NewState[wheelB]==1)|| //PHASE2
- (OldState[wheelA]==1 && NewState[wheelA]==1 && OldState[wheelB]==1 && NewState[wheelB]==0)|| //PHASE3
- (OldState[wheelA]==1 && NewState[wheelA]==0 && OldState[wheelB]==0 && NewState[wheelB]==0)|| //PHASE4
- (OldState[wheelA]==0 && NewState[wheelA]==0 && OldState[wheelB]==0 && NewState[wheelB]==1)) //PHASE5
- {
- TurnDirectionWheel = BACKWARD;
- }
- else //No movement detected for Wheel
- TurnDirectionWheel = NONE;
- //Send Keypress
- startkeypress_timer(WHEEL, TurnDirectionWheel);
- //--------------------------------------------------------------------------
- // Check for LED Button Press
- //--------------------------------------------------------------------------
- if(OldState[LEDA]==NOTPRESSED && NewState[LEDA]==PRESSED)
- LED_Select = LEDA;
- else if (OldState[LEDB]==NOTPRESSED && NewState[LEDB]==PRESSED)
- LED_Select = LEDB;
- else if (OldState[LEDC]==NOTPRESSED && NewState[LEDC]==PRESSED)
- LED_Select = LEDC;
- else //No button press detected for LEDs
- LED_Select = NONE;
- //Send Keypress & Change Lights
- startkeypress_timer(LEDS, LED_Select);
- TurnOnOffLEDs(LED_Select);
- //--------------------------------------------------------------------------
- // Setup for next Input State Change
- //--------------------------------------------------------------------------
- //Save the current state as the old state
- //OldState = NewState;
- for (i=0; i >=7; i++)
- OldState[i]=NewState[i];
- //Debouncing Delay
- delay_us(200);
- }
- //This should not be reachable
- while(1);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement