Forum: Mikrocontroller und Digitale Elektronik Probleme mit LCDUhr


von Daniel (Gast)


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ß

von Karl H. (kbuchegg)


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;

  

von Daniel (Gast)


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!

von Karl H. (kbuchegg)


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.

von Daniel (Gast)


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

von Karl H. (kbuchegg)


Lesenswert?

Daniel wrote:

> Ne bei meinem Code geht leider gar nichts!

Was heist gar nichts?
Kriegst du auch keine Ausgabe in der Interrupt Funktion?
Dann wird der nicht aufgerufen. Jetzt heist es erst mal
rausfinden warum.


von Karl H. (kbuchegg)


Lesenswert?

Blöde Zwischenfrage:
Hast du schon mal verifiziert ob das LCD überhaupt
funktioniert?

von Daniel (Gast)


Lesenswert?

Doch aber die Uhr bleibt auf 00:00:00 stehen!

Mein Board ist ein STK200 mit 4Mhz Takt!

Bin leider überhaupt kein Profi in C.

von Karl H. (kbuchegg)


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.

von Daniel A. (Firma: Ascher) (golfsburg)


Lesenswert?

Vielen Dank!

Jetzt gehts! :D

Kann man jetzt eigentlich die Zeit auch in 00:00:00 noch einteilen?

Gruß

von Karl H. (kbuchegg)


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.

von Daniel A. (Firma: Ascher) (golfsburg)


Lesenswert?

Bin leider erst am anfang meiner C Karriere hab den Compiler erst seid 3 
Wochen wieder.

Dank dir nochmal vielleicht hast du ja mal zeit mir noch ein paar Fragen 
zu beantworten! :D

Gruß

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.