| |||||||
Опубликовано 2013-05-23 09:25:41 автором MRS Електронне реле часу на мікроконтролеріУ попередніх уроках я розповідав , як до микроконтроллерa підключити семисегментний індикатор , кнопки і як управляти навантаженням постійного і змінного струму . Давайте все це матеріалізуємо в який-небудь корисний пристрій , наприклад часовий таймер. Таймер повинен відраховувати якийсь час і після закінчення включати або відключати корисне навантаження , наприклад світлодіод. Скажу чесно , збирав я його на прохання друга , йому потрібно було включати глушилку вай фай . Схема електронного реле часу виглядає так # include <mega8.h> # include <delay.h> struct Stime { unsigned char second ; unsigned char minute ; unsigned char hour ; } Time [ 3 ] ; void TimerEvent () { PORTB.4 = 1 ; } unsigned char Zminute = 0 , Zhour = 0 ; unsigned char chislo [ 4 ] ; // визначаємо масив з двох елементів типу char беззнаковий ( unsigned ) unsigned char numder [] = // визначаємо масив , в якому індексом відповідатимуть біти на порті D { 0b11111100 , // цифра 0 0b01100000 , // цифра 1 0b11011010 , // цифра 2 0b11110010 , // цифра 3 0b01100110 , // цифра 4 0b10110110 , // цифра 5 0b10111110 , // цифра 6 0b11100000 , // цифра 7 0b11111110 , // цифра 8 0b11110110 , // цифра 9 } ; void out ( unsigned char hour , unsigned char minute ) { /* спочатку нам потрібно визначити , зі скількох десятків і одиниць складається виведене число. Наприклад , передали ми "45" , нам треба його розкласти на 4 і 5 , щоб на перший розряд семісегментніка вивести цифру 4 , а на другий - 5 */ chislo [ 1 ] = hour % 10 ; // оператор % дає залишок від цілочисельного ділення , наприклад 34 % 10 буде 4 chislo [ 0 ] = hour/10 ; // Дізнаємося , скільки десятків в числі chislo [ 3 ] = minute % 10 ; chislo [ 2 ] = minute/10 ; } unsigned char i = 0 ; // Змінна для визначення , на який розряд семисегментника виводити число // Переривання по переповненню timer0 interrupt [ TIM0_OVF ] void timer0_ovf_isr ( void ) { PORTD = numder [ chislo [ i ]] ; if ( i == 1 ) PORTD.0 = 1 ; else PORTD.0 = 0 ; // включаємо / вимикаємо точку PORTB = ( ( PORTB & 0b11110000 ) | ( ( ~ ( 1 << i )) & 0b00001111 )) ; // включаємо певний розряд семисегментника if ( + + i > 3 ) i = 0 ; } /* Переривання таймера2 викликається 1 раз на секунду , тому що таймер2 тактується від часового кварцу на 32768 герц і в таймері встановлено переддільник частоти 128 , це значить, що 128 тактів вважаються як один, тобто кварц в нас 32768 таймер в нас 8 бітний, максимальне число 255 ми обираємо переддільник 128 виходить 32768/128 = 255 , це значить, що за секунду змінна рахунку таймера ( TCNT2 ) дійде до 255 і таймер згенерує переривання по переповненню змінної */ unsigned char outMenu = 0 ; interrupt [ TIM2_OVF ] void timer2_ovf_isr ( void ) { if ( time [0]. second + + == 60 ) { time [0]. second = 0 ; if ( time [0]. minute + + == 60 ) { time [0]. minute = 0 ; if ( time [0]. hour + + == 24 ) { time [0]. hour = 0 ; } } out ( time [ outMenu ] . hour , time [ outMenu ] . minute ) ; if ( ( time [0]. minute == Zminute ) && ( time [0]. hour == Zhour )) TimerEvent (); // якщо хвилини і секунди рівні заданим викликаємо функцію TimerEvent } } void main ( void ) { PORTB = 0x00; DDRB = 0x1F ; PORTD = 0x00; DDRD = 0b11111111 ; TCCR0 = 0x00; TCNT0 = 0x00; // Timer / Counter 0 initialization // Clock source : System Clock // Clock value : 0,977 kHz TCCR0 = 0x04 ; TCNT0 = 0x00; // Timer / Counter 2 initialization // Clock source : TOSC1 pin // Clock value : PCK2/128 // Mode: Normal top = FFh // OC2 output : Disconnected ASSR = 0x08 ; TCCR2 = 0x05 ; TCNT2 = 0x00; OCR2 = 0x00; // Timer ( s ) / Counter ( s ) Interrupt ( s ) initialization TIMSK = 0x41 ; // Global enable interrupts # asm ( " sei " ) while ( 1 ) { if (! ( PINC & 0b00000001 ) && outMenu > 0) // перевіряємо чи натиснута кнопка +1 { if ( regim = true ) time [ outMenu ] . hour + + ; else time [ outMenu ] . minute + + ; } if (! ( PINC & 0b00000010 )) // перевіряємо чи натиснута кнопка 2 { if ( + + outMenu > 2 ) outMenu = 0 ; } if (! ( PINC & 0b00000100 ) && outMenu > 0) // перевіряємо чи натиснута кнопка 3 { if ( regim = true ) time [ outMenu ] . hour - ; else time [ outMenu ] . minute - ; } delay_ms ( 200 ) ; out ( time [ outMenu ] . hour , time [ outMenu ] . minute ) ; } ; } Комментарии - (5)
Добавить комментарийДля отправки комментария вы должны авторизоваться. |