Опубликовано 2010-02-27 09:55:03 автором MRS

Підключення до мікроконтролера семисегментний індикатора


У попередньому уроці ми навчилися блимати світлодіод. Цей урок не набагато складніше, тут ми навчимося блимати 7 світлодіодами. Але не просто сім світлодіодів, а семисегментний індикаторсемисегментний індикатор.

Семисегментные індикатори - це світлодіоди, розміщені в певному порядку, так що запалюючи одночасно декілька світлодіодів, можна формувати на індикаторі символи і цифри. Індикатори бувають з загальним катодом (мінусом) з загальним анодом (плюсом). Це означає, що всі сім світлодіодів з'єднані плюсом або мінусом. Наприклад, візьмемо індикатор з загальним катодом і спробуємо на нього що-небудь вивести, наприклад цифру 1. Для цього нам потрібно включити світлодіоди B і С. Беремо наш atmega8 та підключаємо до семисегментнику за схемою схема підключення семисегментника до мк Пишемо просту програму, яка виведе цифру 1

#include <mega8.h> 
void main(void) 
{ 
PORTB=0x00; 
DDRB=0b00000001; //робимо ніжку PB0 виходом 
 
PORTD=0b00000110; // виводимо на ніжки PB1, PB2 лог одиницю, щоб запалити цифру 1 
DDRD=0b01111111; //Робимо ніжки PB0-PB6 виходами 
 
while (1) {}
} 

Дивимося на результат і радіємо! А як на рахунок того, щоб вивести будь-яку цифру від 0 до 9? Для цього нам доведеться трошки ускладнити нашу програму. Напишемо процедуру out для виведення цифр від 0 до 9.
#include <mega8.h> 
#include <delay.h> 
unsigned char numder[]= //визначаємо масив, у якому індекс буде відповідати виведеної цифрі 
{  
0b00111111, //цифра 0 
0b00000110, //цифра 1 
0b01011011, //цифра 2 
0b01001111, //цифра 3 
0b01100110, //цифра 4 
0b01101101, //цифра 5 
0b01111101, //цифра 6 
0b00000111, //цифра 7 
0b01111111, //цифра 8 
0b01101111, //цифра 9 
}; 
 
void out(unsigned char num) 
{ 
PORTD=numder[num]; 
} 
 
void main(void) 
{ unsigned char i=0; 
PORTB=0x00; 
DDRB=0b00000001; //робимо ніжку PB0 виходом 
 
PORTD=0b0000000; 
DDRD=0b01111111; //Робимо ніжки PB0-PB6 виходами 
 
while (1)  
{ 
out(i++); 
delay_ms(1000);//затримка в 1 секунду 
} 
} 

Результат висновок на семисегментний індикатор Семисегментным індикатором можна управляти статично і динамічно. При статичному управлінні інформація на розряди виводиться постійно, до цього ми розглядали статистичне управління. Динамічне управління - це почергове запалювання розрядів індикатора з частотою, яку не сприймає людське око. Схема підключення в цьому випадку виглядає так динамічний висновок на семисегментний індикатор Тепер в нашому коді ми міняємо лише одну сходинку DDRB=0b00000001; на DDRB=0b00000011; //робимо ніжку PB0 і PB1 виходом і дивимося результат. динамічний висновок на семисегментник У нас на обох розрядах виводяться однакові цифри, а нам потрібно, наприклад, на першому виводити цифру 1, а на другому цифру 7. Коли на першому ми будемо виводити цифру "один", другий розряд при цьому вимкнений. У наступний момент часу вимикаємо перший, а на другий виводимо цифру "7". Для відключення по черзі першого і другого розрядів ми будемо встановлювати різні лог рівні на PD0 і PD1.
#include <mega8.h> 
#include <delay.h> 
unsigned char numder[]= //визначаємо масив, в якому індексом будуть відповідати біті на порту D 
{  
0b00111111, //цифра 0 
0b00000110, //цифра 1 
0b01011011, //цифра 2 
0b01001111, //цифра 3 
0b01100110, //цифра 4 
0b01101101, //цифра 5 
0b01111101, //цифра 6 
0b00000111, //цифра 7 
0b01111111, //цифра 8 
0b01101111, //цифра 9 
}; 
 
void out(unsigned char num) 
{  
PORTD=numder[num]; 
} 
 
