Перейти к содержанию

Помогите! Atmega16 И Lcd !


Рекомендуемые сообщения

Но имейте ввиду - данный код написан за 10 минут, никакой оптимизации тут нет, поэтому возможны подтормаживания. Но оптимизацию не делал намеренно, ибо так просто на пальцах обьяснить небыло бы возможности. Я лишь обьяснил Вам сам алгоритм.

Ссылка на комментарий
Поделиться на другие сайты

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

  • Ответов 100
  • Создана
  • Последний ответ

Топ авторов темы

Топ авторов темы

Изображения в теме

... я конечно не хочу показаться тупицей ))))))) .. .. сидел думал над етой функцией .... и пришол к выводу.., что :

1 символ ( со знакоместом 0,0) записывается в (0,1);

символ со знакоместом (0,1) записывается в ( 0,0)..., т.е. получается инверсия какаято )))) белеберда )))).. по плану должен записыватьса с (0,1) в (0,2) т.е. 1й символ на место второго символа, а второй символ на место третьего :) .... и в конче концов мы получаем бегущуюстрочку двигающуюся в таком направлении... ->->->->->->-> ...:) НО нужно в обратном направлении )))):) <-<-<-<-<-<-<- для читательности.... :)....

и ещё!.. код выдает ошибку в CVAVR в строке

p1=lcd_read_byte((0xС0)+k);

пишет :" missing ')' "

P.S. :) :) :) Если я жжостко туплю то сильно не орите с меня )))))))...

Ссылка на комментарий
Поделиться на другие сайты

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

зачем скобки у 0xC0. просто уберите их. я выдавал текст прям с cvavr. где все откомпилил и проверил в протеусе.

Инверсии никакой нет. Смысл функции в сдвиге на одну позицу влево, вот смотрите:

123456789

теперь чтобы было

234567891

нужно что сделать? именно: перемещать единицу до конца, а остальное сдвигать. именно так и работает функция. нарисуйте на листочке, думаю станет понятно. а ваших описаний "со знакоместом (0,0)" я не вижу смысла, так как мы работаем с условно одной строкой, тогда как в 1 строке сразу 2 знакоместа? ;)

Ссылка на комментарий
Поделиться на другие сайты

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

p1=lcd_read_byte(0xС0+k);

.. да и вот так тоже почемуто ошибку выдает... да ну ладно это не важно..... Важно то што я почемуто не погу никак разобраться в том куске кода... ОБЬЯСНИЕ ПЛЗ ЧТО ТАКОЕ 0x80,0x81 и 0x80+k,0x81+k ...

Изменено пользователем Lexey
Ссылка на комментарий
Поделиться на другие сайты

Вот пример в паинте ;)

Прикрепите польность весь исходник. проблема не в этой строчке я думаю.

адрес 0х80 - адрес 1 знакоместа в 1 строке, 0х81 - второго и т.д.

адрес 0хC0 - адрес 1 знакоместа во второй строке. и т.д.

post-108742-1267279897,27_thumb.gif

Ссылка на комментарий
Поделиться на другие сайты

.. так )) вот теперь понял!.. разобрался с адресами.... НО всеравно ))))))) чёто уже весь жень сижу над тем куском кода и у меня уже плавятся мозги ))))).... я понимаю это работает так как вот на маем рис!

или вот примерчик: ( ток не смеяться :) )

ЛЯГУШКА

ЯЛГУШКА

ЯГЛУШКА

ЯГУЛШКА

ЯГУШЛКА

ЯГУШКЛА

ЯГУШКАЛ

:) вот так... вот так я считаю работает тот код )))...

п.с.... Это все возможности моего мозгка :)

post-109440-1267291970,8_thumb.jpg

Изменено пользователем Lexey
Ссылка на комментарий
Поделиться на другие сайты

хм)) ну вопросов то нет ))) но ето никаккаяже не бегущая строка ))))... я так понял это примитивный пример.... :)... щас папробую сваё какоето чудо сочинить.... пожже отпишу !

Ссылка на комментарий
Поделиться на другие сайты

void sdvig(void) 
{
char k,p1,p2;
k=0;
while (k=15) {
p1=lcd_read_byte(0x8F-k);				
lcd_write_byte(0x8D-k,p1);			
k++;
};
};

ну вот впринципе цикл который сдвигает 1 буковку с 15позиции на 14->13->12->11..0 и все!...

а чтобы сдвигать одновременно 16 символом ( вданном случае у нас такова строка) нужно вводить 16 переменных.., т.е p1,p2,p3,p4,p5,p6,p7..... ТАК Я ПОНИМАЮ ? :)

p.s. Йа Мегоацкий программер ))))))))) :)

ну почему бегущей строки то нет? поставь эту ф-цию в бесконечный цикл и у тебя бегущая строка.

