Hallo Freunde,
Da bin ich mal wieder.
Nun möchte ich mir eine "LCD Zeitschaltuhr" programmieren.
So weit so gut.
Bestandteile dieses Projektes :
- Controller = ATMEGA168
- Uhrzeit = 32.768 kHz Quarz an Timer2 (Timer 2 auf OVF konfiguriert)
- LCD = MSH1602A
- Drehencoder = MRL20 (Megatron)
_________________________________________________________
Das "Incrementieren" der Uhrzeit und darstellen auf dem Display klappt bis jetzt mehr oder weniger einwandfrei (manchmal erscheinen irgendwelche Sonderzeichen auf dem LCD).
Mein "Hauptmenü" stelle ich in der "while(1)" da. Dort frage ich mit hilfe von "switch" meinen jeweiligen Menüstatus ab. Der "Menüstatus" ist abhängig vom "Encoder". Drehe ich den Encoder "rechts" so wird "Menüstatus" incrementiert.
Drehe ich den Encoder "links" wird "Menüstauts" decrementiert.
Dadurch komm ich imoment in mein Hauptmenü rein. (0 = Homescreen , 1 = Uhrzeit stellen , 2 = Schaltzeit 1 , 3 = Schaltzeit 2, 4 = Schaltzeit 3, 5 = Zurück)
Da ich imoment noch keinen Drehimpulsgeber habe der einen "Taster" mit onBoard hat, nutze ich zum "Entwickeln" einen Taster.
Meine Fragen jetzt an euch...
- Wie würdet ihr sowas realisieren? Ist das schon zu umständlich wie ich es bis jetzt gemacht habe ?
- Wie stelle ich nun am besten meine Uhrzeit? (Ich wollte eine kopie von der aktuellen Uhrzeit machen und diese dann "eingefroren" in dem Menüpunkt "Uhrzeit stellen" darstellen & ggf. stellen)
Würde mich über interessante Antworten freuen.
Hier der aktuelle Quellcode:
Da bin ich mal wieder.
Nun möchte ich mir eine "LCD Zeitschaltuhr" programmieren.
So weit so gut.
Bestandteile dieses Projektes :
- Controller = ATMEGA168
- Uhrzeit = 32.768 kHz Quarz an Timer2 (Timer 2 auf OVF konfiguriert)
- LCD = MSH1602A
- Drehencoder = MRL20 (Megatron)
_________________________________________________________
Das "Incrementieren" der Uhrzeit und darstellen auf dem Display klappt bis jetzt mehr oder weniger einwandfrei (manchmal erscheinen irgendwelche Sonderzeichen auf dem LCD).
Mein "Hauptmenü" stelle ich in der "while(1)" da. Dort frage ich mit hilfe von "switch" meinen jeweiligen Menüstatus ab. Der "Menüstatus" ist abhängig vom "Encoder". Drehe ich den Encoder "rechts" so wird "Menüstatus" incrementiert.
Drehe ich den Encoder "links" wird "Menüstauts" decrementiert.
Dadurch komm ich imoment in mein Hauptmenü rein. (0 = Homescreen , 1 = Uhrzeit stellen , 2 = Schaltzeit 1 , 3 = Schaltzeit 2, 4 = Schaltzeit 3, 5 = Zurück)
Da ich imoment noch keinen Drehimpulsgeber habe der einen "Taster" mit onBoard hat, nutze ich zum "Entwickeln" einen Taster.
Meine Fragen jetzt an euch...
- Wie würdet ihr sowas realisieren? Ist das schon zu umständlich wie ich es bis jetzt gemacht habe ?
- Wie stelle ich nun am besten meine Uhrzeit? (Ich wollte eine kopie von der aktuellen Uhrzeit machen und diese dann "eingefroren" in dem Menüpunkt "Uhrzeit stellen" darstellen & ggf. stellen)
Würde mich über interessante Antworten freuen.
Hier der aktuelle Quellcode:
Code:
/************************************************************************************************************
* Zeitschaltuhr *
* ______________________________________ *
* *
* - Zeitschaltuhr mit hilfe von Relais / Drehencoder / LCD / I2C RTC *
* *
* *
* *
* *
* Beschreibung : *
* Eine Zeitschaltuhr zum Schalten von größeren Lasten (<= 3A / 230 VAC) *
* Das ganze soll mit --> LCD: (MSH1602A) / Drehencoder: (MRL-20-C) / *
* Relais : (irgendeins was die Last abkann) / Controller ATMEGA168 *
* **DEBUG CPU = MEGA168** *
************************************************************************************************************/
/* Display Belegung (Datenblatt)
1 = GND | 2 = VDD | 3 = Contrast | 4 = RS | 5 = R/W | 6 = E | 7 - 14 = DBO..DB7 | 15 = LED (Hintergrund "ANODE") | 16 = LED (Hintergrund "Kathode" */
/* Display am MEGA32
RS = PB1 | R/W = PB2 | E = PB0 | DB4 = PC0 | DB5 = PC1 | DB6 = PC2 | DB7 = PC3 */
/* Drehencoder
Kanal_A = PD2 (INT0) | Kanal_B = PD0 */
/* Taster
PD3 (INT1) */
/* Frequenz für die **DEBUG CPU** */
#define F_CPU 8000000UL
#include <avr/io.h>
#include "lcd.h"
#include <util/delay.h>
#include <stdlib.h>
#include <avr/interrupt.h>
#define PHASE_A (PIND &= (1<<PIND2))
#define PHASE_B (PIND &= (1<<PIND0))
#define Enter (!(PIND &= (1<<PD7)))
#define Test (PORTC ^= (1<<PC5))
/* Globale Freigabe der Variabeln */
volatile uint8_t Sekunden, Minuten, Stunden, MenueStatus, Menustatus_Old, Sekunden_Kopie, Minuten_Kopie, Stunden_Kopie;
/* Unterprogramme bekannt geben */
void Change_Sekunden();
void Change_Minuten();
void Change_Stunden();
int main(void)
{
/* Ausgänge Konfigurieren */
DDRD |= ((1<<PD1)| (1<<PD4) | (1<<PD5) | (1<<PD6));
DDRB |= 0xFF;
DDRC |= (1<<PC5);
PORTD |= ((1<<PD0) | (1<<PD2) | (1<<PD3));
/* Timer2 konfigurieren */
ASSR |= (1<<AS2);
TCCR2B |= ((1<<CS22) | (1<<CS20));
TIMSK2 |= (1<<TOIE2);
/* INT0 konfigurieren für Drehencoder (fallende Flanke) */
EIMSK |= (1<<INT0);
EICRA |= ((1<<ISC01));
/* INT1 konfigurieren für Enter (fallende Flanke) */
EIMSK |= (1<<INT1);
EICRA |= ((1<<ISC11));
/* Timer0 für die Entprellung konfigurieren */
/*TIMSK0 |= (TOIE0);
TCCR0B |= ((1<<CS02) | (1<<CS00)); // 1024
TCNT0 |= 194; // Ca. 25 mSec. */
/* Interrupts global freigeben */
sei();
/* Start Bildschirm */
lcd_init(LCD_DISP_ON);
lcd_puts("Time Switch V1.0");
lcd_gotoxy(0,1);
lcd_puts("by Hm (C)");
_delay_ms(1000);
/* LCD beim Starten löschen */
lcd_clrscr();
/* Variablen Initalisieren und auf einen bestimmten Wert setzen */
Stunden = 0x00;
Minuten = 0x00;
Sekunden = 0x00;
/* Sofort den Startbildschirm anzeigen (Aktuelle Uhrzeit) */
MenueStatus = 0;
while(1)
{
/* Damit im Display keine verückten Sonderzeichen angezeigt werden */
_delay_ms(200);
/* Sorgt dafür, dass das Menue nur 1 x gelöscht wird nach jedem Menue Schritt */
if (MenueStatus != Menustatus_Old)
{
lcd_clrscr();
}
switch (MenueStatus)
{
case 0: // Homescreen
{
MenueStatus = 0;
}
break;
case 1: // Uhrzeit stellen
{
lcd_gotoxy(2,0);
lcd_puts("*Hauptmenue*");
lcd_gotoxy(0,1);
lcd_puts("-Uhrzeit stellen");
}
break;
case 2: // Schaltzeit 1
{
lcd_gotoxy(2,0);
lcd_puts("*Hauptmenue*");
lcd_gotoxy(1,1);
lcd_puts("-Schaltzeit 1");
}
break;
case 3: // Schaltzeit 2
{
lcd_gotoxy(2,0);
lcd_puts("*Hauptmenue*");
lcd_gotoxy(1,1);
lcd_puts("-Schaltzeit 2");
}
break;
case 4: // Schaltzeit 3
{
lcd_gotoxy(2,0);
lcd_puts("*Hauptmenue*");
lcd_gotoxy(1,1);
lcd_puts("-Schaltzeit 3");
}
break;
case 5: // Zurück
{
lcd_gotoxy(2,0);
lcd_puts("*Hauptmenue*");
lcd_gotoxy(3,1);
lcd_puts("-Zurueck");
}
break;
}
Menustatus_Old = MenueStatus;
}// Ende While
}// Ende Main
ISR (TIMER2_OVF_vect)
{
Sekunden = Sekunden + 1;
/* Überlauf Sekunden "Einer" */
if ((Sekunden & 0x0F) == (0x0A))
{
Sekunden = Sekunden + 6;
}
/* Überlauf Sekunden "Komplett" */
if ((Sekunden == 0x60))
{
Sekunden = 0;
Minuten = Minuten + 1;
}
/* Überlauf Minuten "Einer" */
if ((Minuten & 0x0F) == (0x0A))
{
Minuten = Minuten + 6;
}
/* Überlauf Minuten "Komplett" */
if ((Minuten == 0x60))
{
Minuten = 0;
Stunden = Stunden + 1;
}
/* Überlauf Stunden "Einer" */
if ((Stunden & 0x0F) == (0x0A))
{
Stunden = Stunden + 6;
}
/* Überlauf Stunden "Komplett" */
if ((Stunden == 0x25))
{
Stunden = 0;
}
/* Uhrzeit in einen String packen & nach ASCII umstellen */
char Uhrzeit[9];
Uhrzeit[0] = ((Stunden & 0xF0) >>4) + 0x30;
Uhrzeit[1] = (Stunden & 0x0F) + 0x30;
Uhrzeit[2] = ':';
Uhrzeit[3] = ((Minuten & 0xF0) >>4) + 0x30;
Uhrzeit[4] = (Minuten & 0x0F) + 0x30;
Uhrzeit[5] = ':';
Uhrzeit[6] = ((Sekunden & 0xF0 ) >>4) + 0x30;
Uhrzeit[7] = (Sekunden & 0x0F) + 0x30;
Uhrzeit[9] = '\0';
if (MenueStatus == 0)
{
/* Vorsichtshalber löschen (es ist vorgekommen das aufeinmal irgendwelche Zeichen aufem Display waren) */
lcd_clrscr();
/* Menue Überschrift */
lcd_gotoxy(0,0);
lcd_puts("Aktuelle Uhrzeit");
/* Gehe in die zweite Zeile */
lcd_gotoxy(2,1);
/* Aktuelle Uhrzeit auf dem Display ausgeben */
lcd_puts(Uhrzeit);
}
}
/* Drehencoder auswerten (Phase_A triggert den Interrupt) */
ISR (INT0_vect)
{
if ((PHASE_B)) // rechts drehung
{
if (MenueStatus < 5)
{
MenueStatus ++;
}
}
else // rinks drehung
{
if (MenueStatus > 1)
{
MenueStatus --;
}
}
}
ISR (INT1_vect)
{
/* Ist MenuStauts = 5 (Zurueck) dann das Menue verlassen */
if (MenueStatus == 5)
{
MenueStatus = 0;
lcd_clrscr();
}
if (MenueStatus == 1)
{
Test;
}
}