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

Динамическая индикация

Сб окт 26, 2019 22:22:52

AT90USB162. Нужно чтобы два средних разряда 4-разрядного индикатора мигали. Прерывания по идее пока не должны использоваться.
В протеусе мигает, а вот настоящий микро просто светит цифры...
Код:
.device     AT90USB162
.include "usb162def.inc"
.def    tmp= r16
rjmp reset                  ;прерывание по сбросу
.org $0040 ;*******начало основной программы
reset:   
    ldi     tmp,High(RAMEnd)   
    out     sph,tmp 
    ldi     tmp,Low(RAMEnd)   
    out     spl,tmp         
    ldi     tmp,0b11111111       
    out     DDRB,tmp           
    ldi     tmp,0b11111111               
    out     DDRD,tmp
    ldi     tmp,0b01100000
    out     PORTD,tmp
main:
    ldi  r21, 1 ; выводим единицы
    call decode
    call delay
    ldi  r21, 10 ;гасим
    call decode
    call delay
    jmp  main
decode:   
    lsl r21
    ldi zh, high(DcMatrix*2)   
    ldi zl, low(DcMatrix*2)   
    ldi tmp,0   
    add zl,r21   
    adc zh,tmp   
    lpm r0,z   
    out PORTB,r0; вывод кода индикации в порт   
    ret
DcMatrix:
                          .db 0b00111111
              .db 0b00000110
              .db 0b01011011
              .db 0b01001111
              .db 0b01100110
              .db 0b01101101
              .db 0b01111101
              .db 0b00000111
              .db 0b01111111
              .db 0b01101111   
              .db 0b00000000
delay:     
    ldi r17,255   
    ldi r18,200
    ldi r19,0   
    ldi r20,0
_delay: subi r17,0x1     
    sbci r18,0     
    sbci r19,0     
    sbci r20,0     
    brcc _delay     
    ret

Re: Динамическая индикация

Вс окт 27, 2019 00:44:39

,В протеусе мигает, а вот настоящий микро просто светит цифры...

Есть подозрение, что у Вас и в настоящем мигает, просто Вы этого не видете :-)

Re: Динамическая индикация

Вс окт 27, 2019 05:02:23

AT90USB162.
В протеусе мигает, а вот настоящий микро просто светит цифры...
Думаю, мешает WDT. Попробуйте программно отключить его. Типа
Спойлер
Код:
.include "usb162def.inc"
.def    tmp= r16
.def   ZERO=R15
rjmp reset                  ;прерывание по сбросу
.org $0040 ;*******начало основной программы
reset:   
    ldi     tmp,High(RAMEnd)   
    out     sph,tmp
    ldi     tmp,Low(RAMEnd)   
    out     spl,tmp         

; Reset Watchdog Timer
   WDR

   CLR   ZERO
   OUT   MCUSR,ZERO
; Start timed sequence
   LDI   R16,1<<WDCE|1<<WDE
   STS   WDTCSR, R16
   CBR   R16,1<<WDE
   STS   WDTCSR,R16

    ldi     tmp,0b11111111       
    out     DDRB,tmp           
    ldi     tmp,0b11111111               
    out     DDRD,tmp
    ldi     tmp,0b01100000
    out     PORTD,tmp
main:
    ldi  r21, 1 ; выводим единицы
    call decode
    call delay
    ldi  r21, 10 ;гасим
    call decode
    call delay
    jmp  main
decode:   
;    lsl r21
    ldi zh, high(DcMatrix*2)   
    ldi zl, low(DcMatrix*2)   
;    ldi tmp,0   
    add zl,r21   
    adc zh,ZERO   
    lpm r0,z   
    out PORTB,r0; вывод кода индикации в порт   
    ret
DcMatrix:
   .db 0b00111111,0b00000110   ;0,1
   .db 0b01011011,0b01001111   ;2,3
   .db 0b01100110,0b01101101   ;4,5
   .db 0b01111101,0b00000111   ;6,7
   .db 0b01111111,0b01101111   ;8,9
   .db 0b00000000,0b00000000   ;
delay:     
    ldi r17,255   
    ldi r18,200
    ldi r19,0   
    ldi r20,0
