Probleme mit LCDUhr

Gast #571035
Lesenswert?

/*****************************************************
This program was produced by the
CodeWizardAVR V1.24.2c Evaluation
Automatic Program Generator
© Copyright 1998-2004 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.ro
e-mail:office@hpinfotech.ro

Project :
Version :
Date    : 13.05.2005
Author  : Freeware, for evaluation and non-commercial use only
Company :
Comments:


Chip type           : AT90S8515
Clock frequency     : 3,686411 MHz
Memory model        : Small
External SRAM size  : 0
Data Stack size     : 128
*****************************************************/

#include <90s8515.h>

// Alphanumeric LCD Module functions
#asm
   .equ __lcd_port=0x15 ;PORTC
#endasm
#include <lcd.h>
#include <stdio.h>
char timer;
char seconds=-1;
char minutes=0;
char hours=0;
char szTemp[16+1];
void watch();
// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
// Reinitialize Timer 0 value
TCNT0=0xC7;
// Place your code here
if (timer>0) timer--;
}

// Declare your global variables here

void main(void)
{
// Declare your local variables here

// Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In 
Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T 
State0=T
PORTA=0x00;
DDRA=0x00;

// Port B initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out 
Func0=Out
// State7=1 State6=1 State5=1 State4=1 State3=1 State2=1 State1=1 
State0=1
PORTB=0xFF;
DDRB=0xFF;

// Port C initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out 
Func0=Out
// State7=0 State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 
State0=0
PORTC=0x00;
DDRC=0xFF;

// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In 
Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T 
State0=T
PORTD=0x00;
DDRD=0x00;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 57,600 kHz
TCCR0=0x03;
TCNT0=0xC7;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
GIMSK=0x00;
MCUCR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x02;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
// Analog Comparator Output: Off
ACSR=0x80;

// LCD module initialization
lcd_init(16);

// Global enable interrupts
#asm("sei")

while (1)
      {
      // Place your code here
      if (timer==0) watch();
      };
}
void watch(void)
{
  timer=10000;
  seconds++;
         if (seconds>59)
     {
       seconds=0;
       minutes++;
       }
        else if (minutes>59)
     {
        minutes=0;
          hours++;
        }
        else if (hours>23)
        {
         hours=0;
       }

       sprintf(szTemp,"Time:   %02d:%02d:%02d",hours,minutes,seconds);
       lcd_gotoxy(0,0);
       lcd_puts(szTemp);

}


Die LCD Uhr gibt leider keinen Sekunden takt aus und zählt hoch!

Vielleicht kann mir da einer weiter helfen!

Gruß
#571065
Lesenswert?

Ich hasse es mich durch Unmengen von Wizard generiertem Code
zu quälen, den kein Mensch braucht nur um dann
auf folgendes zu stossen:
1
// Timer/Counter 0 initialization
2
// Clock source: System Clock
3
// Clock value: 57,600 kHz
4
TCCR0=0x03;
5
TCNT0=0xC7;

Wenn der Kommentar stimmt, dann kriegst du 57600 Intrrupts
in der Sekunde. Mit einem Wert von
1
timer=10000;

wird die Uhr als um einen Faktor 5.6 zu schnell laufen.

Timer muss als volatile definiert werden
1
#include <stdio.h>
2
volatile char timer;
3
char seconds=-1;

  
Gast #571080
Lesenswert?

#include <90s8515.h>
#include <stdio.h>
#asm
   .equ __lcd_port=0x15 ;PORTC
#endasm
#include <lcd.h>

volatile char timer;
char seconds=-1;
char minutes=0;
char hours=0;
char szTemp[16+1];
void watch();
// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
// Reinitialize Timer 0 value
TCNT0=0xC7;
// Place your code here
if (timer>0) timer++;
}

// Declare your global variables here

void main(void)
{

PORTA=0x00;
DDRA=0x00;

PORTB=0xFF;
DDRB=0xFF;

PORTC=0x00;
DDRC=0xFF;

PORTD=0x00;
DDRD=0x00;


TCCR0=0x03;
TCNT0=0xC7;


TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
GIMSK=0x00;
MCUCR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x02;


ACSR=0x80;

// LCD module initialization
lcd_init(16);

// Global enable interrupts
#asm("sei")

while (1)
      {
      // Place your code here
      if (timer==0) watch();
      };
}
void watch(void)
{
  timer=10000;
  seconds++;
         if (seconds>59)
     {
       seconds=0;
       minutes++;
       }
        else if (minutes>59)
     {
        minutes=0;
          hours++;
        }
        else if (hours>23)
        {
         hours=0;
       }

       sprintf(szTemp,"Time:  %02d:%02d:%02d",hours,minutes,seconds);
       lcd_gotoxy(0,0);
       lcd_puts(szTemp);

}

Sorry hab leider immer noch nicht des so hin bekommen das erzählt aber 
danke nochmal!
#571110
Lesenswert?

Daniel wrote:

> Sorry hab leider immer noch nicht des so hin bekommen das erzählt aber
> danke nochmal!


Wird deine Interrupt Funktion überhaupt aufgerufen?
(Mach da mal in der Interrupt Funktion eine LED an und
sieh nach ob sie auch tatsählich eingeschaltet wird)


