不同文件中的相同功能 returns 不同的结果

Same function within different files returns different results

我目前正在编写一个用于学习目的的库,但我 运行 遇到了一个奇怪的问题。
所以,
1. 我在主体(main.c)中有一个读取LCD的DDRAM地址的函数。
2. 我将完全相同的函数移动到库文件中 (HD44780.c).
3.我在正文中包含头文件(HD44780.h)。
当我从主体调用函数时,得到的结果是 64。正确。
当我从库中调用相同的函数时,在上一次调用之后立即得到结果 87.False.
也许它与库文件和函数的可达性有关。我的图书馆分为三个文件。

有什么想法吗?如果需要更多信息,请询问。

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
我正在使用 Atmel Studio 6 进行编译。默认优化级别 (-O1)。
更新#2
我检查了预处理器输出,它们也是相同的。
更新#3
由于每次读数的地址为 increased/decreased,因此后续读数结果错误。问题仍然存在。跟函数的位置有关,不知道是什么
如果我调用 main.c 中的函数,它会起作用。
如果我从 HD44780.c 调用它,它不能正常工作。
#更新#4
另一个论坛的人解决了我的问题。您可以在下面查看我的答案。

查看第 31 页 the controller manual

After a read, the entry mode automatically increases or decreases the address by 1

也就是说连续两个读取命令读取了两个不同地址的数据。

编辑

The previous designation determines whether CG or DDRAM is to be read. Before entering this read instruction, either CGRAM or DDRAM address set instruction must be executed. If not executed, the first read data will be invalid. When serially executing read instructions, the next address data is normally read from the second read. The address set instructions need not be executed just before this read instruction when shifting the cursor by the cursor shift instruction (when reading out DDRAM). The operation of the cursor shift instruction is the same as the set DDRAM address instruction.

强调我的

问题出在F_CPU的定义上。
它未在 HD44780.c 文件中定义。每个 .c 文件都是一个独立的编译单元,在编译时与其余 .c 文件链接。
我只在main.c中定义了F_CPU,所以_delay_us[= HD44780.c 中的 26=] 有错误的 F_CPU 值。作为解决方案,我在解决方案的 makefile 中声明了 F_CPU,因此它对所有文件都是可见的。 原因和解决方法是另一个论坛的一个人,我在那里拼命问过同样的问题。
谢谢大家的宝贵时间!

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