.. хм... я думаю там если бесконечный цикл поставить.., то 2й цикл вернет все по прежнему ( т.е.в слово ЛЯГУШКА)... 3й-ЯГУШКАЛ ... и т.д.... :) вродеб так )) ну по крайней мере я так думаю :) :)

Изменено пользователем Lexey
Ссылка на комментарий
Поделиться на другие сайты

блин. ну зачем так тупить. если после первого входа в функцию на экране таже

ЛЯГУШКА то на выходе будет ЯГУШКАЛ

при втором вызове функции на экране будет ГУШКАЛЯ.

неужели это так сложно?

вообщем напиши прогу, мастер кодом для своей меги. и вставь мои функции и в основной цикл функции сдвига и проверь: либо в железе, либо в протеусе.

Ссылка на комментарий
Поделиться на другие сайты

Сегодня попробывал всё реализовать на железе и увидел что все работает..., немного модернизировал прогу:

include <mega16.h>
#include <delay.h>
#include <stdio.h>
// Alphanumeric LCD Module functions
#asm
  .equ __lcd_port=0x15 ;PORTC
#endasm
#include <lcd.h>
#include <string.h>
// Declare your global variables here

void vivod(void)
{
lcd_clear();
lcd_gotoxy(0,0); 
#pragma rl+
lcd_putsf("пропорпорпор"); 

lcd_gotoxy(0,1);
lcd_putsf("опропроепрп"); 
#pragma rl-
}; 
void sdvig(void) 
{
char k,g1,g2;
k=0;
while (k<15) {
g1=lcd_read_byte(0x80+k);
g2=lcd_read_byte(0x81+k);
lcd_write_byte(0x81+k,g1);
lcd_write_byte(0x80+k,g2); 
k++;
};
}; 
void sdvig2(void) 
{
char y,p1,p2;
y=0;
while (y<15) {
p1=lcd_read_byte(0xC0+y);
p2=lcd_read_byte(0xC1+y);
lcd_write_byte(0xC1+y,p1);
lcd_write_byte(0xC0+y,p2); 
y++;
};
}; 
void main(void)
{
lcd_init(16);
vivod();
while (1)
     {
sdvig();  
sdvig2();
delay_ms(400); 
     };  
     };



и получилось 2 бегущие строчки!!! :)

это мы разобрали строку не более чем 16 символов!

теперь меня интересует как выводить строки больших размеров,массивами! :)

Помогите мне в этом разобраться :)

Изменено пользователем Lexey
Ссылка на комментарий
Поделиться на другие сайты

Невидержал, очень захотелось помочь :) Поставил CV и наклепал примерчик :ph34r:

За код сильно не пинать, первый раз под АВР пишу прогу :rolleyes:

/*****************************************************
This program was produced by the
CodeWizardAVR V1.25.8 Professional
Automatic Program Generator
© Copyright 1998-2007 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com

Project : 
Version : 
Date    : 02.03.2010
Author  : Alex                            
Company : home                            
Comments: 


Chip type           : ATmega16
Program type        : Application
Clock frequency     : 4,000000 MHz
Memory model        : Small
External SRAM size  : 0
Data Stack size     : 256
*****************************************************/

#include <mega16.h>
#include <stdio.h>
#include <delay.h>


// Alphanumeric LCD Module functions
#asm
  .equ __lcd_port=0x15 ;PORTC
#endasm
#include <lcd.h>


#pragma rl+
unsigned char arr[] = "                Компьютерно-интегрированные технологические процессы и производства!                 " ;
#pragma rl-


void main(void)
{
unsigned int i=0 , a=0;



// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;

// LCD module initialization
lcd_init(16);

lcd_clear();  

lcd_gotoxy(0,0);  
//lcd_puts(arr);  



for(i=0; i < sizeof(arr)-16 ; i++)
{
       for(a=0; a<15 ; a++)
       {
               lcd_gotoxy(a,0); 
               lcd_putchar(arr[i+a]);
       }

delay_ms(100); 
}


while (1)
     {
     };
}

В архиве проект CV с файлом протеуса.

lcd.rar

Ссылка на комментарий
Поделиться на другие сайты

Cпасибо большое! а вы бы не могли подсказать как выводить сразу 2 бег\строки.., с помощью вот этого вашего метода (массивом) ..., просто именно В ЭТОМ У МЕНЯ И ПРОБЛЕМА!!.. 1 стоку могу вывести а сразу 2шт нет ..:) :)

Изменено пользователем Lexey
Ссылка на комментарий
Поделиться на другие сайты

Немного не понятно. Вы хотите сами научиться програмить, или что-бы Вам тупо написали эту бег. строку и всё ?

Вы хотя-бы попытались разобраться немного. :)

Зачем Вам это всё ? Колитесь ! :D

Ссылка на комментарий
Поделиться на другие сайты

