Опубликовано 2013-05-23 09:25:41 автором MRS

Electronic time switch on the microcontroller


In previous lessons , I described how to connect the microcontroller seven-segment indicator , button and how to run a DC load and AC . Let all this materializing in any useful device, such as time taymer.Taymer should count for some time and after enable or disable payload , such svetodiod.Skazhu honestly , I collected at the request of his friend , he had to include glushylku wai fai . Diagram of the electronic timers looks skhema electronic relay vremeni
firmware code :
# include < mega8.h>
# include
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] ; / / define an array of two elements of type char is unsigned (unsigned)
unsigned char numder [] = / / define an array in which the index will match biti on port D
{
0b11111100, / / '0
0b01100000, / / number 1
0b11011010, / / number 2
0b11110010, / / number 3
0b01100110, / / number 4
0b10110110, / / number 5
0b10111110, / / number 6
0b11100000, / / number 7
0b11111110, / / figure 8
0b11110110, / / number 9
};
void out (unsigned char hour, unsigned char minute)
{
/ * first, we need to determine how many of the tens and units is outputted number .
For example, we passed "45" , we need to expand it to 4 and 5 to the first rank semisegmentnika
4 digit display , and the second - 5 * /
chislo [ 1 ] = hour% 10; / / % operator yields the remainder of the integer division , eg 34% of 10 is 4
chislo [ 0 ] = hour/10; / / Find out how many tens including

chislo [ 3 ] = minute% 10 ;
chislo [ 2 ] = minute/10;
}
unsigned char i = 0 ; / / Variable to determine at what rank semisegmentnika output by
/ / Overflow interrupt timer0
interrupt [TIM0_OVF] void timer0_ovf_isr (void)
{
PORTD = numder [chislo [i]];
if (i == 1 ) PORTD.0 = 1 ; else PORTD.0 = 0 ; / / enable / disable point
PORTB = ((PORTB & 0b11110000) | ((~ ( 1 << i)) & 0b00001111)); / / include certain rank semisegmentnika
if (+ + i> 3 ) i = 0 ;
}
/ * Interrupt taymera2 called 1/second because TIMER2 clocks from time to 32,768 Hertz quartz
and set the timer prescaler frequency 128 means that 128 is considered as one of measures toest
quartz in us 32768
We timer 8 bit maksimalnoe number 255
We choose predelitel 128
turns 32768/128 = 255 , this means that for an intrinsic schetayu second timer (TCNT2) reaches 255 and the timer interrupt zgeneriruet
overflow variable
* /
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 (); / / if the minutes and seconds are jobs call the 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) / / check if you pressed 1
{
if (regim = true) time [outMenu]. hour + +; else time [outMenu]. minute + +;
}
if (! (PINC & 0b00000010)) / / check if you pressed 2
{
if (+ + outMenu> 2 ) outMenu = 0 ;
}
if (! (PINC & 0b00000100) && outMenu> 0) / / check if you pressed 3
{
if (regim = true) time [outMenu]. hour -; else time [outMenu]. minute -;
}
delay_ms ( 200 );

out (time [outMenu]. hour, time [outMenu]. minute);
};

}
files to the project in the archive Timer.zip

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

  • Zanli23 говорит:
    Здравствуйте! Дайте пожалуйста код прошивки для этого таймера. Хочу собрать простое реле времени, примерно по такой схеме, но не могу найти ничего подходящего. Нужен реле периодического действия с выдержкой до 4 часов и работой 1 сек - 2 мин. Спасибо
    • AdminRu говорит:
      Добавил архив, возможно программу прийдется подкорректировать, так как финальная версия потерялась
  • Zanli23 говорит:
    Спасибо!
  • Zanli23 говорит:
    Не могу разобраться с кодом, когда прошиваю МК индикаторы поочередно начинают выводить нули. Помогите пожалуйста разобраться. P.S. Я недавно начал изучать мк )
  • AdminRu говорит:
    Индикатор по умолчанию просто выводит счет времени. Для того чтобы сегменты переключались быстрей нужно увеличить частоту таймера 0. Для этого уменьшаем предделитель таймера з TCCR0=0x04; на TCCR0=0x03;.
    Событие по совпадению времени вызывается а строке
    if ( (time[0].minute==Zminute) && (time[0].hour==Zhour) ) TimerEvent(); //если минуты и секунды равны заданым вызываем функцию TimerEvent
    попробуйте подставить вместо Zminute и Zhour константы. Например if ( (time[0].minute==1) && (time[0].hour==0) ) TimerEvent();. Дальше в функции TimerEvent() установите лог 1 на необходимой ножке мк например:
    void TimerEvent()
    {
    PORTB.4=1;
    }

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

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