- LiTime Speicher und Akkus         
Ergebnis 1 bis 2 von 2

Thema: RTC / Binär Uhr

  1. #1

    RTC / Binär Uhr

    Anzeige

    Powerstation Test
    Hi,

    ich bin neu hier. Euer Forum ist echt Klasse ich konnte schon viele Probleme mit euere Hilfe lösen. Doch nun find ich keine Lösung meines Problems.
    Ich möchte mir eine Binäre Uhr bauen doch leider funktiont es nicht wie es soll.

    Ich habe ein 32,???? Khz Uhren-Quarz an TOSC1 & TOSC2 meines Atmega16 angeschlossen.

    Mein CODE .. kommentiert ..:
    Code:
     /* this program uses a external 32.768 khz Quarz on TOSC1 and TOSC2
    to archieve a 1 Hz Signal for time measurement.
    PORTD will be inverted in the interrupt routine.
     */
    
    #include <inttypes.h>
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <avr/signal.h>
    
    volatile uint16_t seconds;
    volatile uint8_t minutes;
    volatile uint8_t hours;
    uint8_t i,j;
    
    void display_first_array(uint8_t);
    void display_second_array(uint8_t);
    
    // Timer2  (autom. Aufruf 1/s)
    INTERRUPT(SIG_OVERFLOW2) 
    {
    	seconds++;
    	if (i==0)
    	{
    		PORTB+=16;
    		i++;
    		return;
    	}
    	
    	if (i==1)
    	{
    		PORTB-=16;
    		i--;
    	}
    }
    
    void initialize(void)
    {
    	seconds=0;
    	minutes=0;
    	hours=0;
    
    	DDRA = 0;
    	PORTA = 0;
    
    	DDRC = 0;
    	PORTC = 0;
    	
    	//first port for the LEDS
    	DDRB=255;
            PORTB=0;
    	 
    	//second Port for the LEDS
    	DDRD = 255;
    	PORTD = 0;
    
    
    	// initialise Timer2 for time measurement
    	// (asynchron driven by a 32.768 kHz quartz)
    	TIMSK &=~((1<<TOIE2)|(1<<OCIE2));  // disable TC2 interrupt
    	ASSR |= (1<<AS2);                   // Timer/Counter2 asynchron with quartz 32,768kHz
    	TCNT2 = 0x00;                        // initial value for Timer2
    	TCCR2 = 0x05;                        // divide ck/128
    	while(ASSR & 0x07);                 // wait until ASSR is written
    	TIMSK |= (1<<TOIE2);                // enable interrupt 
    		
    	sei();
    }
    
    
    	
    int main() {
    	
    	initialize();
    	
    	
    	while(1)
    	{
    	
    	if (seconds==60)
    	{
    		PORTD=++minutes;
    		seconds=0;
    	}
    	
    	if (minutes==60)
    	{
    		PORTB=++hours;
    		minutes=0;
    	}
    	
    	if (hours==12)
    	{
    		hours=0;
    	}
    	
    	
    		
    	}
    }
    Doch leider klappt es nicht [-( warum ?? weis jemand was??

    Gruß

    Stephan

  2. #2
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.802
    Was auf jeden Fall fehlt ist einige Zugriffe atomar zu machen.

    Schau mal in folgendem Artikel, der Artikel ist noch Baustelle, aber es sind ein paar Links drin, die zu dem Thema was sagen.

    https://www.roboternetz.de/wissen/in...Programmierung

    In deinem Fall wäre das einfachste so was wie ein yield() in der Hauptschleife:
    Code:
       // yield();
       sei();
       nop();
       cli();
    Es gibt also nur einen definierten Punkt im Programm, wo eine IRQ ausgelöst werden kann. Dadurch werden Konflikte vermieden, weil sonst "gleichzeitig" auf PORTB und seconds zugegriffen wird.

    Allerdings glaub ich net, daß das der Grund ist, warum es überhaupt nicht funktioniert...

    Muss man da nicht Fuses setzen?

    Und der Test auf ASSR muss *vor* dem Setzen neuer Werte gemacht werden.

    Ausserdem kannst du in der ISR einfach hinschreiben
    Code:
       PORTB ^= 16;
    Disclaimer: none. Sue me.

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

LiTime Speicher und Akkus