_delay: subi r17,0x1     
    sbci r18,0     
    sbci r19,0     
    sbci r20,0     
    brcc _delay     
    ret
.EXIT

Re: Динамическая индикация

Пт янв 03, 2020 15:22:09

Всем доброго времени суток. Нашел на AliExpress такой вот индикатор. (См.вложение) Планирую использовать его в своем проекте. Индикатор имеет 8 выводов, и состоит из 16 светодиодов, подключенных по схеме матрицы 4х4. С помощью сдвигового регистра в протеусе подал на индикатор коды от 0 до 255. Использовал кнопку для инкремента переменной по внешнему прерыванию. Да вот оказия. Мне необходимо получить последовательное зажигание всех светодиодов. Но, согласно схеме матрицы, последовательность диодов D0,D1,D2,D3 + D4...D6 статически никак не зажечь. И тут как выход - динамическая индикация на таймере. D0,D1,D2,D3 и D0,D4 мерцают с частотой, которая настраивается и зависит от:
1) Частоты МК (от фьюзов при прошивке МК).
2) Делителя частоты при инициалицации таймера.
3) Регистра сравнения в таймере/компараторе.
Задача - найти необходимые значения частоты при которой мерцание светодиодов было бы не заметным. Пришлость немного нагородить секций в switch( :)) ){}
Indicator.gif
Индикатор
(130.51 KiB) Скачиваний: 223
Модель_в_протеусе-4.gif
Модель в протеусе-4
(112.04 KiB) Скачиваний: 196
Модель_в_протеусе-14.gif
Модель в протеусе-14
(140.9 KiB) Скачиваний: 210
Модель_в_протеусе-15.gif
Модель в протеусе-15
(69.93 KiB) Скачиваний: 188
Код
Спойлер
Код:
/* --------- ATiny85  --------- */
#define F_CPU 8000000UL //частота процессора 8 MHz
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include "shiftreg.h"

#define Prescaler_No   (1<<CS00) //No prescaling)
#define Prescaler_8    (1<<CS01)
#define Prescaler_64   (1<<CS01)|(1<<CS00)
#define Prescaler_256  (1<<CS02)
#define Prescaler_1024 (1<<CS00)|(1<<CS02);

volatile uint8_t trigger = 1;
volatile uint8_t dat = 0;
volatile uint8_t temp;
uint8_t display[4];
uint8_t digits[] = {
   0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x00
     };

SHIFTREG_register reg;

void INT0_init( void )
{
   GIMSK = (1 << INT0);
   MCUCR = (1 << ISC01);
};

ISR(INT0_vect)//External Interrupt
{
dat++;   
};

void TIM0_COMPA_init(void ){
   TCNT0 = 0; //Очищаем счетный регистр (на вcякий случай)
   OCR0A = (256-1)-0;//Регистр сравнения, (256-1)-число
   TCCR0A = (1<<WGM01);// Сброс при совпадении.
   TIFR = (1<<OCF0A); // Регистр флагов прерываний таймера счетчика
   TIMSK = (1<<OCIE0A); //Разрешение прерывания по совпадению таймера/счётчика 0A
   TCCR0B = Prescaler_1024;// Делитель частоты
};

ISR(TIM0_COMPA_vect){
   
trigger = (trigger==0)?(1):(0);

switch (dat) {
case  0:{ display[0] = 23; break; }
case  1:{ display[0] = 55; break; }
case  2:{ display[0] = 119; break; }
case  3:{ display[0] = 247; break; }
case  4:{ display[0] = (trigger) ? (247) : (19); break;}
case  5:{ display[0] = (trigger) ? (247) : (51); break;}      
case  6:{ display[0] = (trigger) ? (247) : (115); break;}
case  7:{ display[0] = 243; break; }
case  8:{ display[0] = (trigger) ? (243) : (17); break;}
case  9:{ display[0] = (trigger) ? (243) : (49); break;}
case 10:{ display[0] = (trigger) ? (243) : (113); break;}
case 11:{ display[0] = 241; break; }
case 12:{ display[0] = (trigger) ? (241) : (16); break;}   
case 13:{ display[0] = (trigger) ? (241) : (48); break;}
case 14:{ display[0] = (trigger) ? (241) : (112); break;}
case 15:{ display[0] = 240; break; }
default:{ break; }
}   
   temp      =  (dat / 100) % 10;
   display[3] =  digits[temp];
   temp      =  (dat / 10)  % 10;
   display[2] =  digits[temp];
   temp      =  dat % 10;
   display[1] =  digits[temp];

SHIFTREG_OutputValue( &reg, display, 4 );

if( dat>15 ){ dat=0; }

};

