Итак, для этого мы используем таймер, который настроены на частоту тактирования 1Гц. ЖК-дисплей пару кнопок для настройки времени кнопку для выбора режима (часы/будильник), кнопку сброса времени и кнопку отключения сирены. Кнопка ALR/Clock служит для переключения режима настройки часов, либо настройки будильника. В качестве индикатора срабатывания будильника мы используем светодиод.
Собираем схемку:
А вот сам исходник: #include <mega8.h> // Alphanumeric LCD Module functions #asm .equ __lcd_port=0x12 ;PORTD #endasm #include <lcd.h> #include <delay.h>
unsigned char sek; unsigned char min; unsigned char hour; // стандартные значения будильника unsigned char hour_b=12; unsigned char min_b=0; // Timer 1 output compare A interrupt service routine interrupt [TIM1_COMPA] void timer1_compa_isr(void) { // Place your code here TCNT1H=0; TCNT1L=0; sek++; } // Declare your global variables here void main(void) { PORTB=0xFF; DDRB=0x00;
PORTC=0x00; DDRC=0x7F;
// Timer/Counter 1 initialization // Clock source: System Clock // Clock value: 7,813 kHz // Mode: Normal top=FFFFh // OC1A output: Discon. // OC1B output: Discon. // Noise Canceler: Off // Input Capture on Falling Edge // Timer 1 Overflow Interrupt: Off // Input Capture Interrupt: Off // Compare A Match Interrupt: On // Compare B Match Interrupt: Off TCCR1A=0x00; TCCR1B=0x05; TCNT1H=0x00; TCNT1L=0x00; ICR1H=0x00; ICR1L=0x00; OCR1AH=0x1E; OCR1AL=0x85; OCR1BH=0x00; OCR1BL=0x00; // Timer(s)/Counter(s) Interrupt(s) initialization TIMSK=0x10;
// LCD module initialization lcd_init(16); // Global enable interrupts #asm("sei") while (1) { // Place your code here // Кнопки if (PINB.5==0) // режим Alarm/clock { if (PINB.0==0) // если нажата первая кнопка { delay_ms(250); // задержка 1/4 сек. (для удобства) выбора hour++; } if (PINB.1==0) // если нажата вторая кнопка { delay_ms(250); // задержка 1/4 сек. (для удобства) выбора hour--; } if (PINB.2==0) // если нажата третья кнопка { delay_ms(250); // задержка 1/4 сек. (для удобства) выбора min++; } if (PINB.3==0) // если нажата четвертая кнопка { delay_ms(250); // задержка 1/4 сек. (для удобства) выбора min--; } if (PINB.4==0) // Reset { hour=0; min=0; sek=0; } if (PINB.6==0) // Stop ALARM (светодиод будильника затушить) { PORTC.0=0; } ///// Условия часов. if(sek==60) // если сек = 60 { min++; // добавляем 1 к переменной "минута" sek=0; // зануляем переменную "секунда" } if(min==60) // если мин = 60 { hour++; // добавляем 1 к переменной "час" min=0; // зануляем переменную "минута" } if (hour==24) // так как у нас часы имеют 24 часовый формат { // при достыжении 24 часов, онулируем все переменные. hour=0; min=0; sek=0; } // защита переполнения переменной, она нужна для того чтобы в моментах когда время не переходило в минус. if (hour==255) hour=0; if (min==255) min=0; if (hour==hour_b && min==min_b) // срабатывание будильника PORTC.0=1; // будильник будет работать только одну минуту, когда время и минуты совпадают. lcd_gotoxy(4,0); lcd_putchar(hour/10+0x30); lcd_putchar(hour%10+0x30); lcd_putchar(':'); lcd_putchar(min/10+0x30); lcd_putchar(min%10+0x30); lcd_putchar(':'); lcd_putchar(sek/10+0x30); lcd_putchar(sek%10+0x30); } else { if (PINB.0==0) { delay_ms(250); // задержка 1/4 сек. (для удобства) выбора hour_b++; } if (PINB.1==0) { delay_ms(250); // задержка 1/4 сек. (для удобства) выбора hour_b--; } if (PINB.2==0) { delay_ms(250); // задержка 1/4 сек. (для удобства) выбора min_b++; } if (PINB.3==0) { delay_ms(250); // задержка 1/4 сек. (для удобства) выбора min_b--; } // защита переполнения переменной, она нужна для того чтобы в моментах когда время не переходило в минус. if (hour_b==255) hour=0; if (min_b==255) min=0; lcd_gotoxy(4,0); // выводим посередине, если хотите вывести в начале дисплея тогда нужно выставить lcd_gotoxy(0,0); lcd_putchar('A'); lcd_putchar('l'); lcd_putchar('.'); lcd_putchar(' '); lcd_putchar(hour_b/10+0x30); lcd_putchar(hour_b%10+0x30); lcd_putchar(':'); lcd_putchar(min_b/10+0x30); lcd_putchar(min_b%10+0x30); } }; }
Файлы по проекту находятся в разделе файлы. Все вопросы на форум :)
|