Я предлагаю на практике освоить работу с основными возможностями таймера. Итак, начнем! Давайте сделаем таймер в которого максимальное значение было 24 часа 59 мин. 59 сек :) Возьмем наш таймер и просто будем не инкрементировать(++) переменную, а декрементировать (--), для того чтобы таймер считал время назад. А в конце когда будет 00-00-00 на определенный порт выводилась лог. 1, в данном случае я использую светодиод.
Сделаем кнопки установки времени, START, STOP и RESET. Но RESET здесь необычный, он не выставляет все на 0 ибо при 00-00-00 срабатывает светодиод, так что RESET устанавливает время 00-00-03. Параметр сек., можно установить в строке unsigned char sek=3; где вместо 3 ставим любое другое значение. Главные регистры которые мы ипользовали:
TCCR1B&=0b11111000; // останавливаем таймер TCCR1B|=0b00000101; // запускаем таймер Итак предлагаю схему:
А вот и сам код. #include <mega8.h>
// Alphanumeric LCD Module functions #asm .equ __lcd_port=0x12 ;PORTD #endasm #include <lcd.h> #include <delay.h> // подключаем библиотеку задержки unsigned char sek=3; // переменная сек. задаем стандартно 3 чтобы не зажечь светодиод сразу. unsigned char min; // пересенная мин. unsigned char hour; // переменная часов // Timer 1 output compare A interrupt service routine interrupt [TIM1_COMPA] void timer1_compa_isr(void) // таймер выставлен на частоту 1 Гц { // Place your code here TCNT1H=0; TCNT1L=0; sek--; // декрементируем переменную sek }
// Declare your global variables here
void main(void) { PORTD=0x00; // порт как выход DDRD=0xFF;
PORTB=0xFF; // порт как выход DDRB=0x00;
PORTC=0xFF; // выставляем порт С на все кнопки. DDRC=0x00;
// 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") TCCR1B&=0b11111000; // останавливаем таймер while (1) { // роботаем с кнопками if (PINB.0==0) // если нажата первая кнопка { delay_ms(250); // задержка 1/4 сек. (для удобства) выбора min++; // к значению минуты добавляем еденицу } if (PINB.1==0) // если нажата вторая кнопка { delay_ms(250); // задержка 1/4 сек. (для удобства) выбора min--; // от значения минуты вычитаем еденицу } if (PINB.2==0) // если нажата третья кнопка { delay_ms(250); // задержка 1/4 сек. (для удобства) выбора hour++; // к значению час добавляем еденицу } if (PINB.3==0) // если нажата четвертая кнопка { delay_ms(250); // задержка 1/4 сек. (для удобства) выбора hour--; // от значения часов вычитаем еденицу } // главное условие // мы его используем для того чтобы не можно было ввести 99 часов или 99 мин и 99 сек. :) по необходимости это можно убрать. if (hour==25) hour=0; if (min==59) min=0; if (sek==59) sek=0; if (PINB.4==0) // если нажата пятая кнопка { TCCR1B|=0b00000101; // запускаем таймер } if (PINC.0==0) { TCCR1B&=0b11111000; // останавливаем таймер по необходимости } if (PINC.1==0) // если нажата шестая кнопка { delay_ms(250); // задержка 1/4 сек. (для удобства) выбора sek++; // sek +1 } if (PINC.2==0) { delay_ms(250); // задержка 1/4 сек. (для удобства) выбора sek--; // sek -1 } if (PINC.3==0) { min=0; hour=0; sek=1; // устанавливаем 1 секунду, для того чтобы порт не "зажегся" TCCR1B&=0b11111000; // останавливаем таймер PORTD.3=0; } ///// Условия таймера. if(sek==255) // сравнение переменной sek, почему 255 - потомучто переменная char когда у него значение 0 и мы вычитаем еще 1 { // то пулучаем 255. min--; sek=59; } if(min== 255) // сравнение переменной min { min=0; sek=59; hour--; } if(hour== 0) // { min=59; // зануляем переменную "hour" } if ( min==0 && sek==0 && hour==0) // если таймер срабатывает { PORTD.3=1; // включаем светодиод TCCR1B&=0b11111000; // останавливаем таймер }
// выводим переменные lcd_gotoxy(4,0); // выводим посередине, если хотите вывести в начале дисплея тогда нужно выставить lcd_gotoxy(0,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); }; }
Прошивка и схема в Proteus, находиться в разделе файлы. Все вопросы на форум:)
Проект не доделан, есть ошибки.
|