никак не въеду:
таймер Т1 на тини2313. прерывание при совпадении дает мне счетчик времени.
использую флаг от прерывания для отсчета необходимых пауз. на паузе зависает.
unsigned char x=0;
unsigned char y=0;
unsigned char z=0;
unsigned char N=0; //***вариант первый
//флаг1 инвертируется каждое прерывание от таймера
//число N задаю по ходу программы дл отработки пауз
//разной длительности
void wait(void)
{
z=N; //назначаю кол-во прерываний N для отсчета
x=flag1; //начальное значение х
y=0; //вспомагательная переменная
if (y<z) //если y<z
{
while (x==flag1){}; //проверяю когда изменится flag1, т.е. произойдет прерывание
//пока флаг не изм. крутится пустой цикл
y=y+1; //как только flag1 изм., то инкремент y
}
else
{
N=0; //если y=z, то переход к следующей функции
};
}
//******** или вариант второй
void wait(void)
{
x=flag1;
y=0;
z=N;
m1:
if (y<z)
{ if (x==~flag1) {y=y+1;x=flag1;}
else {goto m1;};
};
}
//********третий вариант
void wait(void)
{
z=N; //назначаю кол-во прерываний N для отсчета
x=flag1; //начальное значение х
y=0;
if (y<z) //если y<z
{
while (x==flag1){}; //проверяю когда изменится flag1, т.е. произойдет прерывание
//пока флаг не изм. крутится пустой цикл
y=y+1; //как только flag1 изм., то инкремент y
}
else
{
// N=0; //если y=z, то переход к следующей функции
};
}
Добавлено (22.11.2010, 19:49)
---------------------------------------------
Code
/*****************************************************
This program was produced by the
CodeWizardAVR V2.04.9a Evaluation
Automatic Program Generator
© Copyright 1998-2010 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com
Project :
Version :
Date : 16.11.2010
Author : Freeware, for evaluation and non-commercial use only
Company :
Comments:
Chip type : ATtiny2313
AVR Core Clock frequency: 8,000000 MHz
Memory model : Tiny
External RAM size : 0
Data Stack size : 32
*****************************************************/
#include <stdio.h>
#include <TINY4313_BITS.h>
#include <tiny2313.h> // объявляем библиотека ввода/вывода
#include <delay.h> // объявляем библиотеку для задержки
#define digit1 PORTD.6 //анод первой цифры - единицы
#define digit2 PORTD.5 //анод второй цифры - десятки
#define digit3 PORTA.0 //анод вспомагателного индикатора
#define buzer PORTD.4 //пищалка
#define out0volt PORTD.3 //отключения напряжения от электродов
#define rele_napravlen PORTD.1 //реле направления напряжения на электродах
flash char digits[] = { //создаём массив с цифрами
0x60, //0
0xF9, //1
0xA4, //2
0xB0, //3
0x39, //4
0x32, //5
0x22, //6
0xF8, //7
0x20, //8
0x30, //9
0b11111101, //знак минуса
0b11111111 //пустота
};
char digit_out[3], cur_dig; //переменные для работы с LED
unsigned int indication; //переменная для хранения выводимого на LED числа
unsigned char tmp=0; //переменная для счета числа прерываний Т1
bit flag0=0; //переменные для контроля счета событий таймера Т0
// инвертируется 122 раза в сек
bit flag1=0; //переменные для контроля счета событий таймера Т1
unsigned char x=0; //перем вспомогательная
unsigned char time=0; //перем для счета минут
unsigned char y=0; //перем вспомогательная
unsigned int z=0; //перем вспомогательная
unsigned int N=0; //перем вспомогательная
bit x5=0; //перем вспомогательная
//*****************************************************
void wait(void)
{
x=flag0;
y=0;
z=N;
//m1:
if (y<z) //если y<z
{ if (x==~flag0) //если флаг поменялся
{y=y+1;x=flag0;} //инкремент y, х готовим к смене флага
else {};
};
}
void stop(void)
{
TCCR1B=0x00; //остановка таймера Т1
time=30; // показания индикатора после остановки Т1
out0volt=0; //откл напряжения выхода
buzer=0; //сигнал вкл
N=61; //количество циклов для паузы в 0,5сек
wait(); //отработка паузы
buzer=1; //сигнал откл
}
void recoding(void) //функция для перекодировки из hex в dec
{ if (indication<1000) //начинаем преобразование если число < 1000 так как
{ //3-разрядный LED
digit_out[0]=indication%10; //Делим на 10 остаток в масив 1-разряд
indication=indication/10; //Оставляем 2 разряда
digit_out[1]=indication%10; //Делим на 10 остаток в масив 2-разряд
digit_out[2]=indication/10; //Делим на 10 целое число в масив 3-разряд
}
}
void counter(void) //ф-ция счетчика для числа, выводимого на индикатор
{
if (tmp>=2) //если счет прерываний достиг 240(для отладки 2 вместо 240)
{time=tmp/2; // то это 1 минута (для отладки 2 вместо 240)
x5=time/5; //выделяю периоды по 5 минут
if (time==30) //если время достигло 30мин
{stop();} //то выполн ф-цию СТОП
else //если время еще не 30мин
{if (x5==1) //проверка - если прошло 5мин то вкл бузер
{buzer=0;
x5=0;
N=30;
wait(); //вот здесь нужна пауза в 0,25сек[/color][/b]
buzer=1;}
else {}; //и обнуляю х5
};
}
else
{
};
}
void start(void) //описываю ф-цию start
{
indication=0; //число минут в индикаторе обнулить
TCCR1B=0x00; //остановка таймера Т1
TCCR1B=0x0D; //запуск Т1 делитель 7813Гц и режим прерыв при совпадении с OCR1А
}
//таймер 0
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
flag0=~flag0; //инвертирую каждое прерывание флаг0
PORTB=0xFF; //чтобы предотвратить эффект “тени” на соседних индикаторах
switch (cur_dig){
case 0:{digit3=1; digit1=0; break;}; //подаём питание на разряд 3
case 1:{digit1=1; digit2=0; break;}; //подаём питание на разряд 2
case 2:{digit2=1; digit3=0; break;}; //подаём питание на разряд 1
} //ОА на digit->0, OK->1
PORTB=digits[digit_out[cur_dig]]; //выводим с каждым срабатыванием таймера число с
//мaссива в порт В, но не для всех разрядов сразу
cur_dig++; //с каждым срабатыванием таймера, увеличиваем
//переменную cur_dig на 1
if(cur_dig==3) cur_dig=0; //если cur_dig = 3 обнуляем
}
// Timer1 output compare A interrupt service routine
//прерывание каждые 0,2с.
interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
tmp=tmp+1;
flag1=~flag1; //инвертирую каждое прерывание флаг
// buzer=flag1; //вывожу на вывод бузера для контроля срабатывания прерывания
counter();
indication=time; //посчитанное отправл на индикацию
recoding(); //декодирую ед и десятки
}
void main(void)
{
// Crystal Oscillator division factor: 1
#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif
PORTA=0x00;
DDRA=0x00;
PORTB=0xFF;
DDRB=0xFF;
PORTD=0x7B;
DDRD=0x7A;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 31,250 kHz
// Mode: Normal top=0xFF
// OC0A output: Disconnected
// OC0B output: Disconnected
TCCR0A=0x00;
TCCR0B=0x04;
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer1 Stopped
// Mode: CTC top=OCR1A
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: On
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x08;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x06; //период прерываний 200мс
OCR1AL=0x59;
OCR1BH=0x00;
OCR1BL=0x00;
// INT0: On
// INT0 Mode: Low level
GIMSK=0x40;
MCUCR=0x00;
EIFR=0x40;
TIMSK=0x42;
USICR=0x00;
ACSR=0x80;
// Global enable interrupts
#asm("sei")
start();
}