|
LCD + ATmega8, Нет изображения на ЖКИ |
|
|
|
May 7 2011, 20:54
|
Участник

Группа: Участник
Сообщений: 32
Регистрация: 5-04-10
Пользователь №: 56 435

|
Цитата(Genadi Zawidowski @ May 7 2011, 20:42)  Вот странно... Человеку дали рабочий проект, под WinAWR. Вместо этого берётся драчёвый напильник и шлифуется плохопортируемый кусок кода, без изначально требуемой проверки готовности. Уж и комментарии на русском были. Просто скажите, что не устроило? Скажу честно, я начинающий программист на СИ, потому с Вашим кодом сложнее разобраться, и я иду по пути наименьшего сопротивления. Сначала разбираюсь с менее сложным кодом, просто код на CodeVision уже работает сразу после компиляции, и я решил , что с наименьшими затратами портирую его на WinAVR. А потом буду уже разбираться с Вашим кодом, так как в нем есть опрос ЖКИ на предмет готовности. А у Вас готовый проект, сложнее разобраться. Но все равно спасибо за помощь. Я просто хочу сделать отдельную библиотеек для ЖКИ, а потом просто подключать хидер в другие проекты.
|
|
|
|
|
May 8 2011, 00:31
|
Участник

Группа: Участник
Сообщений: 32
Регистрация: 5-04-10
Пользователь №: 56 435

