Обсуждаем контроллеры компании Atmel.
Ответить

Re: CodeVision AVR в вопросах и ответах

Пн ноя 25, 2019 12:27:14

Kotto писал(а):как авторы часов на ВЛИ и ГРИ реализуют различные спец эффекты
точно так же, как и всегда: любой эффект - это последовательность сменяемых состояний. к линамической индикации это не имеет отношения - динамическая индикация лишь служит средством вывода информации, а подготовкой информации занимается не она.

в самых общих чертах: у вас есть массив, допустим, из 6 байт, в каждой ячейке этого массива у вас хранятся символы, которые непрерывано (при помощи динамической индикации) отображаются на индикаторах. например, в массиве у вас {8,8,8,8,8,8} - на дисплее 6 восьмерок. если каждую секунду вы будете первую восьмерку в массиве заменять на "пробел" и обратно, на индикаторе у вас в первом разряде восьмерка будет мигать...

чтобы "нарисовать" разные эффекты, вам надо лишь прдесмотреть способ кодирования "символов", чтобы менять в массиве эти коды и наблюдать символы на индикаторе. а уж как менять - дело вашей фантазии...
Последний раз редактировалось ARV Пн ноя 25, 2019 12:33:44, всего редактировалось 1 раз.

Re: CodeVision AVR в вопросах и ответах

Пн ноя 25, 2019 12:32:38

Уважаемый ARV, то есть прерывание на динамической индикации просто выкидывает нам на лампы символы из массива, верно? Далее в массиве я просто где нибудь в другом месте меняю символы, верно?

К примеру на ВЛИ у меня будет уже большой массив, состоящий из отдельных сегментов. Я вас правильно понял?

А как, например, сделать плавное затухание? Первая мысль приходит в голову, в массиве каждому символу сделать соответственно значение яркости, а прерывание индикации в зависимости от этого значения будет пропускать цифры... Может как то проще можно?

Re: CodeVision AVR в вопросах и ответах

Пн ноя 25, 2019 12:38:35

Kotto писал(а):Далее в массиве я просто где нибудь в другом месте меняю символы, верно?
верно
Kotto писал(а):Может как то проще можно?
простота - хуже воровства :) в том слмысле, что простота в одном всегда оборачивается сложностью в другом.

вариантов регулировать яркость как всех индикаторов, так и выборочно, может быть просто мнодетсво: начиная от аналоговых (регулирование тока через индикатор аналоговыми срествами) до цифровых, из которых ШИМ - самый простой. в примере, что я выше описал (замена 8 на пробел и обратно) яркость восьмерки вы можете регулировать, меняя соотношение интервала "видимости" пробела: чем дольше пробле, тем ниже яркость восьмерки (только менять "пробел-восьмерка" надо не раз в секунду, а с частотой динамической индикации, т.е. заведомо чаще 25 раз в секунду).

как-то так.

вариант конкретной реализации я рассматривал в небольшой статье: http://arv.radioliga.com/content/view/101/49/

Re: CodeVision AVR в вопросах и ответах

Пн ноя 25, 2019 12:58:05

С общей регулировкой яркости я понимаю ) А вот, к примеру, при переключении секунд, секунды затухают с определенной скоростью, затем разгораются ярче, а остальные символы при этом вполне себе с обычной яркостью горят. Такая задача только введением дополнительного свойства яркости и пропуском циклов при отображении может быть реализована?
---

С пробелом дошло )) Я бы сам и не сообразил (

Re: CodeVision AVR в вопросах и ответах

Пн ноя 25, 2019 13:19:19

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

а вот пропуск циклов - штука скользкая, не стоит ШИМ вырождать в пропуск циклов, иначе вместо регулирования яркости получится мерцание

Re: CodeVision AVR в вопросах и ответах

Пн ноя 25, 2019 13:38:27

Про сегменты сообразил сразу ) За подсказки большое вам спасибо! Сейчас часики на ИВ-2 собираю, буду на них тренироваться, там для разных эффектов с их шрифтом раздолье ) В реальном коде конечно эти мысли все будут куда сложнее выглядеть, но теперь хоть знаю в какую сторону думать. Еще раз спасибо )

