|
| |||||||
|
Опубликовано 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)
Добавить комментарийДля отправки комментария вы должны авторизоваться. |
|||||||