C LCD Zeitschaltuhr

Janiiix3

Aktives Mitglied
28. Sep. 2013
1.333
10
38
Hannover
Sprachen
  1. ANSI C
  2. C#
Hallo Freunde,

Da bin ich mal wieder.:cool:

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;
    }
}
 
Hallo Janiiix,

Drehe ich den Encoder "rechts" so wird "Menüstatus" incrementiert.
Drehe ich den Encoder "links" wird "Menüstauts" decrementiert.

ich habe kleine Stellen die mir aufgefallen sind:

(1)
#define PHASE_B (PIND &= (1<<PIND0))
Mach hier keine Zuweisung, sondern nur eine UND verknüpfung.

(2)
Dein char Array Uhrzeit[9] benötigt wegen dem Abschlußzeichen eine Größe von 10 Byte. Im Moment wird Uhrzeit[10] unkontrolliert ins SRAM geschrieben.

(3) Du musst aufpassen, dass deine Ausgabe auf das Display nicht parallel vom Hauptprogramm und von einer ISR erfolgt. Bei dir passiert das ggf. direkt nach globaler Freigabe der Interrupts (SEI). Eventuell auch innerhalb der while(1) Schleife! Dies würde die "irgendwelche Sonderzeichen" erklären.


Leider habe ich gerade keine Zeit, um auf deine eigentliche Frage nach der Menüführung einzugehen.

Dirk :ciao:
 
Hallo Janiiix,



ich habe kleine Stellen die mir aufgefallen sind:

(1)
#define PHASE_B (PIND &= (1<<PIND0))
Mach hier keine Zuweisung, sondern nur eine UND verknüpfung.

(2)
Dein char Array Uhrzeit[9] benötigt wegen dem Abschlußzeichen eine Größe von 10 Byte. Im Moment wird Uhrzeit[10] unkontrolliert ins SRAM geschrieben.

(3) Du musst aufpassen, dass deine Ausgabe auf das Display nicht parallel vom Hauptprogramm und von einer ISR erfolgt. Bei dir passiert das ggf. direkt nach globaler Freigabe der Interrupts (SEI). Eventuell auch innerhalb der while(1) Schleife! Dies würde die "irgendwelche Sonderzeichen" erklären.


Leider habe ich gerade keine Zeit, um auf deine eigentliche Frage nach der Menüführung einzugehen.

Dirk :ciao:



Zu Punkt "2"

Wieso meckert der Compiler dann nicht ?
Aber es sind doch nur 9 Werte oder sehe ich das falsch ?
 
Zu Punkt "2"

Wieso meckert der Compiler dann nicht ?
Aber es sind doch nur 9 Werte oder sehe ich das falsch ?

Ja es sind 9. Du hast Index 8 übersprungen und Index 9 verwendet. Mach aus der 9 eine 8 dann stimmts.

Code:
     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';
 
Ja es sind 9. Du hast Index 8 übersprungen und Index 9 verwendet. Mach aus der 9 eine 8 dann stimmts.

Code:
     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';

Danke, ist mir garnicht aufgefallen!
 
& damit ich verhindere das auf dem LCD irgendwelche "komischen Zeichen" sind, sollte ich das ausgeben auf der Anzeige generell nur in der "While(1)" machen ?
 
& damit ich verhindere das auf dem LCD irgendwelche "komischen Zeichen" sind, sollte ich das ausgeben auf der Anzeige generell nur in der "While(1)" machen ?

Nicht generell. Wenn du im Hauptprogramm und in einer ISR überträgst kann natürlich die ISR eine Übertragung vom Hauptprogramm unterbrechen. Das geht dann in der Regel schief. Also entweder oder.
 
Wenn ich jetzt in meinem Hauptmenü "hin und her" scrolle... Wird mein alter Text leider nicht gelöscht (der vorher im Display stand)

Code:
/* Sorgt dafür, dass das Menue nur 1 x gelöscht wird nach jedem Menue Schritt */
        if (MenueStatus != Menustatus_Old)
        {
            lcd_clrscr();
            Test;
        }
    
        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

Ist das mit der "If" Abfrage so richtig, wie ich es aktuell habe ?

Ich möchte nur das aktuelle Display löschen, wenn ich auf einen neuen Menüpunkt springe...
 
Hallo,

