Используются внешние прерывания для определения перехода фазы через ноль.
За его обработку у меня отвечает INT0
Спойлер
Код: Выделить всё
//настройка внешнего прерывния INT0
void int0_init( void )
{
//настраиваем на срабатывание INT0 по переднему фронту
MCUCR |= (1<<ISC01)|(0<<ISC00);
//разрешаем внешнее прерывание INT0
En_INT0
}
ISR(INT0_vect)
{
int i=100;
int tempMS=(value+1);
for (;;)
{
i--;
_delay_us(10);
if (i<=tempMS)
{
break;
}
}
int k;
for(k=0; k<5; k++)
{
PORTB |= (1<<1);
_delay_us(2);
PORTB &= ~(1<<1);
_delay_us(2);
}
}Спойлер
Код: Выделить всё
void init_io()
{
//порт, к которому подкл. сегменты
PORTA = 0xff;
DDRA = 0xff;
//порт, к которому подкл. катод
DDRB |=(1<<0)|(1<<1)|(1<<2);
PORTB =0x00;
//инициализация таймера Т0
TIMSK = (1<<TOIE0);
TCCR0B = (1<<CS02)|(0<<CS01)|(1<<CS00); // правка на 461
TCNT0L = T0_TICKS; //правка на 461
//иницилизация прерываний
}
//прерывания таймера Т0 - вывод на индикатор
ISR(TIMER0_OVF_vect) //правка на 461
{
static unsigned char count = 0;
TCNT0L += T0_TICKS; //правка на 461
//гасим оба разряда
PORTB |=(1<<PB0);
PORTB |=(1<<PB2);
PORTA = 0b11111110;
//зажигаем следующий разряд
if (count == 0)
{
segchar(data2);
PORTB &= ~(1<<2);
}
if (count == 1)
{
segchar(data1);
PORTB &= ~(1<<0);
}
count++;
if (count == 2) count = 0;
}Можно ли сделать на МК ATTINY461 организовать подобие много поточности. Чтобы 2 типа прерываний оказывали друг на друга минимальное влияние ?..
Весь код:
Спойлер
Код: Выделить всё
#define F_CPU 8000000 //Hz
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/io.h>
#define T0_TICK_RATE 200 // Hz
#define T0_CLK ((F_CPU)/1024)
#define T0_TICKS (0x100 - T0_CLK / T0_TICK_RATE)
#define DEBOUNCE_TIME 20
#define BUTTON_PIN PINB
#define POWER_BIT PB3
#define UP_BIT PB4
#define DOWN_BIT PB5
#define KEY_POWER 0b00001000
#define KEY_DOWN 0b00100000
#define KEY_UP 0b00010000
#define En_INT0 GIMSK|=(1<<6);
#define Dis_INT0 GIMSK&=~(1<<6); // выключаем прерывание INT0
volatile unsigned char data1=0;
volatile unsigned char data2=0;
volatile unsigned char value;
volatile int _buzzer = 0;
volatile int _pressed = 0;
void init_io();
void segchar(unsigned char seg);
void handle_button(int key);
void handle_buttons();
void process_power();
void process_up();
void process_down();
//настройка внешнего прерывния INT0
void int0_init( void )
{
//настраиваем на срабатывание INT0 по переднему фронту
MCUCR |= (1<<ISC01)|(0<<ISC00);
//разрешаем внешнее прерывание INT0
En_INT0
}
ISR(INT0_vect)
{
int i=100;
int tempMS=(value+1);
for (;;)
{
i--;
_delay_us(10);
if (i<=tempMS)
{
break;
}
}
int k;
for(k=0; k<5; k++)
{
PORTB |= (1<<1);
_delay_us(2);
PORTB &= ~(1<<1);
_delay_us(2);
}
}
int main(void)
{
value=0;
init_io();
sei();
int0_init();
while(1)
{
handle_buttons();
}
return 0;
}
void segchar (unsigned char seg)
{
switch (seg)
{
case 1: PORTA = 0b01111100; break;
case 2: PORTA = 0b10000100; break;
case 3: PORTA = 0b01000100; break;
case 4: PORTA = 0b01101000; break;
case 5: PORTA = 0b01000010; break;
case 6: PORTA = 0b00000010; break;
case 7: PORTA = 0b01110100; break;
case 8: PORTA = 0b00000000; break;
case 9: PORTA = 0b01000000; break;
case 0: PORTA = 0b00010000; break;
}
}
void init_io()
{
//порт, к которому подкл. сегменты
PORTA = 0xff;
DDRA = 0xff;
//порт, к которому подкл. катод
DDRB |=(1<<0)|(1<<1)|(1<<2);
PORTB =0x00;
//инициализация таймера Т0
TIMSK = (1<<TOIE0);
TCCR0B = (1<<CS02)|(0<<CS01)|(1<<CS00); // правка на 461
TCNT0L = T0_TICKS; //правка на 461
//иницилизация прерываний
}
//прерывания таймера Т0 - вывод на индикатор
ISR(TIMER0_OVF_vect) //правка на 461
{
static unsigned char count = 0;
TCNT0L += T0_TICKS; //правка на 461
//гасим оба разряда
PORTB |=(1<<PB0);
PORTB |=(1<<PB2);
PORTA = 0b11111110;
//зажигаем следующий разряд
if (count == 0)
{
segchar(data2);
PORTB &= ~(1<<2);
}
if (count == 1)
{
segchar(data1);
PORTB &= ~(1<<0);
}
count++;
if (count == 2) count = 0;
}
void handle_button(int key)
{
int bit;
switch (key)
{
case KEY_POWER: bit = POWER_BIT; break;
case KEY_UP: bit = UP_BIT; break;
case KEY_DOWN: bit = DOWN_BIT; break;
default: return;
}
if (bit_is_clear(BUTTON_PIN, bit))
{
if (_pressed == 0)
{
_delay_ms(DEBOUNCE_TIME);
if (bit_is_clear(BUTTON_PIN, bit))
{
_pressed |= key;
// key action
switch (key)
{
case KEY_POWER: process_power(); break;
case KEY_UP: process_up(); break;
case KEY_DOWN: process_down(); break;
}
}
}
}
else
{
_pressed &= ~key;
}
}
void handle_buttons()
{
handle_button(KEY_POWER);
handle_button(KEY_DOWN);
handle_button(KEY_UP);
}
void process_power()
{
}
void process_up()
{
if (value < 99)
{
value++;
unsigned char tmp;
tmp = value % 10;
data1 = tmp;
tmp = value/10;
data2= tmp;
}
}
void process_down()
{
if (value > 0)
{
value--;
unsigned char tmp;
tmp = value % 10;
data1 = tmp;
tmp = value/10;
data2= tmp;
}
}
- Вложения
-
- Для Ф.rar
- Proteus + AtmelStudio
- (58.71 КБ) 245 скачиваний
.................................................................................................................



