Динамическая индикация, проблемка

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Закрыто
Аватара пользователя
a_sergeevich
Первый раз сказал Мяу!
Сообщения: 34
Зарегистрирован: Ср окт 01, 2008 20:39:59
Откуда: ЯНАО
Контактная информация:

Динамическая индикация, проблемка

Сообщение a_sergeevich »

Возникла у меня проблема,прямо таки стоупор какой-то.
Дело вот в чем, начал я изучать динамическую индикацию и в принципе всё мне с ней понятно вот мой учебный код динамической индикации:

Код: Выделить всё

#define _pic16f877    // зададим тип процессора
#include <pic>    // подключим файл описаний

__CONFIG(LVPDIS & UNPROTECT & PWRTDIS & WDTDIS & XT);

// таблица знакогенератора
const unsigned char CODE_TABLE[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};    

unsigned char buffer[9]={1,2,3,4,5,6,7,8,9};    // буфер индикатора
unsigned char PTR;    // указатель буфера

void    main(void)
{

    // настроим порты на выход
    TRISB = 0b11110000;    // для дешифратора знакомест (4 младших разряда)
    TRISD = 0b00000000;    // для символа

    PORTD = 0;        // очистим индикатор
    PTR = 0;        // начало буфера
    PORTB = 0b00001111;    // установим последний разряд индикатора

    OPTION = 0b10000010;    // запишем байт настройки в регистр OPTION
    INTCON = 0;        // Выключить все прерывания и сбросить T0IF
    TMR0 = 0;        // Сброс TMR0

    T0IE = 1;        // Разрешить прерывания от TMR0
    GIE = 1;        // Разрешить все прерывания

    
    // зациклим программу
cycle:;
    goto cycle;


}

// обработка прерываний
void interrupt all(void)
{

    PORTD = 0;    // очистим индикатор
    PORTB++;    // установим следующее знакоместо для отображения
    PORTD = CODE_TABLE[buffer[PTR]];    // выведем на индикатор
    PTR++;        // установим указатель на следующий символ
         
    if(PTR == 10) { PTR = 0; PORTB = 0b00001111; } //проверим, не кончился ли массив для вывода на индикатор

    T0IF = 0;    // сбросим флаг прерывания
}
Тут просто выводятся цифры от 1 до 9 на АЛС318 т.е ничего сложного.Теперь ближе к делу или проблеме. Во время всех этих изучений возник вопрос, а как вывести на тот же АЛС318 не 9-ти значное число, а допустим 16-ти,например 1,2,3,4,5,6,7,8,9,0,9,8,7,6,5,4., т.е получится должно, что то типа бегущей строки или эффекта скроллинга.
Я попытался сделать это следующим образом.

в обработчике прерывания изменил и добавил

if(PTR == 10) { PORTB = 0b00001111; }
if(PTR == 16) { PTR = 0; PORTB = 0b00001111; }
но такой способ не прокатывает показания накладываются друг на друга и получается белебирда.
Я ставил задержку, что-бы понаблюдать как все происходит и при включенной задержке я четко вижу как последовательно загораются цифры от 1 до 9 затем от 0 до 4.Нутром чую, что надо наверное как-то организовать, что-то типа паузы между частями,но как это сделать ну никак не врублюсь, вроде придет мысль и думаю ну вот сейчас заработает, а оно не работает результат тот же одни показания накладываются на другие. :cry:
Может хоть кто нибудь направить в нужном направлении куда капать, только по подробнее если можно.

Компилятор используемый мной для этого примера HITECH-PICC.
Дешифратор 74145
МК PIC16F877A

Файл для протеуса:
Вложения
din_ind.zip
(8.33 КБ) 189 скачиваний
Реклама
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18657
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Сообщение ARV »

прочтите статеечки на моем сайте - я писал, опираясь на AVR, но Си он и в африке Си, а проблема у вас именно с алгоритмом... так что почитайте - вдруг поможет?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Реклама
Аватара пользователя
dosikus
Друг Кота
Сообщения: 3604
Зарегистрирован: Пн июл 28, 2008 22:12:01

Сообщение dosikus »

Заполняй буфер в главном цикле а не в прерывании .
Заполнил {1,2,3,4,5,6,7,8,9} - тебе это вывело , задержка, затем {2,3,4,5,6,7,8,9,0}задержка, затем {3,4,5,6,7,8,9,0,8} и т.д .
Задержкой меняешь скорость перемещения .

Код: Выделить всё

    // зациклим программу 
cycle:; 
    goto cycle;
Кошмар.....
Видать с бэйсика перешел ?
Хоть это и одно и то же , но можно же было :

Код: Выделить всё

 while(1)
  {
     }
Аlex

Сообщение Аlex »

dosikus, разницы нет никакой, кому как удобнее. Скомпилированый код в обоих случаях одинаковый. Никакого кошмара нет в этом.

a_sergeevich, ваш код стек переполняет, ищите косяки.
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
a_sergeevich
Первый раз сказал Мяу!
Сообщения: 34
Зарегистрирован: Ср окт 01, 2008 20:39:59
Откуда: ЯНАО
Контактная информация:

Сообщение a_sergeevich »

Да не переходил я с бейсика :) ну просто так написал, обычно всегда и пишу while(1) { }.