Eine Frage an die "C" Experten unter euch...

Ich übergebe die Parameter... (Sekunden als Startwert = 0)

Code:
    IncrementBCD(Sec_Kopie,59);

an diese Funktion ...

Code:
/* Diese Funktion wird für das stellen (hochzählen) der Uhrzeit benötigt */
 uint8_t IncrementBCD(uint8_t Value , uint8_t ValueMax)
{
    Value ++;
    
/* Einer Überlauf */
    if ((Value & 0x0F) == (0x0A))
    {
        Value = Value + 6;
    }
    
/* Überlauf komplett */
    if (Value > ValueMax)
    {
        Value = 0;
    }

/* Gibt den aktuellen Wert von "Value" an den Uhrsprungspunkt zurück */
    return Value ;

Wieso erhalte ich keinen Rückgabewert ?
 
Ah, okay ! Ich habe gedacht der wird direkt in der Variable gespeichert mit der ich sie übergebe...

:p
 
Ich habe das Problem, dass ich die Zeit (Sec_KOPIE) imoment nicht Incrementiert bekomme.
Ich weiß ehrlich gesagt nicht was ich falsch mache...
Hat jemand eine Idee?

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 geschehen                                    *
***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 MEGA168 =                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) 
*/

/* Aufbau: MenueStatus =             0 = Homescreen                (Uhrzeit wird angezeigt )
                                     1 = Uhrzeit stellen        ( Uhrzeit einstellen )
                                     2 = Schaltzeit 1            ( An | Aus )
                                     3 = Schaltzeit 2            ( An | Aus )
                                     4 = Schaltzeit 3            ( An | Aus )
                                     5 = Hintergrundbeleuchtung ( An | Aus )
                                     6 = Exit                    ( Enter = Menü verlassen )
*/

/***************************************************************************************************************************/

/* Frequenz für die **DEBUG CPU** */
    #define F_CPU 8000000UL

/* Bindet benötigte Headerdateien ein */
    #include <avr/io.h>
    #include "lcd.h"
    #include <util/delay.h>
    #include <stdlib.h>
    #include <avr/interrupt.h>

/* Definiert die Pins des Drehencoders */
    #define PHASE_A (PIND & (1<<PIND2))
    #define PHASE_B (PIND & (1<<PIND0))

/* Definiert die Pins vom Taster */
    #define Enter (!(PIND & (1<<PD3)))

/* Definiert die LED (toggeln) als HINTERGRUNDBELEUCHTUNG */
    #define HINTERGRUNDBELEUCHTUNG (PORTC ^= (1<<PC5))

/* Globale Freigabe der Variabeln */
    volatile uint8_t Hrs, Min, Sec, Hrs_KOPIE, Min_KOPIE, Sec_Kopie, MenueStatus, MenueStatus_Old, ReturnValue;
    char Uhrzeit[9];
    
/* Unterprogramme bekannt geben */
    void DisplayTime(uint8_t Hrs ,uint8_t Min,uint8_t Sec);
    uint8_t IncrementBCD(uint8_t Value , uint8_t ValueMax);
    void UhrzeitKopie();
    void OnLeft();
    void OnRight();
    void OnEnter();
    

    
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)");

/* Startbildschirm für "1" Sekunde anzeigen */
    _delay_ms(1000);
    
/* LCD beim Starten löschen */
    lcd_clrscr();

/* Variablen Initalisieren und auf einen bestimmten Wert setzen */
    Hrs =  0x00;
    Min =  0x00;
    Sec =  0x00;
    
/* Sofort den Startbildschirm anzeigen (Aktuelle Uhrzeit) */
    MenueStatus = 0b00000000;
    
/* Menue Überschrift */
    lcd_gotoxy(0,0);
    lcd_puts("Aktuelle Uhrzeit");
                     
/* Schreibt auf das Display "Uhr" */
    lcd_gotoxy(11,1);
    lcd_puts("Uhr");

    
