2016-11-15 3 views
0

Ich schreibe gerade eine Bibliothek für Lernzwecke und ich bin in ein seltsames Problem geraten.
Also,
1. Ich habe eine Funktion im Hauptteil (main.c), die die DDRAM-Adresse eines LCD liest.
2. Ich verschiebe die exakt gleiche Funktion in die Bibliotheksdatei (HD44780.c).
3. Ich füge die Header-Datei (HD44780.h) in den Hauptteil ein.
Wenn ich die Funktion aus dem Hauptkörper aufrufen, bekomme ich ein Ergebnis von 64. Richtig.
Wenn ich die gleiche Funktion aus der Bibliothek direkt nach dem vorherigen Aufruf aufrufen, bekomme ich ein Ergebnis von 87. Falsch.
Vielleicht hat es etwas mit den Bibliotheksdateien und der Erreichbarkeit der Funktionen zu tun. Meine Bibliothek ist in drei Dateien aufgeteilt.Gleiche Funktion in verschiedenen Dateien gibt unterschiedliche Ergebnisse zurück

  • HD44780.h (einschließlich HD44780_Config.h und HD44780.c und Kopfschutz)
  • HD44780.c (nichts enthalten)
  • HD44780_Config.h (einschließlich HD44780.h und hat Kopfschutz)

Irgendeine Idee? Wenn mehr Informationen benötigt werden, fragen Sie einfach.

Main.c

#define F_CPU 16000000L 

#include <util/delay.h> 
#include <avr/io.h> 
#include "IO_macros.h" 
#include "HD44780.h" 

uint8_t _read(void); 

int main(void) 
{ 
    uint8_t x1, x2; 

    LCD_setup(); 

    LCD_gotoXY(0,1); 
    x1 = _read(); //64, Correct answer 
    x2 = LCD_read(); //87, False answer 

    return 0; 
} 

uint8_t _read(void) 
{ 
    uint8_t status = 0; 

    pinMode(LCD_D4, INPUT);    //D7:D4 = Inputs 
    pinMode(LCD_D5, INPUT); 
    pinMode(LCD_D6, INPUT); 
    pinMode(LCD_D7, INPUT); 
    digitalWrite(LCD_RS, LOW);   //RS = 0 
    digitalWrite(LCD_RW, HIGH);   //RW = 1 

    //High nibble comes first 
    digitalWrite(LCD_EN, HIGH);  
    _delay_us(LCD_PULSE_US); 
    status |= digitalRead(LCD_D4)<<4; 
    status |= digitalRead(LCD_D5)<<5; 
    status |= digitalRead(LCD_D6)<<6; 
    digitalWrite(LCD_EN, LOW); 

    //Low nibble follows 
    digitalWrite(LCD_EN, HIGH);  
    _delay_us(LCD_PULSE_US); 
    status |= digitalRead(LCD_D4); 
    status |= digitalRead(LCD_D5)<<1; 
    status |= digitalRead(LCD_D6)<<2; 
    status |= digitalRead(LCD_D7)<<3; 
    digitalWrite(LCD_EN, LOW); 

    pinMode(LCD_D4, OUTPUT);   //D7:D4 = Outputs 
    pinMode(LCD_D5, OUTPUT); 
    pinMode(LCD_D6, OUTPUT); 
    pinMode(LCD_D7, OUTPUT); 
    digitalWrite(LCD_RW, LOW);   //RW = 0 

    return status; 
} 

HD44780.h

#ifndef HD44780_H_ 
#define HD44780_H_ 

#include "HD44780_Config.h" 
//Irrelevant function definitions... 
extern uint8_t LCD_read(void); 

#endif 

HD44780_Config.h

#ifndef HD44780_CONFIG_H_ 
#define HD44780_CONFIG_H_ 

#include "HD44780.h" 

//----- Configuration --------------------------// 
//Irrelevant definitons here 
//----------------------------------------------// 
#endif 

HD44780.c

