2016-11-15 7 views
0

В настоящее время я пишу библиотеку для обучения, и у меня возникла странная проблема.
Итак,
1. У меня есть функция в основном корпусе (main.c), которая считывает адрес DDRAM на ЖК-дисплее.
2. Я перемещаю ту же самую функцию в файл библиотеки (HD44780.c).
3. Я включаю заголовочный файл (HD44780.h) в основной корпус.
Когда я вызываю функцию из основного тела, я получаю результат 64. Исправьте.
Когда я вызываю ту же функцию из библиотеки, сразу после предыдущего вызова, я получаю результат 87. False.
Возможно, что-то связано с файлами библиотеки и достижимостью функций. Моя библиотека разделена на три файла.Такая же функция в разных файлах возвращает разные результаты

  • 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 

Update # 1
Я использую Atmel Studio 6 для компиляции. Уровень оптимизации по умолчанию (-O1).
Обновление # 2
Я проверил выходы препроцессора, и они также идентичны.
Обновление № 3
Концевые чтения имеют ложный результат из-за увеличения или уменьшения адреса при каждом чтении. Однако проблема все еще сохраняется. Это связано с расположением функции, но я не знаю, что это такое.
Если я вызываю функцию в main.c, она работает.
Если я назову его HD44780.c, он не работает должным образом.
# Дополнение # 4
Парень в другом форуме решил мою проблему. Вы можете проверить мой ответ ниже.

+0

Есть (в HD44780.h) прототип функции? – LPs

+2

Упростите свой код. Возьмите материал, пока у вас не будет минимального требования к воспроизведению. –

+0

как вы компилируете и связываете все это? –

ответ

1

Проблема заключалась в определении F_CPU.
Не определено в файле HD44780.c. Каждый файл .c является автономным модулем компиляции, связанным с остальными .c файлов во время компиляции.
Я определил F_CPU только в main.c, поэтому _delay_us в HD44780.c было неправильно F_CPU значение. В качестве решения я объявил F_CPU в make-файле решения, чтобы он отображался для ВСЕХ файлов. Причина и ее решение связаны с тем, что парень на другом форуме, где я задал один и тот же вопрос отчаянно.
Спасибо вам всем за ваше время!

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

2

Глядя на the controller manual на странице 31:

После чтения, режим ввода автоматически увеличивает или уменьшает адрес на 1

Это означает, что две последовательные команды чтения чтения два различных адресных данных ,

РЕДАКТИРОВАТЬ

Предыдущее обозначение определяет, является ли CG или DDRAM для чтения. Перед тем, как ввести эту команду, необходимо выполнить команду , либо Инструкция по настройке адреса CGRAM или DDRAM. Если не выполнены, первые считанные данные будут недействительными. При последовательном выполнении инструкций чтения следующие адресные данные обычно считываются с со второго чтения. Инструкции по набору адресов не должны выполняться непосредственно перед этой инструкцией чтения при перемещении курсора с помощью команды перемещения курсора (при чтении DDRAM). Операция команды сдвига курсора такая же, как и заданная команда адреса DDRAM.

Упор шахта

+0

Вы частично правы. Прочитав ваш комментарий, я попытался переместить курсор снова в ту же позицию, чтобы снова прочитать его. ** Перейти к **, ** Читать **, ** Перейти к **, ** Читать **, и я получаю одинаковые ложные результаты. Я должен проверить это дальше. – ThymiosK

+0

@ThymiosK Я отредактировал. – LPs

+0

Я сам применил весь день к этой конкретной проблеме, и у меня закружилась голова. Я не могу понять ни вашу точку, ни цитату, хотя, похоже, вы нашли решение. Можете ли вы просто выразить это? – ThymiosK