www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Probleme mit LCDUhr


Autor: Daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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ß

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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:
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 57,600 kHz
TCCR0=0x03;
TCNT0=0xC7;

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

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

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

  

Autor: Daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.


Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

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

Autor: Daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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:
#include <90s8515.h>
#include <stdio.h>
#asm
   .equ __lcd_port=0x15 ;PORTC
#endasm
#include <lcd.h>

volatile int timer;
char szTemp[16+1];

// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
  sprintf(szTemp,"%06d", timer);
  lcd_gotoxy(0,0);
  lcd_puts(szTemp);

  timer++;
}

void main(void)
{
  PORTC = 0x00;
  DDRC = 0xFF;

  // LCD module initialization
  lcd_init(16);

  TCCR0 = 0x05;
  TIMSK = 0x01;

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

  while (1)
  {
    ;
  }
}

Ä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.

Autor: Daniel Ascher (Firma: Ascher) (golfsburg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank!

Jetzt gehts! :D

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

Gruß

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Daniel Ascher (Firma: Ascher) (golfsburg)
Datum:

Bewertung
0 lesenswert
nicht 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ß

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.