Сб июн 09, 2018 20:10:41
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
unsigned char bin[64] = { //костыль для управления портом B
0b00000000,
0b00100000,
0b00010000,
0b00110000,
0b00001000,
0b00101000,
0b00011000,
0b00111000,
0b00000100,
0b00100100,
0b00010100,
0b00110100,
0b00001100,
0b00101100,
0b00011100,
0b00111100,
0b00000010,
0b00100010,
0b00010010,
0b00110010,
0b00001010,
0b00101010,
0b00011010,
0b00111010,
0b00000110,
0b00100110,
0b00010110,
0b00110110,
0b00001110,
0b00101110,
0b00011110,
0b00111110,
0b00000001,
0b00100001,
0b00010001,
0b00110001,
0b00001001,
0b00101001,
0b00011001,
0b00111001,
0b00000101,
0b00100101,
0b00010101,
0b00110101,
0b00001101,
0b00101101,
0b00011101,
0b00111101,
0b00000011,
0b00100011,
0b00010011,
0b00110011,
0b00001011,
0b00101011,
0b00011011,
0b00111011,
0b00000111,
0b00100111,
0b00010111,
0b00110111,
0b00001111,
0b00101111,
0b00011111,
0b00111111,
};
unsigned char hour, min, sec, fix;
ISR(TIMER2_COMP_vect) // Должно ли это прерывание будить???
{
sleep_disable(); // Запрещаем сон
sec++;
fix++;
if (sec == 60)
{
sec = 0;
min ++;
};
if (min == 60)
{
min = 0;
hour ++;
};
if (hour > 23)
{
hour = 0;
};
if (fix > 169)
{
TCNT2++;
fix = 0;
};
if((PIND & (1<<PD3))) // проверяем на наличие внешнего питания
{
sleep_enable(); // разрешаем сон
Offall(); // отключаем отображение
sleep_mode(); // Засыпаем (по описанию не понял разницы между sleep_mode(); и sleep_cpu(); но результат одинаковый.
}
}
void Offall(void){
PORTB = 0x00;
PORTD &= 0x1F;
}
void delayws(char del) // задержка, но без отключения отображения.
{
for(int i = 0; i< del; i++){
ShowTime(hour, min, sec);
}
}
void ShowTime(char h, char m, char s)
{
PORTB = bin[h];
PORTD |= (1 <<PD5);
_delay_us(1300);
PORTD &= ~(1 <<PD5);
PORTB = bin[m];
PORTD |= (1 <<PD6);
_delay_us(1300);
PORTD &= ~(1 <<PD6);
PORTB = bin[s];
PORTD |= (1 <<PD7);
_delay_us(1300);
PORTD &= ~(1 <<PD7);
}
int main(void)
{
//SetUp
DDRB = 0b11111111;
DDRD = 0b11100000;
PORTD |= (1 <<PD3);
DDRC|= (0 << PC2)|(0<<PC3);
PORTC |= (1 << PC2)|(1<<PC3);
asm ("cli");
//Timer 2
ASSR |= (1 << AS2); // Разрешаем тактирование таймера Т2 от кварца 32768 (асинхронный режим)
while (ASSR != (0b00001000)) // Ожидаем разрешения записи
{
asm ("nop");
}
TCCR2 |= (1<<CS21) | (1<<CS22) | (1<<WGM21); // Тактирование: 32768 делим на предделитель (256) = 128. Сброс по совпадению.
OCR2 = 127; // В регистр сравнения заносим 127
TIMSK |= (1<<OCIE2); // Разрешаем прерывание по совпадению T2
TIFR = 0; // Сброс флагов.
set_sleep_mode(SLEEP_MODE_PWR_SAVE); // Режим сна
sleep_enable(); // Разрешаем сон
asm ("sei");
while(1){
if((PINC & (1<<PC2)) == 0){ // Кнопка минут
delayws(50);
while((PINC & (1<<PC2)) == 0){
delayws(1);
}
min++;
if (min > 59) min = 0;
}
if((PINC & (1<<PC3)) == 0){ // Кнопка часов
delayws(50);
while((PINC & (1<<PC3)) == 0){
delayws(1);
}
hour++;
if (hour > 23) hour = 0;
}
ShowTime(hour, min, sec); // Вывод времени
}
return 0;
}
Сб июн 09, 2018 20:17:22
Сб июн 09, 2018 20:32:50