Sieh es dir mal an:
CodeBox C
/* ATB_Enc_Menue_Prg_1.c
* Created: 14.12.2016 12:21:55 Author : AS */
//#define F_CPU 16000000 // CPU clock in Hz
#include <stdbool.h>
#include <avr/pgmspace.h>
#include "main.h"
#include <util/delay.h>
#include "i2clcd.h"
#include "i2cmaster.h"
#include "avr/io.h"
#include <avr/interrupt.h>
#include <stdlib.h>
#include <stdint.h>
//#include "encoder.h" !!!!!!!!
//#include "encoder.c"
volatile uint8_t wait;
volatile uint8_t key_state;
volatile uint8_t key_press;
volatile uint8_t key_rpt;
volatile int16_t led1=0;
volatile int8_t Anz=0;
volatile int8_t zeile=2;
volatile int8_t lauf=0;
int8_t Menue;
#define KEY_DDR DDRA // Datenrichtung A
#define KEY_PORT PORTA // Angabe Port A
#define KEY_PIN PINA // Angabe PIN A
#define KEY_1 7 // PA 3
#define KEY_2 6 // PA 5
#define KEY_3 5 // PA 7
#define KEY_4 3 // PA 6
#define ALL_KEYS (1<<KEY_1|1<<KEY_2|1<<KEY_3|1<<KEY_4)
#define REPEAT_MASK (1<<KEY_1|1<<KEY_2|1<<KEY_3)
#define REPEAT_START 80 // after 500ms 50
#define REPEAT_NEXT 40 // every 200ms 50
#define PHASE_A (PINA & 1<<PA0) // Eingang Encoder A P98
#define PHASE_B (PINA & 1<<PA1) // Eingang Encoder B P98
//#define PHASE_A (PINA & 1<<PA2) // Eingang Encoder A P32
//#define PHASE_B (PINA & 1<<PA1) // Eingang Encoder B P32
#define LEDS_DDR DDRB // Ausgang LED
#define LEDS PORTB //
volatile int8_t enc_delta; // -128 ... 127
static int8_t last;
char Buffer[20];
int8_t dreh1 = 4;
//int8_t dreh1u = 2;
// ATmega 1284p auf Board 1, 16 MHz, Drehgeber auf P98 auf Port A, NT2, 8x LED auf P20 am Port B
//***********************************************************************
// Reading rotary encoder
// Author: Peter Dannegger
//************************************************************************
void encode_init( void )
{
int8_t new;
new = 0;
if( PHASE_A ) new = 3; //3
if( PHASE_B ) new ^= 1; // convert gray to binary
last = new; // power on state
enc_delta = 0;
}
/////////////////////////////////////////////
ISR (TIMER0_COMPA_vect) // ISR mit 1 ms
{
int8_t new, diff; // ab hier Encoder
new = 0;
if( PHASE_A ) new = 3;
if( PHASE_B ) new ^= 1; // convert gray to binary
diff = last - new; // difference last - new
if( diff & 1 )
{ // bit 0 = value (1)
last = new; // store new as next last
enc_delta += (diff & 2) - 1; // bit 1 = direction (+/-)
}
static uint8_t ct0=0xFF, ct1=0xFF, rpt; // ab hier Tasten
uint8_t i;
if(wait<=9) // bei 9 sind es 10ms
{
wait++;
} // erhöht
else // wenn dann ...
{
wait=0; // setzt wait auf 0
i=key_state ^ KEY_PIN; // nach +5V
//i=key_state ^~KEY_PIN; // nach GND
ct0=~(ct0&i);
ct1=ct0^(ct1&i);
i&=ct0&ct1;
key_state^=i;
key_press|=key_state&i;
if((key_state & REPEAT_MASK)==0)
rpt=REPEAT_START;
if(--rpt==0)
{
rpt=REPEAT_NEXT;
key_rpt|=key_state & REPEAT_MASK;
}
}
}
//////////////////////////////////////////////////////////
int8_t encode_read1( void ) // lesen einzel Schritt Encoder = schnell
{
int8_t val;
cli();
val = enc_delta;
enc_delta = 0;
sei();
return val; // counts since last call
}
int8_t encode_read2( void ) // lesen zwei Schritt Encoder = mittel
{
int8_t val;
cli();
val = enc_delta;
enc_delta = val & 1;
sei();
return val >> 1;
}
int8_t encode_read4( void ) // lesen vier Schritt Encoder = langsam
{
int8_t val;
cli();
val = enc_delta;
enc_delta = val & 3;
sei();
return val >> 2;
}
////////////////////////////////////////////////////////////////////
void timer_init()
{
//TCCR0A = (1<<WGM01);
TCCR0A = 0;
TCCR0B = (1<<WGM01)|(1<<CS01)|(1<<CS00);
TCNT0=1;
OCR0A = 249;
TIMSK0 |=(1<<OCIE0A);
}
//////////////////////////////////////////////////////
uint8_t get_key_press(uint8_t key_mask)
{
cli();
key_mask &=key_press;
key_press^=key_mask;
sei();
return key_mask;
}
/////////////////////////////////////////
uint8_t get_key_rpt(uint8_t key_mask)
{
cli();
key_mask &=key_rpt;
key_rpt^=key_mask;
sei();
return key_mask;
}
///////////////////////////////////////////////////////
uint8_t get_key_short(uint8_t key_mask)
{
return get_key_press(~key_state & key_mask);
}
///////////////////////////////////////////////////////
uint8_t get_key_long(uint8_t key_mask)
{
return get_key_press(get_key_rpt(key_mask));
}
///////////////////////////////////////////////////////////////////
void led_blinken1()
{
led1++;
if(led1==500)
{
PORTA &= ~(1<<PA5); // Schaltet Pin
}
else
{
if(led1==1000)
{
PORTA |= (1<<PA5); // Schaltet Pin
led1=0;
}
}
}
/////////////////////////////////////////////////////////////////
void Startanzeige()
{
lcd_printlc(1,3,"Enc-Menue 1"); // Text Zeile 1
lcd_printlc(2,2,"**************"); // Text Zeile 2
lcd_printlc(3,1,"Encoder Menue 1"); // Text Zeile 3
lcd_printlc(4,2,"(by achim S.)"); // Text Zeile 4
}
///////////////////////////////////////////////////////////
void Bedienung()
{
lcd_printlc(1,1,"Bedienung-Menue"); // Text Zeile 1
lcd_printlc(2,3,"< + > Auswahl"); // Text Zeile 2
lcd_printlc(3,3,"kurz - Start"); // Text Zeile 3
lcd_printlc(4,3,"lang - Reset"); // Text Zeile 4
}
///////////////////////////////////////////////////
void Anzeige(int8_t valk)
{
Anz++;
if (Anz==50)
{
lcd_printlc(1,3,"Enc-Menue 1"); // Text Zeile 1
lcd_printlc(2,2,"**************"); // Text Zeile 2
lcd_printlc(3,2,"Werte Encoder:"); // Text Zeile 3
itoa(valk,Buffer,10);
lcd_printlc(4,4,Buffer);
Anz=0;
}
}
//////////////////////////////////////////////////////////////////
void Menue1(int8_t zeile) //
{
lauf++;
if(lauf==100)
{
//lcd_command(LCD_CLEAR); // Leere Display
//_delay_ms(2);
lcd_printlc(1,2,"Menue 1 - I2C");
lcd_printlc(2,4,"Menue 1-1");
lcd_printlc(3,4,"Menue 1-2 ");
lcd_printlc(4,4,"Menue 1-3");
lcd_printlc(2,1," ");
lcd_printlc(3,1," ");
lcd_printlc(4,1," ");
lcd_printlc(zeile,1,">>");
lauf=0;
}
}
///////////////////////////////////////////////////////////////////////
void Menue11()
{
lcd_command(LCD_CLEAR); // Leere Display
_delay_ms(2);
lcd_printlc(1,1,"Bedienung-Menue"); // Text Zeile 1
//lcd_printlc(2,3,"< + > Auswahl"); // Text Zeile 2
lcd_printlc(3,3,"Menue 1-1"); // Text Zeile 3
lcd_printlc(4,3,"lang - Reset"); // Text Zeile 4
}
///////////////////////////////////////////////////////////////////////
void Menue12()
{
lcd_command(LCD_CLEAR); // Leere Display
_delay_ms(2);
lcd_printlc(1,1,"Bedienung-Menue"); // Text Zeile 1
//lcd_printlc(2,3,"< + > Auswahl"); // Text Zeile 2
lcd_printlc(3,3,"Menue 1-2"); // Text Zeile 3
lcd_printlc(4,3,"lang - Reset"); // Text Zeile 4
}
///////////////////////////////////////////////////////////////////////
void Menue13()
{
lcd_command(LCD_CLEAR); // Leere Display
_delay_ms(2);
lcd_printlc(1,1,"Bedienung-Menue"); // Text Zeile 1
//lcd_printlc(2,3,"< + > Auswahl"); // Text Zeile 2
lcd_printlc(3,3,"Menue 1-3"); // Text Zeile 3
lcd_printlc(4,3,"lang - Reset"); // Text Zeile 4
}
/////////////////////////////////////////////////////////////////////
///////// Hauptprogramm
/////////////////////////////////////////////////////////////////////
int main( void ) // Hauptschleife
{
timer_init();
i2c_init(); // Starte I2C Bus
lcd_init(); // Starte I2CLCD
lcd_light(0); // 0=Licht an, 1=Licht aus
// Display Befehle
lcd_command(LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKINGOFF);
// Display ON/OFF / Cursor ON/OFF / Blinken ON/OFF
lcd_command(LCD_CLEAR); // Leere Display
_delay_ms(2);
// warte 2ms
Startanzeige();
_delay_ms(3000);
lcd_command(LCD_CLEAR); // Leere Display
_delay_ms(2); // warte 2ms
Bedienung();
_delay_ms(3000);
lcd_command(LCD_CLEAR); // Leere Display
_delay_ms(2);
KEY_DDR&=~ALL_KEYS;
KEY_PORT|=ALL_KEYS;
DDRA |= 0b01111100 ; // LED1+2 auf PA4 und PA5, alle auf Ausgang
//PORTA = 0b00000000; // alle LED auf aus bei 1
PORTA |= (1<<PA5); // LED Blau auf P98 Pin 5
PORTA |= (1<<PA6); // LED Blau auf P98 Pin 5
int8_t val = 0;
LEDS_DDR = 0xff;
encode_init();
val=2;
sei();
while(1)
{
led_blinken1(); // Aufruf Unterprogramm LED blinken
val += encode_read4(); // Aufruf Encoder 4 mit Rückgabe
if (Menue==0)
{
Menue1(val);
}
// Auswertung Grundmenue 1 ////////////////////////////////////
if (val>dreh1) // Begrenzung oben
{
val=2;
}
if (val<2) // Begrenzung unten
{
val=dreh1;
}
//////////////////////////////////////////////////////////////
//LEDS = val;
//Anzeige(val);
if (val==2) // LED blau
{
PORTA &= ~(1<<PA4); // LED auf P98 L3 ??
}
else
{
PORTA |= (1<<PA4); // LED Blau auf P98 Pin 5 ??
}
if (val==4) // LED grün
{
PORTA &= ~(1<<PA3); // LED auf P98 L3 ???
}
else
{
PORTA |= (1<<PA3); // LED Blau auf P98 Pin 5 ????
}
if (val==6) // LED rot
{
PORTA &= ~(1<<PA2); // LED auf P98 L3 ???
}
else
{
PORTA |= (1<<PA2); // LED Blau auf P98 Pin 5 ???
}
if (val==8)
{
PORTA &= ~(1<<PA2); // LED auf P98 L3
PORTA &= ~(1<<PA3); // LED auf P98 L3
PORTA &= ~(1<<PA4); // LED auf P98 L3
}
/*
else
{
PORTA |= (1<<PA2); // LED Blau auf P98 Pin 5
PORTA |= (1<<PA3); // LED Blau auf P98 Pin 5
PORTA |= (1<<PA4); // LED Blau auf P98 Pin 5
}
*/
if(get_key_short(1<<KEY_1)) // schaltet kurz
{
PORTA &= ~(1<<PA6); // LED auf P98 L3
if (val==2) // LED rot
{
Menue=1;
Menue11();
}
if (val==3) // LED rot
{
Menue=1;
Menue12();
}
if (val==4) // LED rot
{
Menue=1;
Menue13();
}
}
if(get_key_long(1<<KEY_1)) // schaltet lang
{
Menue=0;
PORTA |= (1<<PA6); // LED Blau auf P98 Pin 5
lcd_command(LCD_CLEAR); // Leere Display
_delay_ms(2);
}
//PORTA |= (1<<PA3); // LED Grün auf P98 Pin 4
//PORTA |= (1<<PA2); // LED Rot auf P98 Pin 3
}
}