Я пытаюсь запустить две функции «одновременно» через прерывания:
1) Измерьте AD C по таймеру таймера 0 (100 Гц) и покажите результаты на контакте 0-5
2) Мигает светодиод через таймер 1 (10 Гц) на выводе 6.
Проблема, похоже, в том, что ISR таймера 1 блокирует функцию, поэтому больше ничего не выполняется. Вот код:
(Пожалуйста, не обижайтесь на ошибки стиля, код находится в стадии разработки)
#define F_CPU 16000000UL // 16MHz Clock speed
#include <avr/io.h>
#include <avr/interrupt.h>
void ADC_init(void);
void SetTimer0(void);
void SetTimer1(void);
int main(void)
{
DDRB |= (1<<DDB0) + (1<<DDB1) + (1<<DDB2) + (1<<DDB3) + (1<<DDB4) + (1<<DDB5) + (1<<DDB6);
PORTB = 0b00000000;
DDRB &= ~(1<<DDB7);
ADC_init();
SetTimer0();
SetTimer1();
while(1){
}
}
void ADC_init(void)
{
cli();
// Select Vref=AVcc
// and set left adjust result
// select pin ADC0 (PC0)
ADMUX |= (1<<REFS0)|(1<<ADLAR);
//and enable ADC
//enable ADC interupt
//enable autotriggering
//set prescaller to 128
ADCSRA |= (1<<ADEN) | (1<<ADATE) | (1<<ADIE) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);
//set ADC trigger source - Timer0 compare match A
ADCSRB |= (1<<ADTS1)|(1<<ADTS0);
// StartADC
ADCSRA |= (1<<ADSC);
sei();
}
//initialize timer0 match A on 100hz
void SetTimer0(void)
{
cli();
TCCR0A = 0; // set entire TCCR0A register to 0
TCCR0B = 0; // same for TCCR0B
TCNT0 = 0; // initialize counter value to 0
// set compare match register for 100Hz increments
OCR0A = 155; // = 16000000 / (1024 * 100.16025641025641)-1
// toggle PD6/OC0A pin on compare match
TCCR0A |=(1<<COM0A0)|(1<<WGM01);
//Set CTC mode
TCCR0B |= (1 << WGM01);
// Set CS02, CS01 and CS00 bits for 1024 prescaler
TCCR0B |= (1 << CS02) | (0 << CS01) | (1 << CS00);
// enable timer compare interrupt
TIMSK0 |= (1 << OCIE0A);
sei();
}
//initialize timer1 10hz
void SetTimer1(void){
cli();
TCCR1A = 0; // set entire TCCR1A register to 0
TCCR1B = 0; // same for TCCR1B
TCNT1 = 0; // initialize counter value to 0
// set compare match register for 10 Hz increments
OCR1A = 24999; // = 16000000 / (64 * 10) - 1 (must be <65536)
// turn on CTC mode
TCCR1B |= (1 << WGM12);
// Set CS12, CS11 and CS10 bits for 64 prescaler
TCCR1B |= (0 << CS12) | (1 << CS11) | (1 << CS10);
// enable timer compare interrupt
TIMSK1 |= (1 << OCIE1A);
sei();
}
// ADC done interrupt
ISR(ADC_vect)
{
// Clear timer compare match flag
TIFR0=(1<<OCF0A);
// save ADC measurement
uint16_t val = ADC;
// show ADC results
if (val < 100)
{ PORTB = 0b00000000; }
else if (val < 300)
{ PORTB = 0b00000001; }
else if (val < 550)
{ PORTB = 0b00000011; }
else if (val < 850)
{ PORTB = 0b00000111; }
else if (val < 1020)
{ PORTB = 0b00001111; }
else
{ PORTB = 0b00011111; }
}
ISR(TIMER1_COMPA_vect)
{
//PORTB ^= PINB5;
static uint16_t on = 0;
if (on == 1){
PORTB = 0b00100000;
on = 0;
}
else {
PORTB = 0b00000000;
on = 1;
}
}
Когда функция SetTimer1()
отключена, DCA работает должным образом. Таким образом, по отдельности оба ISR работают нормально, но вместе - нет. Может ли кто-нибудь помочь мне решить эту проблему?