mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Funktionsparameter


Autor: Marci (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Seid gegrüßt,

könnte mir event. jemand sagen, wo hier genau der Fehler liegen könnte?:
>Hauptprogramm

lcdScreen(0);
>lcdRoutines.h

void lcdScreen(uint8_t screenX)
{
    uint8_t xpos = 0;
    uint8_t ypos = 0;

    if(screenX == 0)
    {
        //lcdClear();
        lcdSetPos(86,0);
        lcdString8("[press >]");

        lcdSetPos(10,16);
        lcdString8("Dynasoft'");

        ypos = 24;
        lcdSetPos(19,ypos);
        for(uint8_t m=0; m<=2; m++)
        {
            for(uint8_t n=0; n<=90; n++)
            {
                lcdSendData(myFontStart[m][n]);
            }
            lcdSetPos(19,ypos += 8); // Y-Position um ein Byte (eine Zeile) weitersetzen
        }
    }
    else if(screenX == 1)
    {
        //lcdClear();
        xpos = 0;
        lcdSetPos(xpos,8);
        lcdString8("Neonröhre 1");
    }
}

Beim Starten des Programms wird lcdScreen(0) aufgerufen und wie 
gewünscht die erste if-Anweisung erfolgreich abgearbeitet (und eine 
Grafik auf das LCD gezeichnet).
Wird aber nun in der main.c, durch z.B. einen Taster, lcdScreen(1) 
aufgerufen, geschieht nix weiter (bzw. das LCD setzt kurz aus und lädt 
den Startbildschirm noch einmal).
Mittels eines USART_sendeByte()-Befehls wurde mir im Terminal "Dy" 
angezeigt - und ich habe nirgendwo etwas dazu gefunden.
Jemand eine Ahnung, was da los ist?
Aus irgendeinem Grund wird der Parameter "1" (bzw. überhaupt irgendein 
Parameter der Funktion) nicht übertragen?!??? - obwohl ich doch nach dem 
Kapitel "Funktionsdef./-deklarationen im C-Buch gearbeitet habe.

LG, Marcel

: Gesperrt durch User
Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>könnte mir event. jemand sagen, wo hier genau der Fehler liegen könnte?:

Nein, hier sind keine Hellseher unterwegs.
Kompletten Sourcecode posten oder Fehler selber suchen.

Autor: Marci (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hier die Referenzen...

main.c

#ifndef F_CPU
#define F_CPU 16000000
#endif
/*******************************************************************************************************/
// Einbindung von Standardbibliotheken
#include <stdint.h>        // Datentypen (standardisiert)
#include <avr/io.h>        // Registernamen
#include <avr/interrupt.h>
#include <stdio.h>         // Rechenoperationen, etc.
#include <stdlib.h>
#include <string.h>        // Zeichenketten-Funktionen
#include <util/delay.h>

// Einbindung der Header-Files
#include "usart.h"

#include "lcdFonts.h"
#include "lcdRoutines.h"

/*******************************************************************************************************/
// Definition von PORTpins, Masken und Konstanten
#define KEY_DDR      DDRK
#define KEY_PORT     PORTK
#define KEY_PIN      PINK
#define KEY1         0
#define KEY2         1
#define KEY3         2
#define KEYU         3
#define KEYL         4
#define KEYX         5
#define KEYR         6
#define KEYD         7
#define ALL_KEYS     (1<<KEY1 | 1<<KEY2 | 1<<KEY3 | 1<<KEYU | 1<<KEYL | 1<<KEYX | 1<<KEYR | 1<<KEYD)

#define REPEAT_MASK  (1<<KEY1 | 1<<KEY2)
#define REPEAT_START 50
#define REPEAT_NEXT  20

#define LED_DDR      DDRL
#define LED_PORT     PORTL
#define LED0         0
#define LED1         1
#define LED2         2
#define LED3         3
#define LED4         4
#define LED5         5
#define LED6         6
#define LED7         7

volatile uint8_t key_state; // debounced and inverted key state: bit = 1: key pressed
volatile uint8_t key_press; // key press detect
volatile uint8_t key_rpt;   // key long press and repeat
/*******************************************************************************************************/
ISR(TIMER0_OVF_vect)                                          // every 10ms
{
    static uint8_t ct0, ct1, rpt;
    uint8_t i;

    TCNT0 = (uint8_t)(int16_t)-(F_CPU / 1024 * 10e-3 + 0.5);  // preload for 10ms

    i = key_state ^ ~KEY_PIN;                                 // key changed ?
    ct0 = ~(ct0 & i);                                         // reset or count ct0
    ct1 = ct0 ^ (ct1 & i);                                    // reset or count ct1
    i &= ct0 & ct1;                                           // count until roll over ?
    key_state ^= i;                                           // then toggle debounced state
    key_press |= key_state & i;                               // 0->1: key press detect

    if((key_state & REPEAT_MASK) == 0)                        // check repeat function
        rpt = REPEAT_START;                                   // start delay
    if(--rpt == 0)
    {
        rpt = REPEAT_NEXT;                                    // repeat delay
        key_rpt |= key_state & REPEAT_MASK;
    }
}
/*******************************************************************************************************/
// check if a key has been pressed. Each pressed key is reported
// only once
//
uint8_t get_key_press(uint8_t key_mask)
{
    cli();                                          // read and clear atomic !
    key_mask &= key_press;                          // read key(s)
    key_press ^= key_mask;                          // clear key(s)
    sei();
    return key_mask;
}
/*******************************************************************************************************/
// check if a key has been pressed long enough such that the
// key repeat functionality kicks in. After a small setup delay
// the key is reported beeing pressed in subsequent calls
// to this function. This simulates the user repeatedly
// pressing and releasing the key.
uint8_t get_key_rpt(uint8_t key_mask)
{
    cli();                                          // read and clear atomic !
    key_mask &= key_rpt;                            // read key(s)
    key_rpt ^= key_mask;                            // clear key(s)
    sei();
    return key_mask;
}
/*******************************************************************************************************/
uint8_t get_key_short(uint8_t key_mask)
{
    cli();                                          // read key state and key press atomic !
    return get_key_press(~key_state & key_mask);
}
/*******************************************************************************************************/
uint8_t get_key_long(uint8_t key_mask)
{
    return get_key_press(get_key_rpt(key_mask));
}
/*******************************************************************************************************/
uint16_t val_PWM5a;
uint16_t val_PWM5b;

/*******************************************************************************************************/
int main(void)
{
    KEY_DDR &= ~ALL_KEYS;         // Konfiguration der Taster auf "Eingang"
    KEY_PORT |= ALL_KEYS;         // PullUp-Festlegung

    TCCR0B = (1<<CS02)|(1<<CS00); // Einstellung von Timer/Vorteiler: 1024
    TIMSK0 = 1<<TOIE0;            // Aktivierung des Timer-Interrupts

    LED_DDR = 0xFF;               // Konfiguration der LEDs auf "Ausgang"
    LED_PORT = 0xFF;              // LEDs auf logisch 1 setzen



    DDRB = 0xff;
    /***************************************************************************************************/
    // PWM-Grundeinstellungen:
    // Modi-Festlegung der Timer/Counter auf nicht-invertierende 10-Bit PWMs:
  // COMnxn = Ausgabeart des PWM-Signals (pro PWM-Kanal)
  // WGMnn = Pulsweiten-Modulatorbits, um den PWM-Modus zu aktivieren (pro Timer)
//  TCCR5A = (1<<COM5A1) | (1<<COM5B1) | (1<<WGM52) | (1<<WGM51) | (1<<WGM50);
  // Generierung eines Taktes von CK/1024 (Vorteiler)
//  TCCR5B = (1<<CS52) | (1<<CS50);
    // Festlegung der PWM-Startwerte
//    val_PWM5a = 0;
//    val_PWM5b = 0;
  // Einstellung des Top- bzw. Compare-Wertes (jeweils in Relation zur Taktlänge):
  // OCRnx = Pulsbreite (pro PWM-Kanal)
//  OCR5A = val_PWM5a; //OCR5B = val_PWM5b;
    /***************************************************************************************************/
    // Initialisierung des Displays
    lcdInitPort();
  lcdInit();
  lcdClear();
  PortLcdCtrl |= 0b00100000; // Aktivierung der Hintergrundbeleuchtung
    // Laden des LCD-Startbildschirms
    lcdScreen(0);
    /***************************************************************************************************/
    // Initialisierung des USART
    USART_Init();
    USART_SendString("Dynasoft' autoDesk gestartet.");
    //USART_ReceiveByte();
    /***************************************************************************************************/
  while(1)
    {
        // USART-Abfrage
        /*if(UDR1 == 1)
        {
            PORTL ^= (1<<PL1);
        }
        else if(UDR1 == 2)
        {
            PORTL |= (0<<PL1);
        }*/

        if(get_key_short(1<<KEY1))
        {
            LED_PORT ^= 1<<LED1;
            lcdScreen(1);
        }

        if(get_key_long(1<<KEY1))
            LED_PORT ^= 1<<LED2;

        if(get_key_press(1<<KEY2) || get_key_rpt(1<<KEY2))
        {
            uint8_t i = LED_PORT;

            i = (i & 0x07) | ((i << 1) & 0xF0);
            if( i < 0xF0 )
                i |= 0x08;
            LED_PORT = i;
        }

   }
  return 0;
}
/*******************************************************************************************************/


lcdRoutines.h
/*******************************************************************************************************/
#ifndef lcdRoutines_h
#define lcdRoutines_h
/*******************************************************************************************************/
// LCD-Informationen:
// 
// PortC = LCD-Data
// PortA = LCD-Control
//         A7 = PS (std=High=parallel Mode)
//       A6 = C86 (std=High=6800 Mode)
//          A5 = unbenutzt
//       A4 = /RD = E (Schreibflanke H->L)
//       A3 = /WR = R/W (Low=Schreiben)
//         A2 = A0 (Low=ControlData; High=DisplayData)
//       A1 = /RES (Low=activ; std=High)
//       A0 = CS1 (ChipSelect=muss Low sein; std=High)
/*******************************************************************************************************/
#define sbi(ADDRESS,BIT) ((ADDRESS) |= (1<<(BIT)))
#define cbi(ADDRESS,BIT) ((ADDRESS) &= ~(1<<(BIT)))
/*******************************************************************************************************/
// Definition der PORTs
#define PortLcdData PORTC
#define PortLcdDataPIN PINC
#define PortLcdDataDDR DDRC
#define PortLcdCtrl PORTA
#define PortLcdCtrlDDR DDRA
/*******************************************************************************************************/
// Initialisierung der Ports
void lcdInitPort()
{
  // Port-C als Eingang ohne Pullup konfigurieren (für LCD-Data)
  // Port-C muß je nach Aktion die ausgeführt wird (schreiben oder lesen) als Ausgang oder Eingang konfiguriert werden
  PortLcdDataDDR = 0x00;
  PortLcdData = 0;

  // Port-A als Ausgang konfigurieren (für LCD-Control)
  // Bit0 = CS = ChipSelect Low-aktiv
  // Bit1 = R/W = Low=Schreiben
  // Bit2 = RS = Low=Control, High=Data
  // Bit3 = E = Schreibflanke H->L
  // Bit4 = Reset = Low-aktiv
  PortLcdCtrlDDR = 0xff;
  PortLcdCtrl = 0b1100011;
}
// PE: = Parameter Eingang 
// PA: = Parameter Ausgang
// initialisiert das LCD
void lcdInit();
// sendet ein Steuerkommando an das LCD
// PE: data = Steuerkommando
void lcdSendCmd(uint8_t data);
/*******************************************************************************************************/
// schreibt ein Byte an die aktuelle Position auf dem LCD (aktuelle Position wird weitergesetzt)
// PE: data = das Byte
void lcdSendData(uint8_t data);
/*******************************************************************************************************/
// liest ein Byte von der aktuellen Position auf dem LCD (aktuelle Position wird beibehalten)
// PA: das glesene Byte
uint8_t lcdReadData();
// Setzt die Position der nächsten Ausgabe, z.B. für Texte.
// Der y-Wert wird auf eine 8er Grenze abgerundet. (0,8,16,24...56)
// PE: x = x-Koordinate 0...127; y = y-Koordinate 0...63 
void lcdSetPos(uint8_t x, uint8_t y);
/*******************************************************************************************************/
// rückt die angegebenen Zeile zur aktuellen Zeile auf dem LCD (Rolleffekt)
// PE: line = Nummer der Linie zu der gerollt werden soll
void lcdGotoLine(uint8_t line);
/*******************************************************************************************************/
// löscht alle angezeigten Daten auf dem LCD
void lcdClear();
/*******************************************************************************************************/
// schaltet die Anzeige aus/ein
// PE: on = Ein/Aus 0/1; 0 = Anzeige an; 1 = Anzeige aus (komplett dunkel)
void lcdSendCmdOn(uint8_t on);
/*******************************************************************************************************/
// invertiert die Anzeige (dunkel auf hell/ hell auf dunkel)
// PE: on = Aus/Ein 0/1; 0 = Normal (dunkel auf hell); 1 = Invers (hell auf dunkel)
void lcdSendCmdReverse(uint8_t jn);
/*******************************************************************************************************/
// setzt ein Pixel an Position x,y auf dem LCD
// PE: x = x-Koordinate 0...127; y = y-Koordinate 0...63
void lcdSetPixel(uint8_t x, uint8_t y);
/*******************************************************************************************************/
// sendet daten an das LCD, wird von lcdSendData() benutzt
// PE: data = zu sendende Daten
void lcdSend(uint8_t data)
{
  // Bit 3 an Port-A löschen (Schreiben auf LCD)
  cbi(PortLcdCtrl,3);
  // Daten auf Port-C
  PortLcdData = data;
  // Port-C als Ausgang konfigurieren
  PortLcdDataDDR = 0xFF;
  // Bit 0 an Port-A löschen (ChipSelect = An)
  cbi(PortLcdCtrl,0);
  // Bit 4 an Port-A setzen; E = 1 (Schreiben mit HighPuls an E)
  sbi(PortLcdCtrl,4);
  // Inlineassembler: kurz warten
  __asm volatile ("nop \n nop \n nop \n");
  // Bit 4 an Port-A löschen; E = 0
  cbi(PortLcdCtrl,4);        
  // Bit 0 an Port-A setzten (ChipSelect = Aus)
  sbi(PortLcdCtrl,0);
}
/*******************************************************************************************************/
// initialisiert das LCD
void lcdInit()
{
  _delay_ms(1);  
  // Licht aus
  PortLcdCtrl &= ~0b00100000;
  // Bit 0 an Port-A setzten (ChipSelect = Aus)
  sbi(PortLcdCtrl,0);
  // Bit 7 an Port-A setzten (parallel on)
  sbi(PortLcdCtrl,7);
  // Bit 6 an Port-A setzten (6800 Modus)
  sbi(PortLcdCtrl,6);

  // Reset am LCD
  PortLcdCtrl &= ~0b00000010;
  _delay_ms(1);  
  PortLcdCtrl |= 0b00000010;
  _delay_ms(1);  

  // Eine Reihe von Steuerkommandos an das LCD senden (sihe Datenblatt)
  
  // internal Reset 
  lcdSendCmd(0xE2);
  // ADC select  
  lcdSendCmd(0xA0);
  // COM output scan direction = revers   
  lcdSendCmd(0xC8);
  // LCD drive voltage bias ratio   
  lcdSendCmd(0xA2);

  lcdSendCmd(0x2F);

  lcdSendCmd(0x26);
  // select booster ratio  
  lcdSendCmd(0xF8);
  
  lcdSendCmd(0x00);
  // set output voltage  
  lcdSendCmd(0x81);

  lcdSendCmd(0x09);
  // read-modify-write  
  lcdSendCmd(0xE0);  
  // display on
  lcdSendCmd(0xAF);  
}
/*******************************************************************************************************/
// sendet ein Steuerkommando an das LCD
// PE: data = Steuerkommando
void lcdSendCmd(uint8_t data)
{
    // Bit 2 an Port-A löschen (Datenart = Steuerkommando)
  cbi(PortLcdCtrl,2);
  // Senden
  lcdSend(data);
}
/*******************************************************************************************************/
// schreibt ein Byte an die aktuelle Position auf dem LCD (aktuelle Position wird weitergesetzt)
// PE: data = das Byte
void lcdSendData(uint8_t data)
{
  // Bit 2 an Port-A setzten (Datenart = Daten)
  sbi(PortLcdCtrl,2);
  // Senden
  lcdSend(data);
}
/*******************************************************************************************************/
// liest ein Byte von der aktuellen Position auf dem LCD (aktuelle Position wird beibehalten)
// PA: das Byte
uint8_t lcdReadData()
{
  uint8_t data;

  // Port-C als Eingang konfiguriren (für lesen)
  PortLcdDataDDR = 0x00;
  // Bit 2 an Port-A setzten (Datenart = Daten)
  sbi(PortLcdCtrl,2);
  // Bit 3 an Port-A setzten (lesen)
  sbi(PortLcdCtrl,3);
  // Bit 0 an Port-A löschen (ChipSelect = An)
  cbi(PortLcdCtrl,0);

  // ein DUMMY-lesen nach Adress-Änderung (MUSS SEIN!)

  // Bit 4 an Port-A setzten (Flanke vorbereiten)
  sbi(PortLcdCtrl,4);
  // Inlineassembler: kurz warten
  __asm volatile ("nop \n nop \n nop \n");
  // Bit 4 an Port-A löschen
  cbi(PortLcdCtrl,4);

  // Ende DUMMY-lesen

  // Bit 4 an Port-A setzten (Flanke vorbereiten)
  sbi(PortLcdCtrl,4);
  // Inlineassembler: kurz warten
  __asm volatile ("nop \n nop \n nop \n");
  // Daten an PIN-C holen
  data=PortLcdDataPIN;
  // Bit 4 an Port-A löschen
  cbi(PortLcdCtrl,4);        

  // Bit 0 an Port-A setzten (ChipSelect = Aus)
  sbi(PortLcdCtrl,0);
  // Port-C als Ausgang konfigurieren
  PortLcdDataDDR = 0xFF;

  return data;
}
/*******************************************************************************************************/
// Setzt die Position der nächsten Ausgabe, z.B. für Texte.
// Der y-Wert wird auf eine 8er Grenze abgerundet. (0,8,16,24...56)
// PE: x = x-Koordinate 0...127; y = y-Koordinate 0...63
void lcdSetPos(uint8_t x, uint8_t y)
{
  // x-Koordinate
  lcdSendCmd(0b00010000 + (x>>4));
  lcdSendCmd(0b00000000 + (x & 0x0f));
  // y-Koordinate
  lcdSendCmd(0b10110000 + (y>>3));
}
/*******************************************************************************************************/
// rückt die angegebenen Zeile zur aktuellen Zeile auf dem LCD (Rolleffekt)
// PE: line = Nummer der Linie zu der gerollt werden soll
void lcdGotoLine(uint8_t line)
{
  // Zeile initialisieren
  lcdSendCmd(0b01000000 + (line & 0b00111111));
}
/*******************************************************************************************************/
// löscht alle angezeigten Daten auf dem LCD
void lcdClear()
{
  // die Anzeige besteht 128 * 8 Bytes, welche senkrecht angeordnet sind
  // in jedem Byte liegt Bit0 oben und Bit7 unten
  // y-Schleife (senkrecht); 8 mal, da 64 Pixel aus 8 Bytes je 8 Bits bestehen  
  for(uint8_t y=0; y<64; y+=8)
  {
      // gehe zu Zeilenanfang
    lcdSetPos(0,y);
    // x-Schleife (waagerecht); 128 Pixel sind 128
    for(uint16_t x=0; x<128; x++)
      // Byte auf 0 setzen
      lcdSendData(0);
  }
  // aktuelle Position auf linksoben setzen (0,0)
  lcdSetPos(0,0);
}
/*******************************************************************************************************/
// invertiert die Anzeige (dunkel auf hell/ hell auf dunkel)
// PE: on = Aus/Ein 0/1; 0 = Normal (dunkel auf hell); 1 = Invers (hell auf dunkel)
void lcdSendCmdReverse(uint8_t jn)
{
  // Anzeige normal/revers
  lcdSendCmd(0b10100110 + jn);
}
/*******************************************************************************************************/
// schaltet die Anzeige aus/ein
// PE: on = Ein/Aus 0/1; 0 = Anzeige an; 1 = Anzeige aus (komplett dunkel)
void lcdSendCmdOn(uint8_t on)
{
  // Alle Pixel an/aus
  lcdSendCmd(0b10100100 + on);
}
/*******************************************************************************************************/
// setzt ein Pixel an Position x,y auf dem LCD
// PE: x = x-Koordinate 0...127; y = y-Koordinate 0...63
void lcdSetPixel(uint8_t x, uint8_t y)
{
  // gehe zur Position
  lcdSetPos(x,y);
  uint8_t data;
  // Bitmuster für Position  des Bits (Pixel) im Byte
  data = 1<<(y & 0b00000111);
  // Byte auslesen, Bit setzten, Byte zurückschreiben
  lcdSendData(lcdReadData()|data);
}
/*******************************************************************************************************/
void lcdChar8(int c) // c ist hier der jeweilige ASCII-Wert (z.B.: "A">65) des gesendeten Charakters
{
    for(uint8_t nColumn=1; nColumn<=7; nColumn++)
    {
        lcdSendData(myFont[c][nColumn]);
        if(nColumn == myFont[c][0]) // wenn das Ende des Charakters im Array erreicht ist...
        {
            lcdSendData(0x00); // ... ein 0-Byte (leere Spalte) senden...
            break; // ... und Funktion verlassen (bzw. nächsten Charakter einlesen)
        }
    }
}
/*******************************************************************************************************/
// Bildung einer Zeichenkette aus den einzelnen Charaktern:
void lcdString8(const char *data)
{
    while(*data != '\0')
        lcdChar8(*data++);
}
/*******************************************************************************************************/
// Auswahl der Screens
void lcdScreen(uint8_t screenX)
{
    uint8_t xpos = 0;
    uint8_t ypos = 0;

    if(screenX == 0) // Startbild
    {
        //lcdClear();
        lcdSetPos(86,0);
        lcdString8("[press >]");

        lcdSetPos(10,16);
        lcdString8("Dynasoft'");

        ypos = 24;
        lcdSetPos(19,ypos);
        for(uint8_t m=0; m<=2; m++)
        {
            for(uint8_t n=0; n<=90; n++)
            {
                lcdSendData(myFontStart[m][n]);
            }
            lcdSetPos(19,ypos += 8); // Y-Position um ein Byte (eine Zeile) weitersetzen
        }
    }
    else if(screenX == 1) // Testbild
    {
        //lcdClear();
        xpos = 0;
        lcdSetPos(xpos,8);
        lcdString8("Neonröhre 1");
    }
}
/*******************************************************************************************************/
#endif
/*******************************************************************************************************/


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

Bewertung
0 lesenswert
nicht lesenswert
> Wird aber nun in der main.c, durch z.B. einen Taster, lcdScreen(1)
> aufgerufen, geschieht nix weiter (bzw. das LCD setzt kurz aus und lädt
> den Startbildschirm noch einmal).

Klingt ganz danach, als ob dein Tastendruck einen Kurzschluss auslösen 
würde und dein Prozessor neu startet.


Mach doch mal am Anfang bei der ersten Gelegenheit eine Testausgabe 
rein, dann weißt du es genau
    lcdInitPort();
  lcdInit();
  lcdClear();
  PortLcdCtrl |= 0b00100000; // Aktivierung der Hintergrundbeleuchtung

//////////////////////////
  lcdString8( "Starting" );
  _delay_ms( 1000 );
  lcdClear();
//////////////////////////

    // Laden des LCD-Startbildschirms
    lcdScreen(0);

Wenn du die "Starting" Meldung siehst, dann ist dein µC aus irgendeinem 
Grund resettet worden.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Marci (Gast)

>Hier die Referenzen...

patsch

Und hier die Watschn für soviel Ignoranz! Lies mal was über 
Netiquette!
Lange Quelltexte gehören in den ANHANG!

Autor: Marci (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Karl Heinz:

Vielen lieben Dank für die schnelle Hilfe!;-)

Fazit:
Einmal wird das "Starting" kurz angezeigt und wechselt dann zum 
Startbildschirm.
Ein anderes Mal wird im Loop das "Starting" neu geladen.

Ich versteh, wie und warum? An welcher Stelle?

@ Falk:

Ok. Ich wußte dies nicht, werd´ich mir merken.
Code einfach zu "überblicken" war mir in der Regel auch selbst lieber, 
als erst irgendwelche Anhänge öffnen zu müssen.

LG, Marcel

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

Bewertung
0 lesenswert
nicht lesenswert
Marci schrieb:
> @ Karl Heinz:
>
> Vielen lieben Dank für die schnelle Hilfe!;-)
>
> Fazit:
> Einmal wird das "Starting" kurz angezeigt und wechselt dann zum
> Startbildschirm.
> Ein anderes Mal wird im Loop das "Starting" neu geladen.

Wenn du das "STarting" mehr als einmal siehst, dann wird dein µC aus 
irgendeinem Grund resettet. Da du weiter oben von Tasten gesprochen 
hast, wirst du wohl mit den Tasten beim Drücken einen Kurzschluss 
auslösen oder sonst irgendetwas schlimmes machen. (Ist nur eine 
Möglichkeit, eine andere wäre zb ein Stackoverflow)

> Ich versteh, wie und warum? An welcher Stelle?

Wenn du innerhalb der Loop keinen Text "Starting" ausgibst, dann KANN 
diese Ausgabe nur von einem Neustart des Prozessors stammen. Genau das 
war der Sinn der Übung das herauszufinden.

Autor: Marci (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ps.:

Upps, da hatt´ich doch glatt das NICHT vergessen.;-)

Hmmmm... der Grund, warum ich es ned versteh´ ist, dass die Anweisungen 
IN der lcdScreen-Funktion ja direkt in main.c-main aufgerufen, ja 
einwandtfrei funktionieren.

LG, Marcel

Autor: Marci (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hmmmm... aber der Taster an sich funktionert ja. 1000e Male schon in der 
Anwendung getestet!?

LG, Marcel

Autor: Marci (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich kann mir eigentlich nur vorstellen, dass die untenstehende Funktion 
nichtdefinierte Typen, etc. einen Fehler verursacht...


Mit dem Parameter 0 in folgender Funktion...
lcdScreen(0);

... müßte doch screenX als Wert 0 haben, oder hab´ ich 
Funktionsdeklarationen nicht ganz verstanden?
void lcdScreen(uint8_t screenX)
{

}

LG, Marcel

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Ich kann mir eigentlich nur vorstellen, dass die untenstehende Funktion
>nichtdefinierte Typen, etc. einen Fehler verursacht...

Und ich könnte mir vorstellen das da wohl eine
Sonneneruption stattfindet wenn du auf die Taste drückst.

Oben wird ja noch was per UART ausgegeben.
Zeig deine UART Routinen. Vermutlich wird da
irgendwo ein Interrupt freigegeben für den
es keine Interruptroutine gibt.

Autor: Marci (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Holger,

versteh´ dies jetzt bitte nicht falsch, aber dein Zynismus gehört nicht 
an einen Platz, an dem erwachsene Menschen zivilisiert miteinander 
kommunizieren möchten. Schlaue Sprüche übrigens auch nicht.

Ich bin kein Anfänger, sondern habe schon langjährige Erfahrungen in 
ActionScript, StarBasic, VBA und teils auch PHP.
Glaub mir bitte, wenn ich dir hiermit mitteile, dass ich es recht gut 
abschätzen kann, dir Codeschnipsel vorzuenthalten, von denen ich der 
Meinung bin, dass sie irrelevant bezüglich eines bestimmten Kontextes 
sind und desweiteren die Übersicht sowie auch Effektivität hier im Forum 
noch weiter beeinträchtigen würden.

Die USART-Funktionen laufen reibungslos. Mich wundert aber, dass du die 
lcdFonts.h gar nicht erwähnst - diese hat nämlich mehrere Hundert Zeilen 
Code.;-)) > ist aber auch nicht von Bedeutung.

Wenn du mir immer noch helfen möchtest...
... ich habe herausgefunden, dass die Funktion soweit bestens 
funktioniert, seltsamerweise ist die Bedingung dafür aber der Parameter 
0: sprich, sobald die Funktion lcdScreen() einen anderen Parameter als 0 
übergeben bekommt, stürzt das Programm ab und lädt von neuem. Ich hab 
zudem mal kurz auf Wikipedia ein paar Zeilen über "Überlauf" gelesen... 
und das klingt irgendwie nach dem Problem. Zumal es mir so vorkommt, als 
ob der Funktion anscheinend kein Parameter-Wert übergeben wird und bei 
"0" ganz einfach nur die erste if-Anweisung durchlaufen werden könnte.

Ich weiß es auch nicht.:(

Vielleicht aber einer von euch.

LG, Marcel

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

Bewertung
0 lesenswert
nicht lesenswert
Marci schrieb:

> Vielleicht aber einer von euch.

Nein, von uns weiß das auch keiner, solange du uns kein vollständiges 
Programm gibst, das man mal durch den Compiler jagen könnte und sich zb 
die Speicherauslastung ansehen kann.

> Ich hab zudem mal kurz auf Wikipedia ein paar Zeilen über "Überlauf"
> gelesen... und das klingt irgendwie nach dem Problem.

Stacküberlauf könnte sein. Dann passiert alles mögliche.
Der Überlauf, der dir da im Hinterstübchen vorschwebt, ist es nicht.

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>versteh´ dies jetzt bitte nicht falsch, aber dein Zynismus gehört nicht
>an einen Platz, an dem erwachsene Menschen zivilisiert miteinander
>kommunizieren möchten. Schlaue Sprüche übrigens auch nicht.

Ich bin nicht zynisch, ich hab dir einen Tipp gegeben.
Der könnte falsch sein. So what?

>Ich bin kein Anfänger,

Ich auch nicht.

> sondern habe schon langjährige Erfahrungen in
>ActionScript, StarBasic, VBA und teils auch PHP.

Kannst dir die Zertifikate dazu bei uC an die Wand kleben.

>Glaub mir bitte, wenn ich dir hiermit mitteile, dass ich es recht gut
>abschätzen kann, dir Codeschnipsel vorzuenthalten,

Dann behalte sie für dich und stell hier keine Fragen mehr.

> von denen ich der
>Meinung bin, dass sie irrelevant bezüglich eines bestimmten Kontextes
>sind und desweiteren die Übersicht sowie auch Effektivität hier im Forum
>noch weiter beeinträchtigen würden.

Ich bevorzuge komplette Quellcodes. Die dürfen durchaus sehr komplex
und groß sein. Was irrelevant ist wird sich noch rausstellen.

>Mich wundert aber, dass du die
>lcdFonts.h gar nicht erwähnst - diese hat nämlich mehrere Hundert Zeilen
>Code.;-)) > ist aber auch nicht von Bedeutung.

Die habe ich nicht erwähnt weil ich sie NIE gesehen habe;)

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl Heinz Buchegger schrieb:
> Stacküberlauf könnte sein.