int main(void)
{   
   DDRB &= ~(1 << PB2);
//                                              ds_pin,st_cp_pin,sh_cp_pin
   reg = SHIFTREG_InitRegister(&DDRB, &PORTB, PB0,   PB1,      PB3);
   TIM0_COMPA_init();
   INT0_init();
   sei();

   while (1) {   }
   
   return 0;
}

/*
23,55, ... 240 коды, при отправке которых в регистр 74HC595, загораются светодиоды в матрице
----------
(0) 23 ---------D0
(1) 55 ---------D0,D1
(2) 119 --------D0,D1,D2
(3) 247 --------D0,D1,D2,D3
(4) 247+19 -----D0,D1,D2,D3 + D4        (динамическая индикация)
(5) 247+51 -----D0,D1,D2,D3 + D4,D5     (динамическая индикация)
(6) 247+115 ----D0,D1,D2,D3 + D4,D5,D6  (динамическая индикация)
(7) 243 --------D0,D1,D2,D3,D4,D5,D6,D7
(8) 243+17 -----D0,D1,D2,D3,D4,D5,D6,D7 + D8        (динамическая индикация)
(9) 243+49 -----D0,D1,D2,D3,D4,D5,D6,D7 + D8,D9     (динамическая индикация)
(10) 243+113 ---D0,D1,D2,D3,D4,D5,D6,D7 + D8,D9,D10 (динамическая индикация)
(11) 241 -------D0,D1,D2,D3,D4,D5,D6,D7,D8,D9,D10,D11
(12) 241+16 ----D0,D1,D2,D3,D4,D5,D6,D7,D8,D9,D10,D11 + D12         (динамическая индикация)
(13) 241+48 ----D0,D1,D2,D3,D4,D5,D6,D7,D8,D9,D10,D11 + D12,D13     (динамическая индикация)
(14) 241+112 ---D0,D1,D2,D3,D4,D5,D6,D7,D8,D9,D10,D11 + D12,D13,D14 (динамическая индикация)
(15) 240 -------D0,D1,D2,D3,D4,D5,D6,D7,D8,D9,D10,D11,D12,D13,D14,D15
*/
Но это свего лишь модель, и код ещё предстоит тестировать на реальных элементах. На семисегментниках будет отображаться остаток топлива в бензобаке в литрах. А такой вот круговой индикатор - дублирует цифровой для быстрой оценки остатка. Может у кого есть какие либо соображения, уважаемые Коты.

Re: Динамическая индикация

Пт янв 03, 2020 19:48:30

если оно будет в машине - то чем быстрей тем лучше, иначе при вибрации/тряске цифры трясёт (пропадает целостность восприятия дисплея) 1кГц на полное обновление минимум
но и в мегагерцы, конечно загонять тоде не стоит - яркость снизится, нагрузка на алу вырастет...

Добавлено after 5 minutes 51 second:
прикольный индикатор, хоть бы ссылкой поделился :)

Re: Динамическая индикация

Пт янв 03, 2020 20:13:22

Круговая светодиодная точечная матрица/16 отдельных световых точек/15 точек зеленый/1 точка красный свет/8 контактов Планирую такое дело поставить на мотоцикл. Частоту вероятнее всего придется подбирать экспериментально. (Примерно как у ШИМ-ов)

----
OK
Последний раз редактировалось Эйлер Леонард Пт янв 03, 2020 22:56:56, всего редактировалось 1 раз.

Re: Динамическая индикация

Пт янв 03, 2020 21:46:57

Эйлер Леонард, не надо изменять размер шрифта. тем более, что ты задаешь размер меньше "стандартного".
Ответить