不同文件中的相同功能会返回不同的结果

时间:2016-11-15 13:05:23

标签: c embedded avr avr-gcc atmelstudio

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

  • HD44780.h (包括 HD44780_Config.h HD44780.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
我正在使用Atmel Studio 6进行编译。默认优化级别(-O1)。
 更新#2
我检查了预处理器输出,它们也是相同的 更新#3
由于每次读取时地址增加/减少,因此对比读数具有错误结果。问题仍然存在。它与功能的位置有关,但我不知道它是什么 如果我在 main.c 中调用该函数,它就会起作用 如果我从 HD44780.c 调用它,它将无法正常工作 #Update#4
另一个论坛的人解决了我的问题。你可以在下面查看我的答案。

2 个答案:

答案 0 :(得分:2)

在第31页查看the controller manual

  

读取后,输入模式会自动将地址增加或减少1

这意味着两个连续的读命令读取两个不同的地址数据。

修改

  

先前的指定确定是否要读取CG或DDRAM。在进入此阅读之前   指令, CGRAM或DDRAM地址设置指令必须执行。如果没有执行,则第一个   读取数据将无效。 当串行执行读指令时,通常会读取下一个地址数据   从第二次读取开始。地址集指令不需要在此读指令之前执行   通过光标移位指令移动光标时(读出DDRAM时)。的运作   光标移位指令与设置的DDRAM地址指令相同。

强调我的

答案 1 :(得分:1)

问题在于 F_CPU 的定义 它未在 HD44780.c 文件中定义。每个 .c 文件都是一个独立的编译单元,在编译时与其余的 .c 文件链接。
我仅在 main.c 中定义了 F_CPU ,因此 HD44780.c 中的 _delay_us 错误 F_CPU 值。作为解决方案,我在解决方案的makefile中声明了 F_CPU ,因此它对所有文件都可见。 原因及其解决方案是由于另一个论坛上的人,我拼命地问了同样的问题 谢谢大家的时间!

  

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