Da würde ich auch mein Geld drauf setzen, denn offensichtlich hat er ja 
in lcdFonts.h ganze Fonts im RAM liegen.

Marci schrieb:
> Mich wundert aber, dass du die
> lcdFonts.h gar nicht erwähnst - diese hat nämlich mehrere Hundert Zeilen
> Code.;-)) > ist aber auch nicht von Bedeutung.

Aber seiner Meinung nach ist die Datei ja nicht von Bedeutung.
Ach, es ist doch immer wieder "schön", wenn "erfahrene Programmierer" 
vorbei schauen, die zwar selber nicht in der Lage sind den Fehler zu 
finden, aber trotzdem meinen, den Hilfswilligen einhämmern zu müssen, wo 
der Fehler auf keinen Fall zu suchen ist.

@Marci:
> Die USART-Funktionen laufen reibungslos.
Sowas ist absolut kein Argument Code vorzuenthalten. Wo du doch ein ach 
so erfahrener Programmierer bist, müsstest du doch eigentlich wissen, 
dass das keinesfalls bedeutet "sind garantiert fehlerfrei". Es bedeutet 
lediglich, dass in den bisher getesteten Konstellationen keine Probleme 
aufgetaucht sind. Vielleicht waren bisher einfach Interrupts nur nie 
global freigeschaltet, und schon wird aus "laufen (bisher) reibungslos" 
ein "hier desaströs", sollte dort z.B. der TXC-Interrupt freigeschaltet 
werden. Ich selber vermute zwar die Stack-Kollision, aber die Nachfrage 
von holger zum UART-Code war berechtigt.

