我目前正在编写一个用于学习目的的图书馆,但我遇到了一个奇怪的问题
所以,
1.我在主体(main.c)中有一个功能,它读取LCD的DDRAM地址
2.我将完全相同的功能移到库文件(HD44780.c)中
3.我在主体中包含头文件(HD44780.h)
当我从主体调用该函数时,我得到64的结果。正确。
当我从库中调用相同的函数时,在上一次调用之后,我得到87的结果。错误。
也许它与库文件和函数的可达性有关。我的库分为三个文件。
有什么想法吗?如果需要更多信息,请询问。
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
另一个论坛的人解决了我的问题。你可以在下面查看我的答案。
答案 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 ,因此它对所有文件都可见。
原因及其解决方案是由于另一个论坛上的人,我拼命地问了同样的问题
谢谢大家的时间!