while(1)
{
        


/* Springt in das Unterprogramm "DisplayTime" & zeigt die aktuelle Uhrzeit an */
        
        if (MenueStatus == 0b00000000)
        {        
            DisplayTime(Hrs,Min, Sec);
        }
                    
/* Sorgt dafür, dass die LCD Anzeige nur 1 x geschrieben wird, wenn sich im "MenuStatus" was tut */
        if (MenueStatus != MenueStatus_Old)
        {
            lcd_clrscr();
            HINTERGRUNDBELEUCHTUNG;
            MenueStatus_Old =  MenueStatus;        
            
            switch (MenueStatus)    
         {
            
            case  0b00000000: // Homescreen
            {
                
                    MenueStatus = 0;
                
             /* Menue Überschrift */
                lcd_gotoxy(0,0);
                lcd_puts("Aktuelle Uhrzeit");
                    
             /* Schreibt auf das Display "Uhr" */
                lcd_gotoxy(11,1);
                lcd_puts("Uhr");
            }
                break;
                
            case 0b00000001: // Uhrzeit stellen
            {
                lcd_gotoxy(2,0);
                lcd_puts("*Hauptmenue*");
                lcd_gotoxy(0,1);
                lcd_puts("-Uhrzeit stellen");
            }
                break;                
                
            case 0b00000010: // Schaltzeit 1
            {
                lcd_gotoxy(2,0);
                lcd_puts("*Hauptmenue*");
                lcd_gotoxy(1,1);
                lcd_puts("-Schaltzeit 1");
            }
                break;
                
            case 0b00000011: // Schaltzeit 2
            {
                lcd_gotoxy(2,0);
                lcd_puts("*Hauptmenue*");
                lcd_gotoxy(1,1);
                lcd_puts("-Schaltzeit 2");                
            }
                break;

            case 0b00000100: // Schaltzeit 3
            {
                lcd_gotoxy(2,0);
                lcd_puts("*Hauptmenue*");
                lcd_gotoxy(1,1);
                lcd_puts("-Schaltzeit 3");
            }
                break;
                
            case 0b00000101: // Hintergrundbeleuchtung
            {
                lcd_gotoxy(2,0);
                lcd_puts("*Hauptmenue*");
                lcd_gotoxy(1,1);
                lcd_puts("-Beleuchtung");                
            }
                break;
                
            case 0b00000110: // Zurück
            {
                lcd_gotoxy(2,0);
                lcd_puts("*Hauptmenue*");
                lcd_gotoxy(4,1);
                lcd_puts("-Zurueck");
            }                
                break;
    
            }// Ende (Switch)
        }// (MenueStatus != MenueStatus_Old)    
    }// Ende While
    
}// Ende Main