Autor: Marci (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Jungs^^,

ich habe wohl gerade meine Läuterung erfahren?!;-)
Bitte entschuldigt, es war nicht meine Absicht, schlechtes Karma zu 
verbreiten oder irgendjemandem auf den Schlips zu treten. Sorry.

Ich wollte einfach nur Unnötiges vermeiden - aber dies ist sicher eine 
Frage des Standpunktes bzw. der Erfahrung.^^

Also wenn mir immer noch jemand helfen mag (bitte, BITTE!), hier die 
Dateien...

LG, Marcel

Autor: achja (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
langjährige Erfahrung? Ich will ja nicht böse sein aber...

Die Definition von char myFont[256][8] in einer Headerdatei???? Und ohne 
"const"? Und so dass alles im RAM landet? (Da müsste ein Schlüsselwort 
hin, "PROGMEM" glaube ich).

Autor: Marci (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hey ho;-),

"langjährig" heißt nicht unbedingt "tiefgreifend".
Zudem ist C, mit samt seinen externen Files, auch nicht unbedingt leicht 
verdaubar. Mit z.B. "Bitoperationen" und überhaupt hardwarenaher 
Programmierung, mußte ich mich bis heuer noch niemals auseinandersetzen.

Also wenn du genauere Informationen dazu hast, nur heraus damit.;-)
Ich habe nämlich erst vor einigen Tagen mit dem Kapitel header-Files 
angefangen...