void main(void) 
{ unsigned char z=0; 
PORTB=0x00; 
DDRB=0b00000011; //робимо ніжку PB0 і PB1 виходом 
 
PORTD=0b0000000; 
DDRD=0b01111111; //Робимо ніжки PB0-PB6 виходами  
while (1)  
{ 
if (z==0) //якщо z=0, то виводимо першу цифру 
{ 
out(1); //виводимо 1 
PORTB=0b00000001; // включаємо семисегментник, який висить катодом на ніжці PB0 
} 
if (z==1) //якщо z=1 виводимо другу цифру 
{ 
out(7); // виводимо цифру 7 
PORTB=0b00000010; // Включаємо семисегментник на ніжці PB1 
}  
if (++z>1) z=0; // збільшуємо z на одиницю і перевіряємо, не більше 1. Якщо більше, то z записуємо 0 
delay_ms(40); //Робимо затримку в 40 мілісекунд, це 25 висновків за секунду 
} 
} 

Давайте все це приаккуратим:
  1. Зробимо, щоб ми могли викликати процедуру out, передавши їй будь-яке число від 0 до 99, і вона сама вирішить, на який сегмент яку цифру виводити
  2. Приберемо логіку виведення на дисплей з головного циклу і помістимо її в таймер, наприклад на timer0
#include <mega8.h> 
#include <delay.h> 
unsigned char chislo[2]; //визначаємо масив з двох елементів типу char беззнаковий(unsigned) 
unsigned char numder[]= //визначаємо масив, в якому індексом будуть відповідати біті на порту D 
{  
0b00111111, //цифра 0 
0b00000110, //цифра 1 
0b01011011, //цифра 2 
0b01001111, //цифра 3 
0b01100110, //цифра 4 
0b01101101, //цифра 5 
0b01111101, //цифра 6 
0b00000111, //цифра 7 
0b01111111, //цифра 8 
0b01101111, //цифра 9 
}; 
unsigned char i=0; // змінна для визначення, на який розряд семисегментника виводити число 
// переривання по переповнюванню timer0 
interrupt [TIM0_OVF] void timer0_ovf_isr(void) 
{ 
PORTD=numder[ chislo[i] ];  
PORTB=i+1; //включаємо певний розряд семисегментника 
if (++i>1) i=0; 
} 
 
void out(unsigned char num) 
{  
/*спочатку нам потрібно визначити, скільки десятків і одиниць складається виведене число. 
Наприклад, ми передали "45", нам треба його розкласти на 4 і 5, щоб на перший розряд семисегментника  
вивести цифру 4, а на другий - 5 */ 
chislo[0]=num%10; //оператор % дає залишок від цілочисельного ділення, наприклад 34%10 4 
chislo[1]=num/10; // дізнаємося, скільки десятків в числі 
} 
 
void main(void) 
{ 
unsigned char z=0; // змінна, яка буде виводитися на дисплей 
PORTB=0x00; 
DDRB=0b00000011; //робимо ніжку PB0 і PB1 виходом 
 
PORTD=0b0000000; 
DDRD=0b01111111; //Робимо ніжки PB0-PB6 виходами  
 
TCCR0=0x03; //встановлюємо переддільник таймера 
TCNT0=0x64; // число, з якого таймер починає рахувати до 255 
 
TIMSK=0x01; // переривання по переповненню таймера 0 
#asm("sei") //дозволяємо переривання 
 
while (1)  
{ 
out(z++); // виводимо значення змінної z і збільшуємо її на 1 
delay_ms(1000); //Робимо затримку в 40 мілісекунд, це 25 висновків за секунду 
} 
} 

У наступній статті я розповім, як до мікроконтролера підключити lcd дисплей.

Комментарии - (4)

  • Сергей говорит:
    Все примеры замечательно работают как на симуляторе, так и в железе. Вопрос, как дописать программу динамического вывода символов для 4-х разрядного индикатора и с повторяющимся циклом. Очень нужно. Заранее спасибо.
  • Admin говорит:
    Все делается по аналогии. Узнать сколько тысяч сотен десятков и единиц, и вывести их.
  • dethdron говорит:
    Спасибо получилось, а как привязать к кнопкам ? делаю программу при нажатии на кнопку-1 светодиод-1 горит при отпускании гаснет,при нажатии на кнопку-2 светодиод-2 горит при отпускании гаснет. Со светодиодами работает а как сделать так же что бы на индикаторе нажал один горит 1 нажал два горит 2? изначально у меня так #include <mega8.h> void main (void) { DDRD = 0x00; //порт D - вход PORTD = 0xFF; //подключаем нагрузочный резистор DDRB = 0xFF; //порт B - выход PORTB = 0x00; //устанавливаем 0 на выходе while(1) { PORTB = ~PIND; //~ знак поразрядного инвертирования } }
    • Admin говорит:
      Нужно в цикл While добавить проверку на нажатия кнопки, если нажата то выводить номер нажатой кнопки, например так
      while (1)
      {
      if (PIND.0==0) out(1);
      if (PIND.1==0) out(2);
      delay_ms(1000); //Делаем задержку в 40 милисекунд, это 25 выводов за секунду
      }
      }

Добавить комментарий

Для отправки комментария вы должны авторизоваться.