Так сейчас буду пробовать переварить инфу по буферам. :)
Реклама
Аватара пользователя
a_sergeevich
Первый раз сказал Мяу!
Сообщения: 34
Зарегистрирован: Ср окт 01, 2008 20:39:59
Откуда: ЯНАО
Контактная информация:

Сообщение a_sergeevich »

ARV, статья про динамическую индикацию отличная, спасибо.
Реклама
Аватара пользователя
dosikus
Друг Кота
Сообщения: 3604
Зарегистрирован: Пн июл 28, 2008 22:12:01

Сообщение dosikus »

Аlex писал(а):dosikus, разницы нет никакой, кому как удобнее. Скомпилированый код в обоих случаях одинаковый. Никакого кошмара нет в этом.

a_sergeevich, ваш код стек переполняет, ищите косяки.
Уважаемый , о том что разницы нет и я писал - иль вы только шапки всегда читаете ? 8)
Кошмар именно в goto , увидев это новичок подумает
что можно этот оператор везде юзать...
И вообще все это было шуткой а не наездом, извиняюсь что смайл не влепил , думал догадаетесь сами... :)) :)) :)) :))
Последний раз редактировалось dosikus Вс сен 27, 2009 09:42:19, всего редактировалось 1 раз.
Аватара пользователя
dosikus
Друг Кота
Сообщения: 3604
Зарегистрирован: Пн июл 28, 2008 22:12:01

Сообщение dosikus »

a_sergeevich писал(а):Да не переходил я с бейсика :) ну просто так написал, обычно всегда и пишу while(1) { }.

Так сейчас буду пробовать переварить инфу по буферам. :)
В прерывании сканируется буфер - на определенное знакоместо проецируется определенный элемент буфера, одно прерывание -один элемент. И так все элементы . Период обновления всего индикатора должен быть более 25 Гц . Нам надо создать анимацию - где каждый кадр это состояние буфера на момент вывода кадра .... Думаю дальше сам разберешься .
Сайт ARV в помощь . Спасибо ему за это говорю.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18657
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Сообщение ARV »

dosikus писал(а): Кошмар именно в goto , увидев это новичок подумает что можно этот оператор везде юзать...
вы будете наверное удивлены, но оператор goto действительно можно везде юзать :))) и порой без него получается много хуже, чем с ним... хотя принято считать этот оператор "неприличным" :)))
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
a_sergeevich
Первый раз сказал Мяу!
Сообщения: 34
Зарегистрирован: Ср окт 01, 2008 20:39:59
Откуда: ЯНАО
Контактная информация:

Сообщение a_sergeevich »

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

Код: Выделить всё

#define _pic16f877
#define  buf_size 20
#include <pic>

__CONFIG (LVPDIS & UNPROTECT & PWRTDIS & WDTDIS & XT);

const unsigned char CODE_TABLE[10] = 
{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f
};

unsigned char buffer[buf_size];
unsigned char buffer2[buf_size]={1,2,3,4,5,6,7,8,9,4,5,3,6,2,1,0,3,4,5,7
};
unsigned char PTR;
unsigned int i = 0, j=0, z;
int s=0;

void main (void) 
{
    

    TRISB = 0b11110000;
    TRISD = 0b00000000;
    PORTD = 0;
    PTR = 0;
    PORTB = 0b00001111;
    OPTION = 0b10000010;
    INTCON = 0;
    TMR0 = 0;
    T0IE = 1;
    GIE = 1;

    while (1)
    {
        for(i=0;i<=9;i++)
        {
            buffer[i] = buffer2[j];
            
            j++;
            
            if (j==buf_size+1) { s= -1; break;
            }
        }
        
        s=s+1;
        j=s;
        
        
        
        
        
        

        for(z=0; z<=30000; z++);
    }
}


    void interrupt all (void)
    {
        PORTD = 0;
        PORTB++;
        PORTD = CODE_TABLE[buffer[PTR]];
        PTR++;

        if(PTR==9) {PTR = 0; PORTB = 0b00001111;
        }
        T0IF = 0;
    }
Всё работает, единственное не хочет отображать последнюю цифру, никак не пойму почему.[/code]
Ant1Player
Первый раз сказал Мяу!
Сообщения: 33
Зарегистрирован: Чт июл 14, 2011 22:19:21

Re: Динамическая индикация, проблемка

Сообщение Ant1Player »

Поднимаю тему :) т.к. нужна помощь..
вот кусока кода под АВР

Код: Выделить всё

interrupt [EXT_INT1] void ext_int1_isr(void)
{
imp++;
}

interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
 if (nom_temp<3) nom_temp++; else nom_temp=1;
 switch (nom_temp)
 {
  case 1: {if (kmh>99) display((kmh/100)%10,3); break;}
  case 2: {if (kmh>9)  display((kmh/10)%10,2);break;}
  case 3: {display(kmh%10,1);break;}
 }
}

// Timer 1 output compare A interrupt service routine
interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
kmh=imp*9/5;
переделываю его под пик,с индикацией разобрался, но встрял с импульсами, это спидометр, считывает импульсы, но я так понимаю их надо считывать таймером, но не въезжаю как, можно плз показать как это сделать, с коментами..как разбить км\ч по сегментам разберусь..а вот с импульсами.. :(
P.S. датчик с двумя контактами, 1 на массу второй в МК
Закрыто

Вернуться в «Микроконтроллеры и ПЛИС»