Re: CodeVision AVR в вопросах и ответах

Вт ноя 26, 2019 07:10:34

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

Добавлено after 5 minutes 34 seconds:
и мерцать будет намного меньше чем при пропуске периодов отображения

Re: CodeVision AVR в вопросах и ответах

Вт ноя 26, 2019 13:14:39

Я сейчас так и делаю, но таким образом получается только регулировать яркость всех индикаторов сразу. Кажется регистр TCCR какой то там, точно не помню, не суть, меняем его от 0 до 255, тем самым меняется яркость. В самом прерывании у меня переменная tic, с каждым вызовом она увеличивается на 1, после чего выполняется переключение сетки. Ну и второе прерывание, там просто выполняется гашение. Вроде бы все логично и понятно. А вот как именно в прерывании управлять яркостью конкретного индикатора, не трогая яркость других мне не понятно. Не могли бы вы подробнее объяснить или фрагмент кода набросать?

Re: CodeVision AVR в вопросах и ответах

Вт ноя 26, 2019 13:32:34

в прерывании переполнения:
зажигаем индикатор, подавая напряжение на электрод разряда;
окр1а=яркость[и]; //устанавливаем яркость зажигаемого индикатора

в прерывании окр1а:
забираем значение с присоединенной к экрану клавиатуры, если она есть;
гасим индикатор, снимая напряжение с электрода разряда;
портб=знак[и+1]; //выводим в порт сегментов картинку следующей цифры

Re: CodeVision AVR в вопросах и ответах

Вт ноя 26, 2019 13:37:06

Но таким образом мы будем как раз и менять яркость всех индикаторов разом? Простите, не понимаю :oops: :cry:

Re: CodeVision AVR в вопросах и ответах

Вт ноя 26, 2019 13:42:11

каждому разряду сопоставлена своя ячейка в массиве яркость[ ], значения из которого загружается в регистр сравнения при отображении каждого конкретного разряда...

Re: CodeVision AVR в вопросах и ответах

Вт ноя 26, 2019 14:01:07

а, дошло. Ну я так и писал выше, но сказали что пропусками будет правильнее. Плату сегодня планирую спаять и начать программирование, проверю как оно пойдет в двух случаях.

Re: CodeVision AVR в вопросах и ответах

Пт ноя 29, 2019 13:35:00

И снова здравствуйте!

https://www.youtube.com/watch?v=Cw6WTg8Qen8

Вот запустил часики, написал вот такой код

iv_2_source.rar
(66.52 KiB) Скачиваний: 177


Блин, помогите, на первый взгляд казалось все просто, но на деле оказалось что я даже не знаю как подступиться. Допустим я хочу 1) какую нибудь интересную смену цифр 2) Плавное гашение и разжигание.

Код:
unsigned char zero[8] = {1, 0, 1, 0, 1, 0, 1, 1};
unsigned char one[8] = {1, 1, 0, 1, 0, 1, 1, 1};
unsigned char two[8] = {1, 0, 1, 1, 1, 0, 0, 0};
unsigned char three[8] = {1, 0, 1, 0, 1, 1, 0, 0};
unsigned char four[8] = {0, 1, 1, 0, 1, 1, 1, 0};
unsigned char five[8] = {0, 0, 1, 0, 1, 1, 0, 1};
unsigned char six[8] = {1, 0, 1, 0, 1, 0, 1, 0};
unsigned char seven[8] = {1, 1, 1, 1, 0, 1, 0, 0};
unsigned char eight[8] = {0, 0, 1, 0, 1, 0, 0, 0};
unsigned char nine[8] = {0, 1, 1, 1, 0, 1, 0, 0};


Понимаю, что это вообще не оптимально и проще это все это использовать как биты числа, но для понимания пусть пока так будет.

Хочется в первую очередь понять :write: :idea:

