Схема годинника на DS1302 в Proteus |
#asm // Асемблерна вставка ініціалізації підключення мікросхеми DS1302 до Atmega8 .equ __DS1302_port=0x15;//Подключаем DS1302 к PORTС(0x15-адреса регістра порта) .equ __DS1302_io=2 ;//Другий пін для io .equ __DS1302_sclk=1 ;//Перший пін для sclk .equ __DS1302_rst=0 ;//Нульовий пін для rst #endasm
#include <bcd.h> #include <mega8.h> #include <delay.h> #include <DS1302.h> #define DIGITS 6 // Кількість розрядів індикатора unsigned char chislo[DIGITS]; //масив чисел, що відповідають кожному розряду unsigned char numder[]= //масив, в якому індексу будут відповідати біти на порту D для кожної цифри { 0b00111111, //цифра 0 0b00000110, //цифра 1 0b01011011, //цифра 2 0b01001111, //цифра 3 0b01100110, //цифра 4 0b01101101, //цифра 5 0b01111101, //цифра 6 0b00000111, //цифра 7 0b01111111, //цифра 8 0b01101111, //цифра 9 0b00000000, //пусто }; unsigned char hour_1, minute_1;//години та хвилини для наведення unsigned char second, minute, hour, date, month, year;// змінні часу та дати bit Button_1_state, Button_2_state; unsigned short i=0; // змінна, що визначає номер розряду який виводиться unsigned short k, dp; // змінні для крапки //***************************************************************************** // преривання по переповненню timer0 interrupt [TIM0_OVF] void timer0_ovf_isr(void) { PORTB=0x3f; // погасимо індикатор if (i==2||i==4) dp=k;//виводимо крапку на 2 та 4 індикатор else dp=0; PORTD=((numder[ chislo[i]])|dp); // виведем поточне число PORTB=~(1<<i); // вмикаємо відповідний розряд індикатора if (i++>DIGITS) i=0; // якшо не дійшли до старшого розряду готуєм виведення наступного } // якшо дійшли до старшого розряду готуєм виведення нульового //***************************************************************************** void out_1(unsigned short num)//виведення першої пари знаків (для секунд) { chislo[0]=num%10; //одиниці секунд chislo[1]=num/10; // десятки k=(~k)&0b10000000;// крапка засвічується та гасне кожну секунду } void out_2(unsigned short num)//виведення другої пари знаків (для хвилин) { chislo[2]=num%10; //одиниці хвилин chislo[3]=num/10; // десятки } void out_3(unsigned short num)//виведення третьої пари знаків (для годин) { chislo[4]=num%10; //одиниці годин chislo[5]=num/10; // десятки } //**************************************************************************** void main(void) { //Порт В PORTB=0x00; DDRB=0b00111111; //PB0-3 виходи (розряди) //Порт С PORTC=0b00111111; //включимо підтягуючі резистори на PС0-5 DDRC=0b00000000; //PС0-3 входи (кнопки + DS1302) //Порт Д PORTD=0b0000000; DDRD=0b11111111; //PD0-PD6 виходи (сегменти) TCCR0=0x03; //встановлюємо подільник таймера 64 rtc_init(0,0,0);//Ініціалізація DS1302 // кожне перерив приблизно 2 мс rtc_set_date(13,01,15);//встановлюємо дату 13.01.15 TIMSK=0x01;// переривання по переповненню таймера 0 #asm("sei")// глобальний дозвіл перерывання
//*************************************************************************** while (1) //основний цикл { rtc_get_time(&hour,&minute,&second);//зчитуємо години, хвилини, секунди // у відповідні змінні out_1(second); //виводимо на індикатор секунди out_2(minute); //хвилини out_3(hour); // години while (PINC.3==0){ //Поки натиснена кнопка збільшення хвилин k=0x80;// крапки засвічуються minute++; // збільшуємо хвилини кожні 300мс в діапазоні 0-60 if(minute==60)minute=0; minute_1 = bin2bcd(minute);// перетворюємо двійкове число в двійково-десяткове out_2(minute);//виводимо на індикатор хвилини які наводимо delay_ms(300); Button_1_state = 1; } while (PINC.4==0){ //Поки натиснена кнопка збільшення годин k=0x80;// крапки засвічуються hour++; // збільшуємо години кожні 300мс в діапазоні 0-24 if(hour==24)hour=0; hour_1 = bin2bcd(hour); out_3(hour); //виводимо на індикатор delay_ms(300); Button_2_state = 1; } delay_ms(500); if (Button_1_state && PINC.3){// Якщо кнопка наведення хвилин була натиснена і її тільки що відпустили ds1302_write(0b10000010, minute_1);//Записуємо нове виставлене значення хвилин в 1302 ds1302_write(0b10000000, 0);//Скидаємо секунди в 0 в 1302 Button_1_state = 0;// скидаємо фіксатор } if (Button_2_state && PINC.4){// Якщо кнопка наведення годин була натиснена і її тільки що відпустили ds1302_write(0b10000100, hour_1);//Записуємо нове виставлене значення годин в 1302 Button_2_state = 0; } while (PINC.5==0){ // Поки кнопка дати натиснена k=0;// розділові крапки засвічуються rtc_get_date(&date, &month, &year); // зчитується дата out_1(year); //виводимо на індикатор рік out_2(month); //місяць out_3(date); //число delay_ms(500); } } }
Sourse_file (Proteus in folder EXE)
Немає коментарів :
Дописати коментар