LG, Marcel

Ps.: Bei der Erstellung des mehrdimensionalen Arrays hatten mir sogar 
einige Moderatoren geholfen... wenn dort also etwas nicht stimmt, wissen 
wir, wohin wir uns wenden müssen.;-))))

Autor: achja (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
AIAIAI, die anderen beide Header enthalten ja auch Code.
Und dann das da
> // Einbindung der Header-Files
> #include "lcdFonts.h"
> #include "lcdRoutines.h"
> #include "usart.h"
Ich glaub dir mangelt es an Grundlagen über Code-/Headerdateien und die 
C-Toolchain!

Autor: Marci (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dies entspricht absolut der Wahrheit. Wie gesagt... ich habe erst vor 
Tagen damit angefangen.^^

LG, Marcel

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Na da haben wir ja schon einen Fehler im unwichtigen UART Code;)

// Senden von Zeichenketten (Strings)
void uartPutChar(char data)
{
    while (!(UCSR1A & 103));
    UDR1 = data;
}

Die 103 gehört da bestimmt nicht hin.

Autor: Marci (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hey Holger,

die 103 ist ein Parameter für UBRR (16MHz; 9600Baud; U2xn=0) und der 
Aufbau aller USART-Anweisungen ist DIREKT aus der Betriebsanleitung 
meines ATmega übernommen.

Autor: Marci (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ps.: Ach ne, Schmarrn... die String-Funktion hab´ ich durch Hilfe der 
Moderatoren gebastelt.^^

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>die 103 ist ein Parameter für UBRR (16MHz; 9600Baud; U2xn=0) und der
>Aufbau aller USART-Anweisungen ist DIREKT aus der Betriebsanleitung
>meines ATmega übernommen.

Und was hat die Baudrate mit UCSR1A zu tun?

Autor: Marci (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Holger,

du scheinst es irgendwie mit meiner USART-Funktion zu haben, was?;-))

Hm... also von meinem Board-Hersteller habe ich folgende Kommentierung 
zu der Codezeile:

//warte bis UDR leer ist UCSR0A / USR bei z.B.: 2313

Mehr weiß ich bis dato auch nicht.

Ist bis jetzt aber auch nicht wichtig. Diese Funktion geht erst einmal 
und hat nichts mit meinem Problem zu tun. Komplett OHNE USART stürzt der 
Chip trotzdem ab.

LG, Marcel

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Hallo Holger,
>
>du scheinst es irgendwie mit meiner USART-Funktion zu haben, was?;-))

