четвер, 8 січня 2015 р.

Робота з семисегментним індикатором Частина_1



  Семисегментний індикатори - це світлодіоди, розміщені в певному порядку, так що запалюючи одночасно кілька світлодіодів, можна формувати на індикаторі символи і цифри. Індикатори бувають із загальним катодом (мінусом) і з загальним анодом (плюсом). Це означає, що всі сім світлодіодів з'єднані плюсом чи мінусом. Наприклад, візьмемо індикатор із загальним катодом і спробуємо на нього що-небудь вивести, наприклад цифру 1. Для цього нам потрібно включити світлодіоди B і С, або для того щоб вивести цифру "6" необхідно подати живлення на світлодіоди сегментів А,C,D,E,F та G. Підключити один семисегментний індикатор і керувати ним за допомогою мікроконтролера процедура нескладна. Для цього достатньо сегменти індикатора підключити до порту мікроконтролера через струмообмежувальні резистори по 250 Ом. Загальний вивод підключити до лінії іншого порту мікроконтролера. Залежно від того яку цифру треба вивести, в порт виводимо двійковий код цієї цифри, посилаючись на тип підключеного індикатора (із загальним анодом або катодом) на загальний провід подаємо плюс або мінус. Для зручності можна зробити таблицю кодів для індикатора. Якщо підключення таке: PD7-h, PD6-g, PD5-f, PD4-e, PD3-d, PD2-c, PD1-b, PD0-a, то для відображення цифри 1 в порт D потрібно вивести такий двійковий код: 0b00000110.
Рисунок 1 - Будова семисегментного індикатора
 із спільним катодом
   Для відображення цифрових даних одного семисегментного індикатора зазвичай недостатньо. У таких випадках до мікроконтролера підключають відразу кілька індикаторів, які зєднані в одну збірку паралельно. Однак, через відсутність достатньої кількості виводів у мікроконтролера застосовують спеціальні методи. Один з таких методів це динамічна індикація. Режим динамічної індикації застосовують для побудови багаторозрядних індикаторів. При такому режимі розряди індикатора працюють не одночасно, а по черзі. Перемикання розрядів відбувається з великою швидкістю ( більше 50 Гц), через це людське око не помічає, що індикатори працюють по черзі. Так як у світлодіодів дуже мала інерційність, що змінюються розряди зливаються в одне зображення. У цьому режимі в кожен момент часу працює тільки один розряд, включаються по черзі починаючи з першого закінчуючи останнім, потім все починається спочатку.

Рисунок 2 - Принцип динамічної індикації індикатора
   Підключити семисегментний індикатор до МК можна по схемі, яка приведена на рисунку 3  в нашому випадку використаємо індикатор  із спільним катодом, також слід зазначити, що виводи керування розрядами (1, 2, 3 та 4) бажано вмикати через транзисторні ключі тоді керування від пінів контролера інвертується.

Рисунок 3 - Схема вмикання індикатора та МК

   Нижче наведена таблиця відповідності коду який подається на порт D МК та цифр, що виводяться на семисегментний дисплей в двійковому та шістнадцятковому форматі.

Цифра PD7 (H) PD6 (G) PD5 (F) PD4 (E) PD3 (D) PD2 (C) PD1 (B) PD0 (A) HEX  
0 0 0 1 1 1 1 1 1 0x3F
1 0 0 0 0 0 1 1 0 0x06
2 0 1 0 1 1 0 1 1 0x5B
3 0 1 0 0 1 1 1 1 0x4F
4 0 1 1 0 0 1 1 0 0x66
5 0 1 1 0 1 1 0 1 0x6D
6 0 1 1 1 1 1 0 1 0x7D
7 0 0 0 0 0 1 1 1 0x07
8 0 1 1 1 1 1 1 1 0x7F
9 0 1 1 0 1 1 1 1 0x6F
h 1 0 0 0 0 0 0 0 0x80

   Програма мікроконтролера в IDE CodeVisionAVR приведена нижче, подробиці розкриті в коментарях, слід відзначити, що в програмі застосований таймер 0, для для формування переривань через рівні відрізки часу в кожному перериванні на індикаторі відображається один символ.  Частоту виникнення переривань можна розрахувати якщо відомо частоту тактового генератора fosc (8МГц), коефіцієнт подільника перед лічильником k (64) та розрядність лічильника 0 n (8):
   Отже, виведення символи на індикатор виводяться по одному по черзі через 2 мс, тобто з частотою 500 Гц чого цілком достатньо для динамічного відображення інформації. 


#include <mega8.h>
#include <delay.h>
#define DIGITS 4   // Кількість розрядів індикатора
unsigned short chislo[DIGITS]; //масив чисел, що відповідають кожному розряду
unsigned short numder[]= //масив, в якому індексу будут відповідати біти на порту D для кожної цифри
{ 
0b00111111, //цифра 0
0b00000110, //цифра 1
0b01011011, //цифра 2
0b01001111, //цифра 3
0b01100110, //цифра 4
0b01101101, //цифра 5
0b01111101, //цифра 6
0b00000111, //цифра 7
0b01111111, //цифра 8
0b01101111, //цифра 9
0b00000000, //пусто
};
unsigned char i=0; // змінна, що визначає номер розряду який виводиться
// преривання по переповненню timer0
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
PORTB=0x0f; // погасимо індикатор
PORTD=numder[ chislo[i] ]; // виведем поточне число
PORTB=~(1<<i); // вмикаємо відповідний розряд індикатора
if (i++>DIGITS) i=0; // якшо не дійшли до старшого розряду готуєм виведення наступного
}                    // якшо дійшли до старшого розряду готуєм виведення нульового
void out(unsigned short num)
{ 
    chislo[0]=num%10; //одиниці оператор % дає залишок від цілочисельного ділення, наприклад 34%10 будет 4
    chislo[1]=(num%100)/10; // десятки
    chislo[2]=(num%1000)/100; //сотні
    chislo[3]=num/1000; // тисячі
    if (chislo[3]==0) {chislo[3]=10; // виводимо "пусто" якщо старші розряди =0
      if (chislo[2]==0) {chislo[2]=10;
         if (chislo[1]==0) chislo[1]=10;
        }
       }
      }
void main(void)
{
unsigned int z=0; // змінна, яка виводиться на дисплей
PORTB=0x00;
DDRB=0b00001111; //PB0-3 виходи (розряди)

PORTD=0b0000000;
DDRD=0b01111111; //PD0-PD6 виходи (сегменти) 

TCCR0=0x03; //встановлюємо подільник таймера 64 
            //    кожне перерив приблизно 2 мс
TIMSK=0x01; // прерывания по переполнению таймера 0
#asm("sei") // глобальний дозвіл переривання

while (1) 
{
out(z); // виводимо значення змінної z і збільшуємо її на 1 кожні 200 мс
z++;

delay_ms(200);
 }
}


Працездатність програми підтверджує моделювання в Proteus схема на рисунку 4

Рисунок 4 - Схема моделі семисегментного індикатора в Proteus




Немає коментарів :

Дописати коментар