В начальном состоянии после сброса схема переводится в Power Doun .
На кнопках висят прерывания по изменению - для пробуждения.
При нажати на кнопку начинает мигать соответствующий светодиод , после 20 сек если никаких действий не было все отключается и переходит в
Power Doun .
На макете алгоритм работает не правильно . При нажатии на кнопку PB3 загораются 2 светодиода при отпускании тухнут
на PB2 всегда присутствует низкий уровень - ходя должен быть высокий- PULL UP Прошу помощи
#include <avr/io.h>
#include <avr/interrupt.h>
/************************************/
/*настройка таймера*/
void SetupTIMER0 (void);
/***************************/
/*назначение портов*/
#define led1 PORTB0
#define led2 PORTB1
#define key1 PORTB2
#define key2 PORTB3
#define TIMEON 20
#define DL 200
/*************************************/
/
#define BIT(y) (1 << (y))
#define CHECKBIT(x,y ) (x & (y) ) /* проверка бита y в байте x*/
/**************************************/
#ifndef SETBIT
#define SETBIT(x) (1 << (x))
#endif
/**************************************/
#ifndef CLRBIT
#define CLRBIT(x) (~SETBIT(x))
#endif
/******************************/
void InitPortB(void);
volatile unsigned char timer=0,rt=0;
volatile unsigned char flag=0;
/*******************************/
ISR(TIMER0_OVF_vect)
{
/*1 TIK = 0.000128 C 1 C = 7812*/
TCNT0 = 65536-(65536-7812); /*НОВЫЙ ОТСЧЕТ*/
/****************************************/
rt=~rt;
/*******************************************/
if(CHECKBIT(flag,BIT(0))) {
/*=1 мигание*/
if(!rt) PORTB&=~(1);
else PORTB|=1;
}
else PORTB&=~(1);
if(CHECKBIT(flag,BIT(1))) {
/*=1 мигание*/
if(!rt) PORTB&=~(2);
else PORTB|=2;
}
else PORTB&=~(1);
if (timer) timer--;
else{
timer=TIMEON;
/*остановили таймер*/
PRR|=SETBIT(PRTIM0); // "выключили таймер счетчик
asm volatile("sleep");
}
timer=TIMEON;
}
/************************************/
/************************************/
/*прерывание по смене уровня*/
ISR(PCINT0_vect)
{
uint16_t dt;
/*включили таймер счетчик*/
PRR&=CLRBIT(PRTIM0);
for(dt=0;dt<DL;dt++){ asm volatile( "nop" ); } //задержка для исключения дребезга
if(!PORTB2) {
if(CHECKBIT(flag,BIT(0))) {
/*0 bit==1*/
flag&=~(SETBIT(BIT(0)));
}
else{
flag|=SETBIT(BIT(0));
};
}
/*****************************************************/
if(!PORTB3) {
if(CHECKBIT(flag,BIT(1))) {
/*0 bit==1*/
flag&=~(SETBIT(BIT(1)));
}
else{
flag|=SETBIT(BIT(1));
};
}
}
/***************************************/
/*Пример функции на асемблере*/
//The following code example shows how to turn off the WDT.
#define turn_off_the_WDT() \
asm volatile (\
"cli" "\n\t"\
"wdr" "\n\t"\
"in r16, RSTFLR" "\n\t"\
"andi r16, ~(1<<WDRF)" "\n\t"\
"out RSTFLR, r16" "\n\t"\
"ldi r16, 0xD8" "\n\t"\
"out CCP, r16" "\n\t"\
"ldi r16, (0<<WDE)" "\n\t"\
"out WDTCSR, r16" "\n\t"\
"sei" "\n\t"\
);
/*********************************************************/
void SetIdle(void)
{
SMCR&=CLRBIT(SM2)&CLRBIT(SM1)&CLRBIT(SM0);
//The SE bit must be written to logic one to make the MCU enter the sleep mode when the SLEEP
//instruction is executed.
asm volatile("sleep");
}
/*****************************************************************/
void SetPowerDoun(void)
{
SMCR|=SETBIT(SM1);
SMCR&=(CLRBIT(SM0)&CLRBIT(SM2));
//The SE bit must be written to logic one to make the MCU enter the sleep mode when the SLEEP
//instruction is executed.
asm volatile("sleep");
}
/*****************************************************************/
int main(void)
{ timer=TIMEON;
InitPortB();
SetupTIMER0();
sei();
PRR|=SETBIT(PRTIM0); // "выключили таймер счетчик
SetPowerDoun();
while(1)
{
//TODO:: Please write your application code
}
}
/**********************************/
/*инициализация выводов*/
/**********************************/
void InitPortB(void)
{
// Input/Output Ports initialization
// Port B initialization
// Func5=In Func4=In Func3=In Func2=In Func1=Out Func0=Out
// State5=T State4=T State3=P State2=P State1=0 State0=0
cli();
PORTB=0x0C;
DDRB=0x03;
/*pull ap resistor PB3,PB2*/
PUEB=0x0C;
//PRR – Power Reduction Register
//установили бит Bit 1 – PRADC: Power Reduction ADC
//Writing a logic one to this bit shuts down the ADC.
//Bit 0 – PRTIM0: Power Reduction Timer/Counter0
//Writing a logic one to this bit shuts down the Timer/Counter0 module.
PRR=SETBIT(PRADC);
/*запретили прерыввания по инт*/
EIMSK=0;
/*разщрешили маску по изменению по входу*/
PCICR=SETBIT(PCIE0);
/*определили кокретные выводы с которых будет обработка прерываний по изменению состояния*/
PCMSK=SETBIT(PCINT3)|SETBIT(PCINT2);
// Analog Comparator initialization
// Analog Comparator: Off
ACSR=SETBIT(ACD);
ADCSRB=0x00;
}
/**********************************/
/**********************************/
void SetupTIMER0 (void)
{
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 7,813 kHz
// Mode: Normal top=FFh
// OC0A output: Disconnected
// OC0B output: Disconnected
TCCR0A=0x00;
TCCR0B=0x05;
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;
// External Interrupt(s) initialization
// INT0: Off
// Interrupt on any change on pins PCINT0-5: On
CLKMSR=0x00; //Calibrated Internal 8 MHzOscillator
CLKPSR=0x00; //Clock Division Factor 1
// Timer/Counter 0 Interrupt(s) initialization
TIMSK0=SETBIT(TOIE0);
}
/**********************************/

