Имеется схема PB0,PB1 - выходы включены на светодиоды PB2,PB3 входы включены на кнопки.
В начальном состоянии после сброса схема переводится в 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);
}
/**********************************/
Power Doun и обработка прерываний.
- Реклама
Re: Power Doun и обработка прерываний.
#pragma offtopic
Power Down
Power Down
Разница между теорией и практикой на практике гораздо больше, чем в теории.
- Aheir
- Модератор
- Сообщения: 4517
- Зарегистрирован: Пн апр 03, 2006 11:43:25
- Откуда: Санкт - Петербург
- Контактная информация:
Re: Power Doun и обработка прерываний.
Млин, ну скока раз говорить, что исходники вложением оформляются? Ну не первый же день здесь уже...
Камень какой? Не любые прерывания по изменению выводят камень из Power Down, смотрите внимательно, что используете...
Камень какой? Не любые прерывания по изменению выводят камень из Power Down, смотрите внимательно, что используете...
Оптимизм х (Опыт + Знания) = const
- alexx82
- Открыл глаза
- Сообщения: 64
- Зарегистрирован: Ср июл 06, 2011 19:11:44
- Откуда: В цветущих акациях город
- Контактная информация:
Re: Power Doun и обработка прерываний.
Похоже, наряду с "default-сити" пора вводить понятие "default-МК". И им однозначно будет ATTiny2313. А если судить по обращению к регистру PRR, в данном случае речь идет об ATTiny2313A. 
А теперь 2 вопроса:
1) Зачем дергать PRR? В Power-Down таймеры и так отключены.
2) Как реализован антидребезг кнопок?
PS. Выложите код по-человечески - в нынешнем виде читать нереально.
А теперь 2 вопроса:
1) Зачем дергать PRR? В Power-Down таймеры и так отключены.
2) Как реализован антидребезг кнопок?
PS. Выложите код по-человечески - в нынешнем виде читать нереально.