Naja, sie ist falsch. Daran kannst du noch arbeiten.

>Hm... also von meinem Board-Hersteller habe ich folgende Kommentierung
>zu der Codezeile:
>
>//warte bis UDR leer ist UCSR0A / USR bei z.B.: 2313

He,he. Da hat der dir ne Antwort drauf gegeben? Was bedeutet 2313?

>Ist bis jetzt aber auch nicht wichtig. Diese Funktion geht erst einmal

Glaub ich nicht. Dein Post:

>Mittels eines USART_sendeByte()-Befehls wurde mir im Terminal "Dy"
>angezeigt

Das liegt sehr wahrscheinlich an der falschen UART Routine.
Die Ausgabe wird nicht komplett beendet.

>und hat nichts mit meinem Problem zu tun. Komplett OHNE USART stürzt der
>Chip trotzdem ab.

Kommen wir mal zur Ausgangsfrage:

>Wird aber nun in der main.c, durch z.B. einen Taster, lcdScreen(1)
>aufgerufen, geschieht nix weiter

Ich sehe in deinem aktuellen Programm kein lcdScreen(1).
Wo ist das hin?

Im Sourcecode steht das Programm ist für einen ATmega2560.
Hast du das Programm für einen ATMega2560 übersetzt?
Benutzt du einen ATMega2560?