/* Hier wird die "genaue" Sekunde generiert (Quarz = 32,769 kHz) */
ISR (TIMER2_OVF_vect)
{
[COLOR=#ff0000][B]    IncrementBCD(ReturnValue,59);
    DisplayTime(Hrs_KOPIE, Min_KOPIE, Sec_KOPIE);[/B][/COLOR]
}

/* Drehencoder auswerten (Phase_A triggert den Interrupt) */
ISR (INT0_vect)
{
  if ((PHASE_B)) // rechts drehung
  {
    OnRight();
  }
  
  else // links drehung
  
  {
    OnLeft();
  }
  
  
}// Ende ISR (INT0_vect)

/* Tastenabfrage "Enter" */
ISR (INT1_vect)
{
/* Ist MenuStauts = 5 (Zurueck) dann das Menue verlassen */
    if (MenueStatus == 6)
    {
        MenueStatus = 0;
        lcd_clrscr();
    }
    
/* MenüStatus = 1 (Uhrzeit stellen)    */
    if (MenueStatus == 1)
    {        
        UhrzeitKopie();
    }
    
/* Hintergrundbeleuchtung aktivieren */
    if (MenueStatus == 5)
    {
        HINTERGRUNDBELEUCHTUNG;
    }
    
}// Ende ISR (INT1_vect)


void DisplayTime(uint8_t Hrs, uint8_t Min, uint8_t Sec)
{
    
/* Uhrzeit in einen String packen & nach ASCII umstellen */
    Uhrzeit[0] = ((Hrs & 0xF0) >>4) + 0x30;
    Uhrzeit[1] = (Hrs & 0x0F) + 0x30;
    Uhrzeit[2] = ':';
    Uhrzeit[3] = ((Min & 0xF0) >>4) + 0x30;
    Uhrzeit[4] = (Min & 0x0F) + 0x30;
    Uhrzeit[5] = ':';
    Uhrzeit[6] = ((Sec & 0xF0 ) >>4) + 0x30;
    Uhrzeit[7] = (Sec & 0x0F) + 0x30;
    Uhrzeit[8] = '\0';
     
     /* Gehe in die zweite Zeile */
         lcd_gotoxy(2,1);
     
     /* Aktuelle Uhrzeit auf dem Display ausgeben */
         lcd_puts(Uhrzeit);    
         
    
}// Ende (void DisplayTime(uint8_t Hrs, uint8_t Min, uint8_t Sec))

/* Hier wird eine Kopie von der aktuellen Uhreit gemacht (Stunden, Minuten, Sekunden) */
void UhrzeitKopie()
{
/* Aktuelles Display löschen */
    lcd_clrscr(); 
    
/* Kopie von der aktuellen Zeit machen */
    Sec_Kopie = Sec;
    Min_KOPIE = Min;
    Hrs_KOPIE = Hrs;
        
/* Schickt die Kopie zum umrechnen an "DisplayTime" */
    DisplayTime(Hrs_KOPIE, Min_KOPIE, Sec_Kopie);
    
}// Ende (void UhrzeitKopie())


[COLOR=#ff0000][B]/* Diese Funktion wird für das stellen (hochzählen) der Uhrzeit benötigt */
 uint8_t IncrementBCD(uint8_t Value , uint8_t ValueMax)
{
    Value ++;
    
/* Einer Überlauf */
    if ((Value & 0x0F) == (0x0A))
    {
        Value = Value + 6;
    }
    
/* Überlauf komplett */
    if (Value > ValueMax)
    {
        Value = 0;
    }

    ReturnValue = Value;
/* Gibt den aktuellen Wert von "Value" an den Uhrsprungspunkt zurück */
    return ReturnValue ;
    
}// Ende (void IncrementBCD(uint8_t Value , uint8_t ValueMax))[/B][/COLOR]


void OnRight()
{
    if (MenueStatus < 0b00000110)
    {
        
        switch (MenueStatus & 0b11110000)
        {
            case 0b000000000:
            {
                MenueStatus ++;
            }
                break;        
            
        }// Ende switch
    }// Ende if
    
        switch (MenueStatus & 0b00001111)
        {
            case 0b00000001:
            {
                IncrementBCD(Sec_Kopie,59);
                DisplayTime(Hrs_KOPIE,Min_KOPIE,Sec_Kopie);
            }
                break;

        }
    
}

void OnLeft()
{
    if (MenueStatus > 0b00000001)
    {
        switch (MenueStatus & 0b11110000)
        {
            case 0b000000000:
            {
                MenueStatus --;
            }
            break;
        }
        
    }
}
 
Zu C konkret kann ich nichts sagen, aber normalerweise gibt es halt Prozeduren/Subroutinen, die aufgerufen werden, und dann irgendwas machen, und eben Funktionen, die zusätzlich eben irgendwas zurückliefern, der Aufruf der Funktion erfolgt also, als wenn das eine Variable wäre (Zuweisung/Vergleich).

Diesen Subroutinen oder Funktionen können beim Aufruf Argumente mitgegeben werden - dabei können diese called by reference oder called by value sein (also in der sub) das ist ein wichtiger Unterschied... wie ist das bei C?
 
Ist doch einfach ne Zuweisung. Wie das was alles so schönes vordefiniert ist. Beispielsweise SQR (falls das AVR C das hat) zum berechnen der Quadratwurzel.

Ergebnis = SQR(Wert)

Genau so kannst du aber auch schreiben

Wert = SQR(Wert)

Die Funktion bekommt den Wert als Variable, macht damit was auch immer sie für bestimmt ist und gibt sie zurück.
Nix anderes als Wert = 1 + 2.

Das geht genau so mit selbstgeschriebenen Funktionen, wie eben IncrementBCD. Du musst nur den berechneten Wert "return"en und dann auch empfangen. Nur der Aufruf IncrementBCD ist sinnfrei. Es wird gerechnet aber du verwirfst das Ergebnis.
 
wie ist das bei C?
In C ist alles 'call by value'. Statt 'call by reference' übergibt man Adressen (by value).

Code:
int func(int x)  // call by value
{
  return 2*x;
}

oder

Code:
void func(int *x)  // call by reference
{
  *x *= 2;
}
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)