#include <mega16.h>
#include <stdio.h>
#include <delay.h>

#asm
  .equ __lcd_port=0x15 ;PORTC
#endasm
#include <lcd.h>


#pragma rl+
unsigned char arr_1[] = "                Компьютерно-интегрированные технологические процессы и производства!                  " ;
unsigned char arr_2[] = "                Абра-кадабра трам парарам пам-пам пам-пам.......                 " ;
#pragma rl-


void main(void)
{
unsigned int i=0 , a=0;
bit fl =0;

unsigned int size_1, size_2;
unsigned int s_tmp_1, s_tmp_2;

ACSR=0x80;
SFIOR=0x00;

lcd_init(16);
lcd_clear();  

size_1 = sizeof(arr_1)-17;      // Вычесляем длину 1-ой строки
size_2 = sizeof(arr_2)-17;      // Вычесляем длину 2-ой строки

fl=0;
while(!fl)      // Ждём флага окончания вывода строк
{

//*****************
       if(s_tmp_1 < (size_1) )   // Если 1-ая строка не закончилась
       {
       s_tmp_1++;

       for(i=0;i<16;i++)        // Выводим 16 следующих символов
               {
                lcd_gotoxy(i,0); 
                lcd_putchar(arr_1[s_tmp_1+i]);
               }
       }
//******************
       if(s_tmp_2 < (size_2) )     // Если 2-ая строка не закончилась
       {
       s_tmp_2++;

       for(i=0;i<16;i++)           // Выводим 16 следующих символов
               {
                lcd_gotoxy(i,1); 
                lcd_putchar(arr_2[s_tmp_2+i]);
               }
       }

//***************** 
fl = (s_tmp_1==size_1) && (s_tmp_2==size_2);    // Ждём окончания вывода обеих строк. 
                                                //Если закончили устанавливаем флаг для выхода из цикла  


delay_ms(100);    // Пауза
}

delay_ms(1000); 
lcd_clear();  
lcd_gotoxy(0,0); 

#pragma rl+
lcd_putsf ("Ура !!!!!!!!!!");
#pragma rl-


while (1);
}

:P:D

lcd.rar

Ссылка на комментарий
Поделиться на другие сайты

Alex отлично, алгорит правильный.

На мой взгляд топикстартеру еще рано постигать азы программирования на уровне того же мк. Самое время понять ему аглоритмы. Как раньше в школе учили: поднять перо, передвинуть влево, опустить перо... и т.д. Хоть и считалось оно в свое в ремя нерациональным на фоне тогда еще технологий, но на деле выходит правильным. Ибо азы программирования постигаются с элементарного. А тут человеку даешь код из 4х строк, а потом обьясняешь в 10 сообщениях как этот код еще и работает...

Ссылка на комментарий
Поделиться на другие сайты

Спасибо за помощь!

Немного не понятно. Вы хотите сами научиться програмить, или что-бы Вам тупо написали эту бег. строку и всё ?

Вы хотя-бы попытались разобраться немного.

Зачем Вам это всё ? Колитесь !

я пытался разбираться сам.. но ничего не получается... посмотрите для сравнения выше мои посты... там на железе все правильно работает а понять я никак и не смог этот алгорилм.... а точнее:

void sdvig(void) 
{
char k,p1,p2;
k=0;
while (k<15) {
p1=lcd_read_byte(0x80+k);
p2=lcd_read_byte(0x81+k);
lcd_write_byte(0x81+k,p1);
lcd_write_byte(0x80+k,p2); 
k++;
};
};

.... я пробую.., пытаюсь разобратьса сам...

еслибы мне это было бы не надо то я бы воопще тут не сидел и не задавал вам глупые вапросы...

этот проэкт (устройство)- курсовая работа!... просто подключить ее и тупо вывести строку на ЖК ( не бегущую).., это я уже сделал примерно месяц назад....

а щас просто разбераюсь в азах программирования МК с вашей помощью на примере "бугущей строки"!!!

p.s.

... что-бы Вам тупо написали эту бег. строку и всё ?

Вы хотя-бы попытались разобраться немного.

А тут человеку даешь код из 4х строк, а потом обьясняешь в 10 сообщениях как этот код еще и работает...

если вам трудно мне отвечать на мои вопросы ( дурные, тупые, простые) то можете просто игнорировать и не заходить на эту тему... на этом форуме достаточно пользователей, которые могут дать ответы на мои вопросы, и при этом их не будет это раздражать.... .

Ссылка на комментарий
Поделиться на другие сайты

Отвечать не сложно, видимо Вам сложно думать.

В этих 4х строках кода нет ничего кроме операторов присвоения и знака плюса ;) Ну и 1 переменная. Неужели так сложно на листке бумаги нарисовать алгоритм? в том то и дело: вы не понимаете не сам код, а монера мышления у вас странная. вы дошли до середины, вроде верно рассуждали, потом нали опять уходить не туда, я порекомендовал собрать в железе например и проверить - вы проверили - написали что все в порядке. но вот почему вы сразу не стали думать тогда почему же ЭТО РАБОТАЕТ? А сразу же запросили алгоритм на более длинную строчку?

Ссылка на комментарий
Поделиться на другие сайты

Если бы нам было трудно отвечать, мы не отвечали бы. вы просите пример, мы Вам его даём. Только от этого смысла никакого нет, Вы либо не хотите понять, либо не можете.

И всётаки если не можете, попытаюсь объяснить по этому коду

void sdvig(void) 
{
char k,p1,p2;
k=0;
while (k<15) {
p1=lcd_read_byte(0x80+k);
p2=lcd_read_byte(0x81+k);
lcd_write_byte(0x81+k,p1);
lcd_write_byte(0x80+k,p2); 
k++;
};
};

char k,p1,p2;

Объявили 3 однобайтные переменные и присвоили им имена k,p1,p2.

k=0;

Тут думаю понятно

while (k<15)

{

......

В этих скобках будет выполнятся код, пока переменная k меньше 15-ти

......

}

p1=lcd_read_byte(0x80+k);

Читаем байт из ЛСД с адресом 0x80+k

Т.е. если k=0, читается адрес 0x80. Если k=1, адрес 0x81. И т.д...

И записываем считанное значение в переменную p1

p2=lcd_read_byte(0x81+k);

Тоже самое, только смещение по адресу не 0x80, а 0x81. Т.е. Следующий адрес, соответственно следующий символ в строке.

И записываем значение в переменную p2

lcd_write_byte(0x81+k,p1);

Записываем в ЛСД байт, со значением переменной p1, по адресу 0x81+k

Т.е. если k=0, адрес = 0x81. Если k=1, адрес = 0x82. И т.д...

lcd_write_byte(0x80+k,p2);

Тоже самое, только пишем из переменной p2 и по адресу 0x80+k.

k++;

Инкремент переменной k.

Получается что мы меняем два соседних символа местами. Почему только это бегущая строка получается, ХЗ.. :huh: Сам не понимаю :D

Ну вот, как то так....

Ссылка на комментарий
Поделиться на другие сайты

Есть команда сдвига всего экрана влево, вправо.

#define LCD_MOVE_DISP_LEFT       0x18   // shift display left                 
#define LCD_MOVE_DISP_RIGHT      0x1C   // shift display right                
_lcd_write_comand(LCD_MOVE_DISP_LEFT);
_lcd_write_comand(LCD_MOVE_DISP_ RIGHT);

Остается только написать _lcd_write_comand.

(В отличии от посылки данных, посылка команды производится при RS=0)

Правда Протеус 7.5 sp3 build 7401 сдвигает не в ту сторону, но в железе работает правильно.

В некоторых индикаторах(в моем тоже) длина строки 40 символов(при видимых 16).

Прокрутка происходит так, при прокрутке влево, отображаются 2-17 символы, далее 3-18 и.т.д.

1 символ появится справа после 40 символа.

Ссылка на комментарий
Поделиться на другие сайты

Получается что мы меняем два соседних символа местами. Почему только это бегущая строка получается, ХЗ.. :huh: Сам не понимаю :D

Ну вот, как то так....

реально порадовал ;))))))))) не в обиду конечно же ;)

Ссылка на комментарий
Поделиться на другие сайты

Не знаю в тему это или нет.Но вроде про дисплей.

Подскажите кто знает,как сохранить показания на дисплее в еепром чипа,или дисплея не знаю. Вобщем, надо сохранять показания счёта а потом после выключения по запросу вывести показания и продолжить отсчёт.Возможно как-то всю память дисплея сохранить?

Пользуюсь CVR библиотечными функциями подаренными мне уважаемым VipAndrey.

LCD 2x16 думаю это не важно,интересует команда правильно сформулированная.

Я так понимаю надо считать память RAM дисплея например в переменную unsigned char переменную переписать в еепром.И дальше по вызову какая-то команда которая выведет всё содержимое еепром в RAM LCD.Проблема в правильности записи и вывода.

Заранее спасибо всем.

Ссылка на комментарий
Поделиться на другие сайты

Сразу вопрос: факт отключения будет заранее известен процессору или постоянно регенирировать еепром?

Да и замутка у тебя не очень понятная. Попытаюсь обьяснить на пальцах:

Если у тебя некий счет, то у тебя сама программа работает с переменной, так? Так не проще ли сохранить саму переменную в еепроме? Даже если их несколько. Просто обьявляй так:

eeprom char podsvetka;

и всё. при любои изменении переменной она будет автоматом заноситься в еепром. Так что при обесточке - включении - всё сохраниться.

Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу

×
×
  • Создать...