Der RAM Bedarf liegt bei 2,5kB. Sollte mit einem Atmega2560
also kein Problem sein.

Autor: Marci (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Holger...

danke für das Feedback.
Wahrscheinlich hast du Recht. Das mit dem "Dy" fand ich schon recht 
seltsam^^.
Ich hab gestern nochmal die USART-Source-Codes für den 2560 von Atmel 
durchstöbert und da sind die Routinen etwas anders. Dort gibt es 
allerdings auch keine Routine für eine String-Verarbeitung.

Jepp, du hast Recht. Ich hatte ja zwischenzeitlich diverse Versuche 
gemacht und scheinbar vor dem POST nicht mehr umgestellt. In der Abfrage 
von KEY1 muß natürlich lcdScreen(1) stehen.

Ich habe das Programm gestern in eine einzige .c-Datei geschrieben und 
bis auf die Tasterabfrage und die lcdScreen()-Funktion alles 
herausgenommen und voilá, das Problem besteht weiterhin...:(
Es scheint (wie auch schon mal vorher angedeuted) an der 
String-Funktion...
void lcdChar8(int c) // c ist hier der jeweilige ASCII-Wert (z.B.: "A">65) des gesendeten Charakters
{
    for(uint8_t nColumn=1; nColumn<=7; nColumn++)
    {
        lcdSendData(myFont[c][nColumn]);
        if(nColumn == myFont[c][0]) // wenn das Ende des Charakters im Array erreicht ist...
        {
            lcdSendData(0x00); // ... ein 0-Byte (leere Spalte) senden...
            break; // ... und Funktion verlassen (bzw. nächsten Charakter einlesen)
        }
    }
}

... zu liegen (ist auch die einzige Funktion, die ich bis dato komplett 
ohne Hilfe schrieb).
Diese Funktion bekommt (sollte zum.^^) ja von lcdString8 einen Charakter 
übergeben und sollte dann für die Dekrement-Routine in der Schleife 
direkt mit dem dazugehörigen ASCII-Wert weiterrechnen können.
Kann da der Fehler drin sein.

LG, Marcel

Ps.: Und jepp, hab´s versucht, soweit ich es verstanden habe, auf den 
2560 anzugleichen.

Autor: Marci (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hey Jungs,

niemand einen Rat?

LG

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast Du denn Deinen Code schon mal in einem Debugger laufen lassen?

Autor: Marci (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hab´s schon mal versucht, aber ich komm mit AVR Studio nocht nicht so 
gut zurecht.

LG

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dann üb' das. Vor dem Rennen kommt das Laufen.

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Dann üb' das. Vor dem Rennen kommt das Laufen.

Und vor dem Laufen kommt das Gehen;)

Dieser Beitrag ist gesperrt und kann nicht beantwortet werden.