|
Не могу понять где ошибка в коде, вроде изменил все, но изображение не выводится? CODE #include <avr/io.h> #include <util/delay.h> #include <avr/pgmspace.h>
// Задание выводимой строки текста. PROGMEM char static_text[] = "Hello, world!";
// Задание регистров порта подключения ЖКИ-модуля. #define LCD_PORT PORTD #define LCD_DDR DDRD // Задание номера бита порта для вывода сигнала Е. #define LCD_E PD3 // Задание номера бита порта для вывода сигнала RS. #define LCD_RS PD2 // Задание номера бита порта для вывода сигнала RW #define LCD_RW PD1 //Задание регистров порта для светодиода #define LED_PORT PORTC #define LED_DDR DDRC //Задание номера бита порта для светодиода #define LED PC0
// Команда очистки экрана. #define CLEAR_COMMAND 0b00000001
// Команда возврата курсора на начальную позицию. #define HOME_COMMAND 0b00000010
// Команда выбора направления сдвига курсора и экрана: // инкремент счетчика адреса, // без сдвига изображения. #define EMS_COMMAND 0b00000110
// Команда выбора отображения: // изображение включено, // курсор в виде подчерка выключен, // курсор в виде мерцающего знакоместа выключен. #define DISPLAY_COMMAND 0b00001100
// Команда задания сдвига курсора или экрана. //#define SHIFT_COMMAND 0b0001xx--
// Команда инициализации и задания режима работы индикатора // для 8-разрядного режима работы шины данных: // 4-хразрядная шина данных. // Здесь тетрады переставлены местами для корректной работы // подпрограммы записи команды в ЖКИ-модуль. #define INIT_8_COMMAND 0b00000010
// Команда инициализации и задания режима работы индикатора: // использование двухстрочного режима отображения информации, // матрица 5х8 точек, // 4-хразрядная шина данных. #define INIT_COMMAND 0b00101000
// Команда задания адреса в CGRAM. #define CGRAM_COMMAND 0b01000000
// Команда задания адреса в DDRAM. #define DDRAM_COMMAND 0b10000000
// Смещение первого знакоместа второй строки. #define SECOND_ROW 0x40
// Количество одновременно отображаемых символов на ЖКИ. #define TOTAL_CHARS 16
// Длительность программных задержек. #define INIT_DELAY 50 #define INIT_CONTROL_DELAY 50 #define WAIT_LINE_DELAY 1 #define WRITE_DATA_DELAY 50 #define WRITE_DATA_LONG_DELAY 2000
// Переставляет тетрады в байте. unsigned char swap(unsigned char data) { asm( "swap %0": "=r" (data): "0" (data) ); return data; }
// Определение задержки для формирования сигналов на линиях. #define lcd_wait_line() _delay_us(WAIT_LINE_DELAY)
// Записывает данные в ЖКИ-модуль. void _lcd_write_data(unsigned char data) { unsigned char lsn;
// Вывод данных на 4-хразрядную шину.
// Получение и вывод старшей тетрады. lsn = LCD_PORT & 0x0F; LCD_PORT = (data & 0xF0) | lsn;
// Установка стробирующего сигнала Е. LCD_PORT |=(1<<LCD_E); // Задержка сигнала на линии. lcd_wait_line(); // Снятие стробирующего сигнала Е. LCD_PORT &= ~(1<<LCD_E); // Задержка сигнала на линии. lcd_wait_line();
// Получение и вывод младшей тетрады. LCD_PORT = (swap(data) & 0xF0) | lsn;
// Установка стробирующего сигнала Е. LCD_PORT |= (1<<LCD_E); // Задержка сигнала на линии. lcd_wait_line(); // Снятие стробирующего сигнала Е. LCD_PORT &= ~(1<<LCD_E); // Задержка сигнала на линии. lcd_wait_line();
// Формирование задержки для ожидания выполнения команды ЖКИ-модулем. if (!LCD_RS && (CLEAR_COMMAND == data || HOME_COMMAND == data)) { _delay_us(WRITE_DATA_LONG_DELAY); } else { _delay_us(WRITE_DATA_DELAY); } }
// Записывает команду в регистр IR ЖКИ-модуля. void lcd_control(unsigned char control) { // Установка линии RS в низкое состояние - сигнал записи команды. LCD_PORT &= ~(1<<LCD_RS); // Задержка сигнала на линии. lcd_wait_line(); _lcd_write_data(control); }
// Записывает команду в регистр IR ЖКИ-модуля при инициализации. void lcd_init_control(unsigned char control) { lcd_control(control); // Задержка при инициализации должна быть больше. _delay_ms(INIT_CONTROL_DELAY); }
// Записывает символ в регистр DR ЖКИ-модуля. void lcd_putchar(unsigned char c) { // Установка линии RS в высокое состояние - сигнал записи данных. LCD_PORT |= (1<<LCD_RS); // Задержка сигнала на линии. lcd_wait_line(); _lcd_write_data©; }
// Инициализирует ЖКИ-модуль. void lcd_init(void) { // Порт подключения ЖКИ-модуля работает на вывод. LCD_DDR |= 0b11111100;
// Предварительная задержка. _delay_ms(INIT_DELAY); // Отправка команды инициализации для 8-разрядного режима работы шины // данных, переключение на 4-хразрядную шину. lcd_init_control(INIT_8_COMMAND); // Отправка команды инициализации уже для 4-хразрядного режима. lcd_init_control(INIT_COMMAND); // Повторная отправка команды инициализации. lcd_init_control(INIT_COMMAND); // Задание режима отображения. lcd_init_control(DISPLAY_COMMAND); // Очистка экрана. lcd_init_control(CLEAR_COMMAND); // Выбор направления сдвига курсора и экрана. lcd_init_control(EMS_COMMAND); }
// Записывает строку для отображения из памяти даных в ЖКИ-модуль. void lcd_puts(char *str) { char c; while (*str!='\0') { c = *str; lcd_putchar©; str++; } }
// Записывает строку для отображения из памяти программ в ЖКИ-модуль. void lcd_putsf(PROGMEM char *str) { char c; while (pgm_read_byte(str)!='\0') { c = pgm_read_byte(str); lcd_putchar©; str++; } }
int main(void) { // Инициализация ЖКИ-модуля. lcd_init();
// Вывод заданного текста в первой строке с первого знакоместа. lcd_putsf(static_text);
// Переключение на четвёртое знакоместо второй строки. lcd_control(DDRAM_COMMAND + SECOND_ROW + 3);
// Вывод заданного текста во второй строке с четвёртого знакоместа. lcd_putsf(static_text);
//Конфигурираем порт для мигания светодиодом LED_DDR |= 0b11111111;
for (;;) { //Мигаем светодиодом для проверки работоспособности программы LED_PORT |= (1<<LED); _delay_ms(1000); //задержка 1 секунда LED_PORT &= ~(1<<LED); _delay_ms(1000); //задержка 1 секунда } return 0; }
|
|
|
|
|
May 9 2011, 08:35
|
Участник

Группа: Участник
Сообщений: 32
Регистрация: 5-04-10
Пользователь №: 56 435

|
Что-то все умерли? Все молчат, программу запустил с выводом символа из памяти данных, т.е. из ОЗУ. При выводе строки из памяти программ какой-то трабл. Не могли бы посмотреть по коду. Нужно ли вызывать функцию pgm_read_byte или pgm_read-word? Заранее благодарен за ответ
|
|
|
|
|
May 9 2011, 09:04
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Так праздник у цивилизованных людей. QUOTE (Melandr @ May 9 2011, 11:35)  программу запустил с выводом символа из памяти данных, т.е. из ОЗУ. При выводе строки из памяти программ какой-то трабл. Не могли бы посмотреть по коду. Нужно ли вызывать функцию pgm_read_byte или pgm_read-word? Нормально все в вашем исходнике. Символ занимает в памяти байт, вы правильно используете pgm_read_byte(). Должно работать. Прикрепите к сообщению архив с проектом (и с выходными файлами), возможно проблема не в исходнике. Вот моя функция вывода, как видите - практически идентична вашей: CODE template <uint_fast8_t size_x, uint_fast8_t size_y> void lcd_t<size_x, size_y>::put_P(PGM_P pString) { char c; while( (c = pgm_read_byte(pString++)) ) { put(c); } }
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
May 9 2011, 10:17
|
Участник

Группа: Участник
Сообщений: 32
Регистрация: 5-04-10
Пользователь №: 56 435

|
Наконец, добил я код для WinAVR. Вылаживаю его может кому сгодится. CODE #include <avr/io.h> #include <util/delay.h> #include <avr/pgmspace.h>
// Задание выводимой строки текста. char static_text[] PROGMEM = "Hello, world!";
// Задание регистров порта подключения ЖКИ-модуля. #define LCD_PORT PORTD #define LCD_DDR DDRD // Задание номера бита порта для вывода сигнала Е. #define LCD_E PD3 // Задание номера бита порта для вывода сигнала RS. #define LCD_RS PD2 // Задание номера бита порта для вывода сигнала RW #define LCD_RW PD1 //Задание регистров порта для светодиода #define LED_PORT PORTC #define LED_DDR DDRC //Задание номера бита порта для светодиода #define LED PC0
// Команда очистки экрана. #define CLEAR_COMMAND 0b00000001
// Команда возврата курсора на начальную позицию. #define HOME_COMMAND 0b00000010
// Команда выбора направления сдвига курсора и экрана: // инкремент счетчика адреса, // без сдвига изображения. #define EMS_COMMAND 0b00000110
// Команда выбора отображения: // изображение включено, // курсор в виде подчерка выключен, // курсор в виде мерцающего знакоместа выключен. #define DISPLAY_COMMAND 0b00001100
// Команда задания сдвига курсора или экрана. //#define SHIFT_COMMAND 0b0001xx--
// Команда инициализации и задания режима работы индикатора // для 8-разрядного режима работы шины данных: // 4-хразрядная шина данных. // Здесь тетрады переставлены местами для корректной работы // подпрограммы записи команды в ЖКИ-модуль. #define INIT_8_COMMAND 0b00000010
// Команда инициализации и задания режима работы индикатора: // использование двухстрочного режима отображения информации, // матрица 5х8 точек, // 4-хразрядная шина данных. #define INIT_COMMAND 0b00101000
// Команда задания адреса в CGRAM. #define CGRAM_COMMAND 0b01000000
// Команда задания адреса в DDRAM. #define DDRAM_COMMAND 0b10000000
// Смещение первого знакоместа второй строки. #define SECOND_ROW 0x40
// Количество одновременно отображаемых символов на ЖКИ. #define TOTAL_CHARS 16
// Длительность программных задержек. #define INIT_DELAY 50 #define INIT_CONTROL_DELAY 50 #define WAIT_LINE_DELAY 1 #define WRITE_DATA_DELAY 50 #define WRITE_DATA_LONG_DELAY 2000
// Переставляет тетрады в байте. unsigned char swap(unsigned char data) { asm( "swap %0": "=r" (data): "0" (data) ); return data; }
// Определение задержки для формирования сигналов на линиях. #define lcd_wait_line() _delay_us(WAIT_LINE_DELAY)
// Записывает данные в ЖКИ-модуль. void _lcd_write_data(unsigned char data) { unsigned char lsn;
// Вывод данных на 4-хразрядную шину.
// Получение и вывод старшей тетрады. lsn = LCD_PORT & 0x0F; LCD_PORT = (data & 0xF0) | lsn;
// Установка стробирующего сигнала Е. LCD_PORT |=(1<<LCD_E); // Задержка сигнала на линии. lcd_wait_line(); // Снятие стробирующего сигнала Е. LCD_PORT &= ~(1<<LCD_E); // Задержка сигнала на линии. lcd_wait_line();
// Получение и вывод младшей тетрады. LCD_PORT = (swap(data) & 0xF0) | lsn;
// Установка стробирующего сигнала Е. LCD_PORT |= (1<<LCD_E); // Задержка сигнала на линии. lcd_wait_line(); // Снятие стробирующего сигнала Е. LCD_PORT &= ~(1<<LCD_E); // Задержка сигнала на линии. lcd_wait_line();
// Формирование задержки для ожидания выполнения команды ЖКИ-модулем. if (!LCD_RS && (CLEAR_COMMAND == data || HOME_COMMAND == data)) { _delay_us(WRITE_DATA_LONG_DELAY); } else { _delay_us(WRITE_DATA_DELAY); } }
// Записывает команду в регистр IR ЖКИ-модуля. void lcd_control(unsigned char control) { // Установка линии RS в низкое состояние - сигнал записи команды. LCD_PORT &= ~(1<<LCD_RS); // Задержка сигнала на линии. lcd_wait_line(); _lcd_write_data(control); }
// Записывает команду в регистр IR ЖКИ-модуля при инициализации. void lcd_init_control(unsigned char control) { lcd_control(control); // Задержка при инициализации должна быть больше. _delay_ms(INIT_CONTROL_DELAY); }
// Записывает символ в регистр DR ЖКИ-модуля. void lcd_putchar(unsigned char c) { // Установка линии RS в высокое состояние - сигнал записи данных. LCD_PORT |= (1<<LCD_RS); // Задержка сигнала на линии. lcd_wait_line(); _lcd_write_data©; }
// Инициализирует ЖКИ-модуль. void lcd_init(void) { // Порт подключения ЖКИ-модуля работает на вывод. LCD_DDR |= 0b11111110;
// Предварительная задержка. _delay_ms(INIT_DELAY); // Отправка команды инициализации для 8-разрядного режима работы шины // данных, переключение на 4-хразрядную шину. lcd_init_control(INIT_8_COMMAND); // Отправка команды инициализации уже для 4-хразрядного режима. lcd_init_control(INIT_COMMAND); // Повторная отправка команды инициализации. lcd_init_control(INIT_COMMAND); // Задание режима отображения. lcd_init_control(DISPLAY_COMMAND); // Очистка экрана. lcd_init_control(CLEAR_COMMAND); // Выбор направления сдвига курсора и экрана. lcd_init_control(EMS_COMMAND); }
// Записывает строку для отображения из памяти даных в ЖКИ-модуль. void lcd_puts(char *str) { char c; while (*str!='\0') { c = *str; lcd_putchar©; str++; } }
// Записывает строку для отображения из памяти программ в ЖКИ-модуль. void lcd_putsf(char *str) { char c; while (pgm_read_byte(str)!='\0') { c = pgm_read_byte(str); lcd_putchar©; str++; } }
int main(void) { LCD_PORT &= ~(1<<LCD_RW); // Инициализация ЖКИ-модуля. lcd_init();
// Вывод заданного текста в первой строке с первого знакоместа. lcd_putsf(static_text);
// Переключение на четвёртое знакоместо второй строки. lcd_control(DDRAM_COMMAND + SECOND_ROW + 3);
// Вывод заданного текста во второй строке с четвёртого знакоместа. lcd_putsf(static_text);
//Конфигурираем порт для мигания светодиодом LED_DDR |= 0b11111111;
for (;;) { //Мигаем светодиодом для проверки работоспособности программы LED_PORT |= (1<<LED); _delay_ms(1000); //задержка 1 секунда LED_PORT &= ~(1<<LED); _delay_ms(1000); //задержка 1 секунда } return 0; }
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|