Re: CodeVision AVR в вопросах и ответах

Пт ноя 29, 2019 14:27:38

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

если вы пройдете эти три этапа, все вопросы "как" у вас исчезнут сами собой

Re: CodeVision AVR в вопросах и ответах

Пт ноя 29, 2019 15:29:08

Буду долго тупить, но все же надо разобраться. Сейчас делаю вот так

Код:
// Timer2 overflow interrupt service routine
interrupt [TIM2_OVF] void timer2_ovf_isr(void)                    // Прерывание по переполнению на Timer2. Отвечает за динамическую индикацию.

    switch (a) {                                             
            case 0: if ((b1 >= 0) && (b1 < 6)) {show_num (lh); PORTC.4 = 0;}
                    if (b1 > 7) {b1 = 0;}
                    break;
            case 1: show_num (rh); PORTC.3 = 0;
                    break; 
            case 2: show_num (lm); PORTC.0 = 0;
                    break;
            case 3: show_num (rm); PORTC.1 = 0;
                    break;
            case 4: show_num (ls); PORTC.2 = 0;
                    break; 
            case 5: show_num (rs); PORTD.3 = 0;
                    break;
    }
    a++;
    b1++;                                                           
    if (a == 6) {a = 0;}                                       
}               

// Timer2 output compare interrupt service routine
interrupt [TIM2_COMP] void timer2_comp_isr(void)                   
{
    all_off ();
    off_segments ();   
}


Первая лампа просто не включается совсем


Код:
// Timer2 overflow interrupt service routine
interrupt [TIM2_OVF] void timer2_ovf_isr(void)                    // Прерывание по переполнению на Timer2. Отвечает за динамическую индикацию.

    switch (a) {                                             
            case 0: show_num (lh); PORTC.4 = 0;
                    break;
            case 1: show_num (rh); PORTC.3 = 0;
                    break; 
            case 2: show_num (lm); PORTC.0 = 0;
                    break;
            case 3: show_num (rm); PORTC.1 = 0;
                    break;
            case 4: show_num (ls); PORTC.2 = 0;
                    break; 
            case 5: if ((b1 >= 0) && (b1 < 7)) {show_num (rs); PORTD.3 = 0;}
                    if (b1 > br) {b1 = 0;}
                    break;
    }
    a++;
    b1++;                                                       
    if (a == 6) {a = 0;}                                       
}


И в основном цикле сделать так

Код:
        br++;
        if (br > 100) {br = 8;}
        delay_ms (10);


То в принципе яркость секунд меняется... Но не до нуля, если делать br больше сотни, то начинает мерцать, что логично. При этом надо как то точно синхронизировать затухание уложив его в секунду... Где можно посмотреть примеры реализации подобного? Никак не могу сообразить сам.
Последний раз редактировалось Kotto Пт ноя 29, 2019 15:45:49, всего редактировалось 1 раз.

Re: CodeVision AVR в вопросах и ответах

Пт ноя 29, 2019 15:42:19

прочитайте мои статьи о динамической индикации. одну ссылку я вам давал, там же на сайте есть и другие.

Re: CodeVision AVR в вопросах и ответах

Пт ноя 29, 2019 16:38:20