Ansonsten:

volatile char timer;

  timer=10000;

Das wirds nicht spielen. Ein char hat gerade mal 8 Bit.
Damit kannst du bis 255 zählen. Mehr aber auch nicht.
(Hat der Compiler da gar nichts dazu gesagt ?)

if (timer>0) timer++;

Ich denke mal, du willst den Timer runterzählen auf 0
und nicht hochzählen.

Mach doch mal folgendes:
Lass dir in der Inerruptfunktion den aktuellen Timer
Wert ausgeben.

// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
  // Reinitialize Timer 0 value
  TCNT0=0xC7;

  sprintf(szTemp,"%06d", timer);
  lcd_gotoxy(0,0);
  lcd_puts(szTemp);

  timer--;
}

und beobachte mal, ob sich überhaupt was tut.

Normalerweise ist es unklug in einer Interrupt Funktion
solch aufwändige Dinge wie LCD Ausgaben zu machen. Da
du aber einen Vorteiler von 1024 hast, solltest du etwas Zeit
haben um das zu tun. Und wenn zwischendurch mal ein Interrupt
verloren geht, ist es bei diesem Testprogramm kein Beinbruch.
Es geht lediglich darum festzustellen, ob der Interrupt auch
ausgelöst wird.
Gast #571116
Lesenswert?

#include <90s8515.h>
#include <stdio.h>
#asm
   .equ __lcd_port=0x15 ;PORTC
#endasm
#include <lcd.h>

volatile char timer;
char seconds=-1;
char minutes=0;
char hours=0;
char szTemp[16+1];
void watch();
// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
  // Reinitialize Timer 0 value
  TCNT0=0xC7;

  sprintf(szTemp,"%06d", timer);
  lcd_gotoxy(0,0);
  lcd_puts(szTemp);

  timer--;
}

// Declare your global variables here

void main(void)
{

PORTA=0x00;
DDRA=0x00;

PORTB=0xFF;
DDRB=0xFF;

PORTC=0x00;
DDRC=0xFF;

PORTD=0x00;
DDRD=0x00;


TCCR0=0x03;
TCNT0=0xC7;


TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
GIMSK=0x00;
MCUCR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x02;


ACSR=0x80;

// LCD module initialization
lcd_init(16);

// Global enable interrupts
#asm("sei")

while (1)
      {
      // Place your code here
      if (timer==0) watch();
      };
}
void watch(void)
{
  timer=10000;
  seconds++;
         if (seconds>59)
     {
       seconds=0;
       minutes++;
       }
        else if (minutes>59)
     {
        minutes=0;
          hours++;
        }
        else if (hours>23)
        {
         hours=0;
       }

       sprintf(szTemp,"Time:  %02d:%02d:%02d",hours,minutes,seconds);
       lcd_gotoxy(0,0);
       lcd_puts(szTemp);
}

Ne bei meinem Code geht leider gar nichts!

Aber ich finde es klasse von dir mir zur Helfen! :D

Danke
#571127
Lesenswert?

Daniel wrote:

Vielleicht ist das ja beim 8515 anders.
Aber bei den Prozessoren die ich benutze, ist
das hier

>
> // Timer(s)/Counter(s) Interrupt(s) initialization
> TIMSK=0x02;

die Initialisierung für einen Interrupt bei einem Compare
Match.
Du willst aber einen Overflow Interrupt haben. Da muesste
es
  TIMSK = 0x01;
heissen.

Probier doch mal dieses hier:
1
#include <90s8515.h>
2
#include <stdio.h>
3
#asm
4
   .equ __lcd_port=0x15 ;PORTC
5
#endasm
6
#include <lcd.h>
7

8
volatile int timer;
9
char szTemp[16+1];
10

11
// Timer 0 overflow interrupt service routine
12
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
13
{
14
  sprintf(szTemp,"%06d", timer);
15
  lcd_gotoxy(0,0);
16
  lcd_puts(szTemp);
17

18
  timer++;
19
}
20

21
void main(void)
22
{
23
  PORTC = 0x00;
24
  DDRC = 0xFF;
25

26
  // LCD module initialization
27
  lcd_init(16);
28

29
  TCCR0 = 0x05;
30
  TIMSK = 0x01;
31

32
  // Global enable interrupts
33
  #asm("sei")
34

35
  while (1)
36
  {
37
    ;
38
  }
39
}

Änderungen:
* Alles was nicht unmittelbar mit dem Timer, Interrupt oder
  LCD zu tun hat, ist rausgeflogen
* Der Vorteiler wurde auf Maximum, also auf 1024
  gesetzt.
* Im TIMSK wurde der Overflow Interrupt und nicht der Compare
   Match Interrupt freigegeben.
#571144
Lesenswert?

Daniel Ascher wrote:
> Vielen Dank!
>
> Jetzt gehts! :D
>
> Kann man jetzt eigentlich die Zeit auch in 00:00:00 noch einteilen?
>

Sicher. So wie du das gemacht hast, ist das mal ein erster
Schritt.

Dein Problem war, dass du den falschen Interrupt freigegeben
hast.
Mit Datenblatt anstelle von 'Erstell-mir-mal-ein-Programmgerüst-
Wizzard" wär dir das nicht passiert.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren