Статус: устройство готово, осталось в коробку затолкать.
Цель проекта: отключение (или включение) нагрузки через заданное количество минут.
Попросил меня знакомый:
Олег, не знаешь где можно найти таймер выключения электроприборов работающих от 12В? На 220 то полно, но я хочу автоматизировать свой будущий "астрограф" чтобы сам все снимал и выключался.
Задача примитивная, к тому же всё под рукой. Блок-схема примерно такая:
Дальше монтажка, провода. Обожаемые ныне чип-резисторы и конденсаторы (по наличию). Мелко, дёшево и наловчившись очень удобно.
Самое противное в этом проекте - 3х8-сегментный индикатор. Для начала я не нашёл цоколёвку на то, что было в наличии, так что "прозвонил" его, определив где общий. Потом, подавая +5В через резистор 430 Ом нашёл, с помощью жены-красавицы, какая ножка за какой сегмент и какую цифру отвечает.
Программа тоже, сложная только касательно индикатора, всё остальное примитивно. Состоит из трёх частей:
- основной цикл опрашивает кнопки. Если кнопка "минус" нажата, уменьшает таймер. Если "плюс" нажат, соответственно, увеличивает. Дальше задержка 50 мс и всё заново. Таким образом можно достаточно шустро набрать нужное число. По уму надо сделать как в клавиатуре, время до первого повтора сделать больше, к примеру, ~200 мс. Но задача не предусматривает установки числа "с точностью до минуты", поэтому оставил как есть, 20 цифр в секунду;
- таймер ежесекундного отсчёта. Уменьшает количество секунд в изначальном счётчике на 60 секунд, если 0, уменьшает счётчик минут. При наступлении 0 минут переключает реле.
- таймер динамической регенерации экрана. Раз в запуск показывает первую, вторую, третью цифру экрана. Запускается достаточно часто для того, чтобы цифры казались постоянно горящими.
/***************************************************** This program was produced by the CodeWizardAVR V2.05.0 Professional Automatic Program Generator © Copyright 1998-2010 Pavel Haiduc, HP InfoTech s.r.l. http://www.hpinfotech.com
Project : TIMER Version : Date : 06.04.2011 Author : Company : Comments:
Chip type : ATmega8 Program type : Application AVR Core Clock frequency: 16,000000 MHz Memory model : Small External RAM size : 0 Data Stack size : 256 *****************************************************/
#include <mega8.h> #include <delay.h> //#include <stdio.h>
// Declare your global variables here int digit = 60; char seconds = 60; char display[4];
void number(char no, char digit) { switch (digit) { case 0: PORTC = 0; PORTD = 0x14; //c0, c1, c2, c3, d1, d3 //d2, d4 break; case 1: PORTC = 0xf; PORTD = 0x14; break; case 2: PORTC = 8; PORTD = 0x18; break; case 3: PORTC = 9; PORTD = 0x10; break; case 4: PORTC = 7; PORTD = 0x10; break; case 5: PORTC = 1; PORTD = 0x12; break; case 6: PORTC = 0; PORTD = 0x12; break; case 7: PORTC = 0xb; PORTD = 0x14; break; case 8: PORTC = 0; PORTD = 0x10; break; case 9: PORTC = 1; PORTD = 0x10; break; } switch (no) { case 0: PORTB.0 = 1; PORTB.1 = 0; PORTB.2 = 0; break; case 1: PORTB.0 = 0; PORTB.1 = 1; PORTB.2 = 0; break; case 2: PORTB.0 = 0; PORTB.1 = 0; PORTB.2 = 1; break; } }
void numbers(int number) { display[0] = number / 100; number -= display[0] * 100; display[1] = number / 10; number -= display[1] * 10; display[2] = number; }
// Timer1 overflow interrupt service routine interrupt [TIM1_COMPA] void timer1_compa_isr(void) { // ежесекундно if (--seconds == 0) { seconds = 60; if (--digit == 0) { PORTB.3 = 0; } } /* numbers(digit++); if (digit == 1000) { digit = 0; } */ }
// Timer 0 overflow interrupt service routine interrupt [TIM0_OVF] void timer0_ovf_isr(void) { // Place your code here
if (++display[3] == 3) { display[3] = 0; } number(display[3], display[display[3]]);
}
void main(void) { // Declare your local variables here
// Input/Output Ports initialization // Port B initialization // Func7=In Func6=In Func5=In Func4=In Func3=Out Func2=Out Func1=Out Func0=Out // State7=T State6=T State5=P State4=P State3=0 State2=0 State1=0 State0=0 PORTB=0x30; DDRB=0x0f;
// Port C initialization // Func6=In Func5=In Func4=In Func3=Out Func2=Out Func1=Out Func0=Out // State6=T State5=T State4=T State3=0 State2=0 State1=0 State0=0 PORTC=0x00; DDRC=0x0F;
// Port D initialization // Func7=In Func6=In Func5=In Func4=Out Func3=Out Func2=Out Func1=Out Func0=In // State7=T State6=T State5=T State4=0 State3=0 State2=0 State1=0 State0=T PORTD=0x00; DDRD=0x1E;
// Timer/Counter 0 initialization // Clock source: System Clock // Clock value: 62,500 kHz TCCR0=0x04; TCNT0=0x00;
// Timer/Counter 1 initialization // Clock source: System Clock // Clock value: 15,625 kHz // Mode: CTC top=OCR1A // OC1A output: Discon. // OC1B output: Discon. // Noise Canceler: Off // Input Capture on Falling Edge // Timer1 Overflow Interrupt: On // Input Capture Interrupt: Off // Compare A Match Interrupt: Off // Compare B Match Interrupt: Off TCCR1A=0x00; TCCR1B=0x0D; TCNT1H=0x00; TCNT1L=0x00; ICR1H=0x00; ICR1L=0x00; OCR1AH=0x3D; OCR1AL=0x09; OCR1BH=0x00; OCR1BL=0x00;
// Timer/Counter 2 initialization // Clock source: System Clock // Clock value: Timer2 Stopped // Mode: Normal top=0xFF // OC2 output: Disconnected ASSR=0x00; TCCR2=0x00; TCNT2=0x00; OCR2=0x00;
// External Interrupt(s) initialization // INT0: Off // INT1: Off MCUCR=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization TIMSK=0x11;
// USART initialization // USART disabled UCSRB=0x00;
// Analog Comparator initialization // Analog Comparator: Off // Analog Comparator Input Capture by Timer/Counter 1: Off ACSR=0x80; SFIOR=0x00;
// ADC initialization // ADC disabled ADCSRA=0x00;
// SPI initialization // SPI disabled SPCR=0x00;
// TWI initialization // TWI disabled TWCR=0x00;
// Global enable interrupts #asm("sei")
PORTB.0 = 1; PORTB.1 = 1; PORTB.2 = 1;
PORTB.3 = 1;
while (1) { // Place your code here //number(0, PINB.4); //PORTB.3 = PINB.5; if (PINB.4 == 0) { digit--; } if (PINB.5 == 0) { digit++; } numbers(digit); delay_ms(50); } } |