реклама на сайте
подробности

 
 
> вопрос по программке, под WinAVR
skilful
сообщение Aug 5 2007, 19:04
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 186
Регистрация: 23-04-06
Из: Сочи
Пользователь №: 16 411



Доброго времени суток. Вот решил перейти с асма на Си. Взялся за статьи Рюмика. Программка для управления 2 строчным ЖК с hd44780 посредством 8-битной ШД. Хочу пустить "бегущую" букву во второй строчке. Для этого имеется такой коротенький исходник:

#include <avr/io.h>
#define RS PC2
#define E PC0

#define TIME 2

//_______________________________________________
void pause(unsigned int a)
{
unsigned int count;
for (count = a; count>0; count--);
}
//_______________________________________________
//запись команды
void lcd_com(unsigned char p)
{
PORTC &= ~_BV(RS);
PORTC |= _BV(E);

PORTD = p;
pause(TIME);

PORTC &= ~_BV(E);
pause(5*TIME);
}
//_______________________________________________
//запись данных
void lcd_data(unsigned char p)
{
PORTC |= _BV(RS) | _BV(E);
PORTD = p;
pause(TIME);
PORTC &= ~_BV(E);
pause(5*TIME);
}
//_______________________________________________
//инициализация
void lcd_init(void)
{
lcd_com(0x08);
lcd_com(0x38);
pause(1000*TIME); //4.1 ms
lcd_com(0x38);
pause(30*TIME); //100us
lcd_com(0x38);
lcd_com(0x38);


lcd_com(0x01);
pause(1000*TIME);

lcd_com(0x0C);
lcd_com(0x06);
}
//_______________________________________________
//основная часть программы
unsigned int i;

int main(void)
{


PORTB = DDRD = 0xFF; //
PORTC = 0xF8; DDRC = 0x07;
lcd_init();



while(1)
{
for(i=0xC0;i<=0xD4;i++)
{

lcd_com(i);
lcd_data('o');


lcd_com(i-1);
lcd_data(' ');

pause(31000*TIME);

}

}
return (0) ;

}
_______________________________________________
_______________________________________________
_______________________________________________
Вот вопросик состоит в том, что при этих положениях строк:
lcd_com(i);
lcd_data('o');


lcd_com(i-1);
lcd_data(' ');
символ бежит со второго разряда 2-ой строчки


Если их поменять местами:

lcd_com(i-1);
lcd_data(' ');

lcd_com(i);
lcd_data('o');

то тогда все нормально.
Не пойму, что не так? Сижу туплю - перегрелся что ли smile.gif . Заранее спасибо.

Сообщение отредактировал skilful - Aug 5 2007, 19:06
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 5)
GDI
сообщение Aug 6 2007, 10:57
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 235
Регистрация: 14-05-05
Из: Санкт-Петербург
Пользователь №: 5 008



А что за команда получится 0xBF? Которая получится при первом проходе основного цикла при i=0xC0 при выполнении lcd_com(i-1);


--------------------
http://www.embedders.org Блоги разработчиков электроники.
Go to the top of the page
 
+Quote Post
skilful
сообщение Aug 6 2007, 12:09
Сообщение #3


Частый гость
**

Группа: Свой
Сообщений: 186
Регистрация: 23-04-06
Из: Сочи
Пользователь №: 16 411



Получится установка адреса на не отображаемую ячейку памяти.
Go to the top of the page
 
+Quote Post
GDI
сообщение Aug 6 2007, 12:56
Сообщение #4


Профессионал
*****

Группа: Свой
Сообщений: 1 235
Регистрация: 14-05-05
Из: Санкт-Петербург
Пользователь №: 5 008



Если предположить что контроллер дисплея ставит адрес на первую отображаемую ячейку памяти , то , возможно происходит следующее: дисплей печатает символ в первой позиции, затем тут же затирает его пробелом(который ставит в первую отображаемую ячейку), а второй проход цикла ставит все на свои места, символ ставит на 2ю позицию и затирает 1ю позицию. При изменении порядка функций затирания символа в 1й позиции не происходит
мне кажется стоит сделать проверку на i==0xC0, например так:
Код
while(1)
{
for(i=0xC0;i<=0xD4;i++)
{

lcd_com(i);
lcd_data('o');

if (i != 0xC0){
   lcd_com(i-1);
   lcd_data(' ');
}

pause(31000*TIME);

}

}
а не отдавать обработку несуществующего адреса на откуп контроллеру конкретной модели дисплея, чем потом удивляться, почему программа не работает так как того хотелось программисту.


--------------------
http://www.embedders.org Блоги разработчиков электроники.
Go to the top of the page
 
+Quote Post
skilful
сообщение Aug 6 2007, 17:16
Сообщение #5


Частый гость
**

Группа: Свой
Сообщений: 186
Регистрация: 23-04-06
Из: Сочи
Пользователь №: 16 411



спасибо GDI за вникание smile.gif будем считать, что ты все правильно сказал smile.gif. Спс еще раз
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Aug 15 2007, 12:57
Сообщение #6


Гуру
******

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



Цитата(GDI @ Aug 6 2007, 15:56) *
мне кажется стоит сделать проверку на i==0xC0, например так:
Не думаю, что это будет оптимальным решением, ибо проверка нужна только один раз, а выполняться будет на каждом проходе цикла. А вот если изменить алгоритм, то проверка будет не нужна вообще:
Код
while(1)
{
    for(i=0xC0;i<=0xD4;i++)
    {

        lcd_com(i);
        lcd_data('o');
        pause(31000*TIME);
        lcd_com(i);
        lcd_data(' ');
    }
}

Код
while(1)
{
    lcd_com(0xC0);
    lcd_data('o');
    for(i=0xC0;i<=0xD4;i++)
    {
        pause(31000*TIME);
        lcd_com(i);
        lcd_data(' ');
        lcd_data('o');
    }
}

Цитата(GDI @ Aug 6 2007, 15:56) *
а не отдавать обработку несуществующего адреса на откуп контроллеру конкретной модели дисплея, чем потом удивляться, почему программа не работает так как того хотелось программисту.
Согласен на все 100%


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 19:54
Рейтинг@Mail.ru


Страница сгенерированна за 0.01453 секунд с 7
ELECTRONIX ©2004-2016