2016-11-15 58 views
0

我目前正在爲學習目的而編寫一個庫,並且遇到了一個奇怪的問題。
所以,
1.我有一個函數在主體(main.c)讀取LCD的DDRAM地址。
2.我將完全相同的功能移動到庫文件(HD44780.c)中。
3.我在主體中包含頭文件(HD44780.h)。
當我從主體調用函數時,我得到64的結果。正確。
當我從庫中調用相同的函數時,在之前的調用之後立即得到87的結果。錯誤。
也許它與庫文件和函數的可達性有關。我的圖書館分爲三個文件。不同文件中的相同函數返回不同的結果

  • HD44780.h(包括HD44780_Config.hHD44780.c和護頭裝置)
  • HD44780.c(不包括任何東西)
  • HD44780_Config.h (包括HD44780.h並且有頭衛兵)

有什麼想法?如果需要更多信息,請詢問。

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 

更新#1
我使用愛特梅爾Studio 6中編譯。默認優化級別(-O1)。
更新#2
我檢查了預處理器輸出,它們也是相同的。
更新#3
由於地址隨着每次讀取而增加/減少,因此會產生錯誤的結果。問題仍然存在。它與功能的位置有關,但我不知道它是什麼。
如果我打電話main.c的功能,它的工作原理。
如果我從HD44780.c調用它,它不能正常工作。
#更新#4
在另一個論壇的人解決了我的問題。你可以在下面查看我的答案。

+0

有(在HD44780.h)的函數原型? – LPs

+2

簡化您的代碼。把東西拿出來,直到你有一個最小的repro案例。 –

+0

你如何編譯和鏈接它? –

回答

1

問題是在F_CPU的定義。
它在HD44780.c文件中沒有定義。每個.c文件是一個獨立的編譯單元,它在編譯時與其餘的.c文件相鏈接。
我只在main.c中定義的F_CPU,所以_delay_usHD44780.c有錯F_CPU值。作爲解決方案,我在解決方案的makefile中聲明瞭F_CPU,以便它對所有文件均可見。 原因和解決方案是由於另一個論壇中的一個人,在那裏我拼命地問了同樣的問題。
謝謝大家的時間!

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

2

綜觀the controller manual 31頁:

讀取後,輸入模式自動地增加或減少1

這意味着,兩個連續的讀命令讀取的兩個不同的地址數據的地址。

EDIT

先前指定確定CG或DDRAM是否將被讀出。在進入該指令之前,必須執行CGRAM或DDRAM地址設置指令。如果未執行,則第一個 讀取的數據將無效。 當連續執行讀取指令時,通常從第二次讀取中讀取下一個地址數據 。當光標移位指令移動光標時(讀取DDRAM時),地址設置指令不需要在讀取指令 之前執行。光標移位指令的操作與設置的DDRAM地址指令相同。

重點煤礦

+0

你完全正確。在閱讀您的評論之後,我嘗試重新將光標重新放在相同的位置,以便再次重新閱讀。 **轉到**,**閱讀**,**轉到**,**閱讀**,我得到相同的虛假結果。我必須進一步測試它。 – ThymiosK

+0

@ThymiosK我編輯。 – LPs

+0

擁有自己應用的全日這個特殊的問題,弄得我暈頭轉向。我能夠理解你的觀點和報價,儘管看起來你可能已經找到了解決方案。你可以簡單地把它嗎? – ThymiosK

相關問題