//Irrelevant functions precede... 
uint8_t LCD_read(void) 
{ 
    uint8_t status = 0; 

    pinMode(LCD_D4, INPUT);    //D7:D4 = Inputs 
    pinMode(LCD_D5, INPUT); 
    pinMode(LCD_D6, INPUT); 
    pinMode(LCD_D7, INPUT); 
    digitalWrite(LCD_RS, LOW);   //RS = 0 
    digitalWrite(LCD_RW, HIGH);   //RW = 1 

    //High nibble comes first 
    digitalWrite(LCD_EN, HIGH); 
    _delay_us(LCD_PULSE_US); 
    status |= digitalRead(LCD_D4)<<4; 
    status |= digitalRead(LCD_D5)<<5; 
    status |= digitalRead(LCD_D6)<<6; 
    digitalWrite(LCD_EN, LOW); 

    //Low nibble follows 
    digitalWrite(LCD_EN, HIGH); 
    _delay_us(LCD_PULSE_US); 
    status |= digitalRead(LCD_D4); 
    status |= digitalRead(LCD_D5)<<1; 
    status |= digitalRead(LCD_D6)<<2; 
    status |= digitalRead(LCD_D7)<<3; 
    digitalWrite(LCD_EN, LOW); 

    pinMode(LCD_D4, OUTPUT);   //D7:D4 = Outputs 
    pinMode(LCD_D5, OUTPUT); 
    pinMode(LCD_D6, OUTPUT); 
    pinMode(LCD_D7, OUTPUT); 
    digitalWrite(LCD_RW, LOW);   //RW = 0 

    return status; 
} 
//...irrelevant functions follow 

Update # 1
Ich bin mit dem Atmel Studio 6 zu kompilieren. Standard-Optimierungsstufe (-O1)
Update # 2
Ich habe die Preprozessor-Ausgänge überprüft und sie sind auch identisch.
Update # 3
Konsequente Messungen haben ein falsches Ergebnis, da die Adresse bei jeder Messung erhöht/verringert wird. Das Problem besteht jedoch weiterhin. Es hat mit der Position der Funktion zu tun, aber ich weiß nicht, was es ist.
Wenn ich die Funktion in main.c aufrufen, funktioniert es.
Wenn ich es von HD44780.c aufrufen, funktioniert es nicht richtig.
#Update # 4
Ein Kerl in einem anderen Forum löste mein Problem. Sie können meine Antwort unten überprüfen.

+0

Gibt es (in HD44780.h) der Prototyp der Funktion? – LPs

+2

Vereinfachen Sie Ihren Code. Nehmen Sie Zeug aus, bis Sie einen minimalen Reprofall haben. –

+0

Wie kompilieren und verknüpfen Sie alles? –

Antwort

1

Das Problem war bei der Definition von F_CPU.
Es wurde nicht in der HD44780.c Datei definiert. Jede .c Datei ist eine eigenständige Kompilationseinheit, die während der Kompilierung mit den restlichen .c Dateien verknüpft ist.
I definiert die F_CPU nur in main.c, so die _delay_us in HD44780.c hatte falsch F_CPU Wert. Als Lösung habe ich die F_CPU im Makefile der Lösung erklärt, damit es für ALLE Dateien sichtbar ist. Die Ursache und ihre Lösung sind auf einen Typen in einem anderen Forum zurückzuführen, wo ich verzweifelt dieselbe Frage gestellt habe.
Vielen Dank für Ihre Zeit!

http://www.avrfreaks.net/comment/2029541#comment-2029541

2

bei the controller manual auf Seite der Suche 31:

Nach einem Lese erhöht der Eingabemodus automatisch oder verringert die Adresse um 1

Das bedeutet, dass zwei aufeinander folgende Lesebefehle zwei verschiedene Adreßdaten gelesen .

EDIT

Die bisherige Bezeichnung bestimmt, ob CG oder DDRAM zu lesen ist. Bevor Sie diese Anweisung lesen, müssen Sie entweder CGRAM oder die Anweisung für die Adresse der DRAM-Adresse ausführen. Wenn nicht ausgeführt, sind die ersten Lesedaten ungültig. Wenn seriell Leseanweisungen ausgeführt werden, werden die nächsten Adressdaten normalerweise vom zweiten Lesevorgang gelesen . Die Adressensatzanweisungen müssen nicht unmittelbar vor dieser Leseanweisung ausgeführt werden, wenn der Cursor mit der Cursor-Shift-Anweisung verschoben wird (beim Auslesen von DDRAM). Die Operation der Cursor-Shift-Anweisung ist die gleiche wie die eingestellte DDRAM-Adressenanweisung.

Emphasis Mine

+0

Sie haben teilweise Recht. Nachdem ich Ihren Kommentar gelesen hatte, versuchte ich, den Cursor erneut an die gleiche Stelle zu setzen, um ihn erneut zu lesen. ** Springen **, ** Lesen **, ** Springen **, ** Lesen ** und ich bekomme die gleichen falschen Ergebnisse. Ich muss es weiter testen. – ThymiosK

+0

@ThymiosK Ich bearbeitet. – LPs

+0

Ich habe den ganzen Tag auf dieses spezielle Problem angewendet, mir wurde schwindlig. Ich kann weder Ihren Standpunkt noch das Zitat verstehen, obwohl Sie die Lösung gefunden zu haben scheinen. Kannst du es bitte einfach sagen? – ThymiosK

Verwandte Themen