Прочитал, все что написано в статьях понятно. Дальше все равно не понимаю. Казалось бы пропуски я делаю, но толку мало, яркость отдельного индикатора нормально не регулируется, ну а как это во времени еще синхронизировать подавно не понятно ((

Re: CodeVision AVR в вопросах и ответах

Пт ноя 29, 2019 18:02:03

вы сделали так, чтобы массив "экранной области" у вас отображался на дисплее? вот если в главном цикле написать как-то так:
Код:
int main(void){
   char arr1[6] = {0,0,0,0,0,1};
   char arr2[6] = {0,0,0,0,0,2};
   char arr3[6] = {0,0,0,0,0,3};
   
   while(1){
      memcpy(scr, arr1, 6);
      delay_ms(1000);
      memcpy(scr, arr2, 6);
      delay_ms(1000);
      memcpy(scr, arr3, 6);
      delay_ms(1000);
   }
}
будет каждую секунду на индикаторе обновляться шестая цифра? т.е. как бы должно показывать 000001-000002-000003-000001-и т.д.
подразумевается, что scr - это тот самый массив "экранной области".

когда добьетесь этого, покажете нам код :)

Re: CodeVision AVR в вопросах и ответах

Пт ноя 29, 2019 18:41:45

Не могу уже, ударьте меня чем нибудь ( Таким тупым я себя со школы не ощущал ((

disp[6] - это массив цифр, которые отображаются на индикаторе, в прерывании они все выкидываются на индикаторы.

Код:
unsigned char a = 0;   
// Десятки часов, единицы часов
// десятки минут, единицы минут
// десятки секунд, единицы секунд
unsigned char disp[6];               
                                                               
// Timer2 overflow interrupt service routine
interrupt [TIM2_OVF] void timer2_ovf_isr(void)                 

    switch (a) {                                             
            case 0: show_num (disp[5]); PORTC.4 = 0;
                    break;
            case 1: show_num (disp[4]); PORTC.3 = 0;
                    break;               
            case 2: show_num (disp[3]); PORTC.0 = 0;
                    break;
            case 3: show_num (disp[2]); PORTC.1 = 0;
                    break;
            case 4: show_num (disp[1]); PORTC.2 = 0;
                    break; 
            case 5: show_num (disp[0]); PORTD.3 = 0;
                    break;
    }
    a++;
    if (a == 6) {a = 0;}                                       
}               

// Timer2 output compare interrupt service routine
interrupt [TIM2_COMP] void timer2_comp_isr(void)                   
{
// При включенной сетке погасить сегменты -
// пауза для исчезновения тока - выключить сетку -
// включить сегменты следующего индикатора - включить сетку оного.
    all_off ();
    off_segments ();   
}


В главном цикле разрываем показания с микросхемы на цифры, ну а прерывание кидает на индикаторы то что содержится в массиве

Код:
while (1)  {     
        if (i > 100000) {
            RTC_init ();      // Обратиться к ds3231 с прсьбой подготовить передачу даты и времени
            RTC_read_time (); // считаем время и дату
       
            disp[5] = hour23 / 10; disp[4] = hour23 % 10;           
            disp[3] = minute23 / 10; disp[2] = minute23 % 10;       
            disp[1] = sec23 / 10; disp[0] = sec23 % 10;             
            i = 0; 

        }         
        i++;
    }
}



Так же в отдельный файл выбросил функцию, которая создает цифру. Цифру сделал как биты числа, так меньше места занимает

Код:
unsigned char zero = 0b10101011;
unsigned char one = 0b11010111;
unsigned char two = 0b10111000;
unsigned char three = 0b10101100;
unsigned char four = 0b01101110;
unsigned char five = 0b00101101;
unsigned char six = 0b10101010;
unsigned char seven = 0b11110100;
unsigned char eight = 0b00101000;
unsigned char nine = 0b01110100;

void show_num (unsigned char a) {
    switch (a) {
        case 0: PORTD.4 = zero&0b10000000;
                PORTD.5 = zero&0b01000000;
                PORTD.6 = zero&0b00100000;
                PORTD.7 = zero&0b00010000;
                PORTB.1 = zero&0b00001000;
                PORTB.2 = zero&0b00000100;
                PORTB.6 = zero&0b00000010;
                PORTB.7 = zero&0b00000001;
                break;
        case 1: PORTD.4 = one&0b10000000;
                PORTD.5 = one&0b01000000;
                PORTD.6 = one&0b00100000;
                PORTD.7 = one&0b00010000;
                PORTB.1 = one&0b00001000;
                PORTB.2 = one&0b00000100;
                PORTB.6 = one&0b00000010;
                PORTB.7 = one&0b00000001;
                break;
        case 2: PORTD.4 = two&0b10000000;
                PORTD.5 = two&0b01000000;
                PORTD.6 = two&0b00100000;
                PORTD.7 = two&0b00010000;
                PORTB.1 = two&0b00001000;
                PORTB.2 = two&0b00000100;
                PORTB.6 = two&0b00000010;
                PORTB.7 = two&0b00000001;
                break; 
        case 3: PORTD.4 = three&0b10000000;
                PORTD.5 = three&0b01000000;
                PORTD.6 = three&0b00100000;
                PORTD.7 = three&0b00010000;
                PORTB.1 = three&0b00001000;
                PORTB.2 = three&0b00000100;
                PORTB.6 = three&0b00000010;
                PORTB.7 = three&0b00000001;
                break;

        case 4: PORTD.4 = four&0b10000000;
                PORTD.5 = four&0b01000000;
                PORTD.6 = four&0b00100000;
                PORTD.7 = four&0b00010000;
                PORTB.1 = four&0b00001000;
                PORTB.2 = four&0b00000100;
                PORTB.6 = four&0b00000010;
                PORTB.7 = four&0b00000001;
                break;               
        case 5: PORTD.4 = five&0b10000000;
                PORTD.5 = five&0b01000000;
                PORTD.6 = five&0b00100000;
                PORTD.7 = five&0b00010000;
                PORTB.1 = five&0b00001000;
                PORTB.2 = five&0b00000100;
                PORTB.6 = five&0b00000010;
                PORTB.7 = five&0b00000001;
                break;
                 
        case 6: PORTD.4 = six&0b10000000;
                PORTD.5 = six&0b01000000;
                PORTD.6 = six&0b00100000;
                PORTD.7 = six&0b00010000;
                PORTB.1 = six&0b00001000;
                PORTB.2 = six&0b00000100;
                PORTB.6 = six&0b00000010;
                PORTB.7 = six&0b00000001;
                break;     
               
        case 7: PORTD.4 = seven&0b10000000;
                PORTD.5 = seven&0b01000000;
                PORTD.6 = seven&0b00100000;
                PORTD.7 = seven&0b00010000;
                PORTB.1 = seven&0b00001000;
                PORTB.2 = seven&0b00000100;
                PORTB.6 = seven&0b00000010;
                PORTB.7 = seven&0b00000001;
                break;   
               
        case 8: PORTD.4 = eight&0b10000000;
                PORTD.5 = eight&0b01000000;
                PORTD.6 = eight&0b00100000;
                PORTD.7 = eight&0b00010000;
                PORTB.1 = eight&0b00001000;
                PORTB.2 = eight&0b00000100;
                PORTB.6 = eight&0b00000010;
                PORTB.7 = eight&0b00000001;
                break; 
               
        case 9: PORTD.4 = nine&0b10000000;
                PORTD.5 = nine&0b01000000;
                PORTD.6 = nine&0b00100000;
                PORTD.7 = nine&0b00010000;
                PORTB.1 = nine&0b00001000;
                PORTB.2 = nine&0b00000100;
                PORTB.6 = nine&0b00000010;
                PORTB.7 = nine&0b00000001;
                break;                                                       
    }   
}


Хоть что то я делаю правильно чтобы придти к пониманию? Это какой то северный пушной зверек. Как только я в этом разберусь, обязательно сам буду писать статью для таких же как я, иначе в интернете инфы именно по этому вопросу никакой ((

ARV и другие кто читает эту тему, я отлично понимаю как раздражает тупление новичков, но очень вас прошу о терпении и понимании, я действительно хочу разобраться.
----------


Если я верно вас понял, SCR у меня это DISP, если я буду в него копировать массивы с набором цифр, то меняться они разумеется будут.

Re: CodeVision AVR в вопросах и ответах

Пт ноя 29, 2019 19:34:13

я же вам давал ссылки на мои статьи, разве там ТАК рекомендовалось делать?

ведь все вопросы, касающиеся организации прерыания для индикации, организации преобразования чисел в символы и т.п. я там расписывал...
Ответить