прерывание от таймера 0

Обсуждаем контроллеры компании Atmel.
Ответить
Аватара пользователя
wws63
Сверлит текстолит когтями
Сообщения: 1231
Зарегистрирован: Вс май 21, 2006 16:07:59
Откуда: Алтай

прерывание от таймера 0

Сообщение wws63 »

Прошу специалистов помочь разобраться с проблемой.
В программке 3 ШИМа для управления RGB диодом. Скважность зависит от частоты входного сигнала на входе INT0.
ШИМ работает номрально, а для счета импульсов за период времени задействовал Таймер 0.
Но не считате, Где то ошибочка.

Код: Выделить всё

#include <avr/io.h>
#define F_CPU 8000000UL //8MHz
#include <util/delay.h>
#include <avr/interrupt.h>

volatile unsigned char Tic_Count = 0;
volatile unsigned char i = 0;
volatile unsigned char i_Count = 10;
#define BLUE_PB  1
#define BLUE_PWM    OCR1A
#define RED_PB   2
#define RED_PWM  OCR1B
#define GREEN_PB    3
#define GREEN_PWM   OCR2


ISR( INT0_vect )   // прерывание по внешнему сигналу
    {
	Tic_Count ++;
    }

ISR (TIMER0_OVF_vect)
    {
	 TCNT0 = 60; // переполнение через 25мС
	 i_Count--;
	 if(i_Count == 0)
	    {
		 i_Count = 10;  
		 i = Tic_Count;
		 Tic_Count = 0x00;
	    }
	 }
int main(void) 
{   //---------- настройка пинов МК
	DDRB |= (1<<BLUE_PB) | (1<<RED_PB) | (1<<GREEN_PB); // на выход RGB
	PORTB &= ~((1<<BLUE_PB) | (1<<RED_PB) | (1<<GREEN_PB));
	DDRD |= (1<<2); // PD2 на вход (INT0)
	PORTD |= (1 << 2); // Включение подтягивающего резистора
	MCUSR |= (1 << ISC00) | (1 << ISC01); // Передний фронт сигнала
	GICR  = (1 << INT0);                 // Включение входа прерывания
	sei(); /* Общее разрешение прерываний */
	//-----------------инициализация Таймер 1---------------
	TCCR1A |= (1 << COM1A1) | (1 << COM1B1) | (1 << WGM11);
	TCCR1B |= (1 << WGM13) | (1 << WGM12) | (1 << CS10);
	TCNT1 = 0x00;
	ICR1 = 0xFF;
	OCR1A = 0x00;
	OCR1B = 0x00;
    //-------------инициализация Таймер 2----------------------------
	TCCR2 |= (1 << COM21) | (1 << WGM21) | (1 << WGM20) | (1 << CS20);
	TCNT2 = 0x00;
	OCR2 = 0x00; 
	//-------------инициализация Таймер 0--------------------------------
	TCCR0 = 0b00000101; // Т0 на внутр.такт, делитель 1024
	TCNT0 = 60; // переполнение через 25мС
	i_Count = 10; 
	TIMSK |= (1 << TOIE0); /* Разрешить прерывание по                       
                                переполн.Т0*/
	sei();
	
	while(1) 
	{
	    //---------------------------------
	    if (i>26)  
	        {
		    BLUE_PWM = 0;
		    RED_PWM  = 255;    
		    GREEN_PWM = 0;
		   }
		
			 //----------------------------------
		 if (i>15)  
		      {
			 BLUE_PWM = 250;
			 RED_PWM  = 250;    
			 GREEN_PWM = 250;
			 }
		
		       
	        if (i<8)  
	             {
		        BLUE_PWM = 0;
		        RED_PWM  = 0;    // зеленый
		        GREEN_PWM = 250;
			  }
		
		  }
	}

Реклама
Аватара пользователя
VALNER
Открыл глаза
Сообщения: 57
Зарегистрирован: Ср янв 03, 2018 01:36:14

Re: прерывание от таймера 0

Сообщение VALNER »

У вас pin INT0 настроен на выход, а не на вход. Ну и в замен подтяжки вы просто держите на D2 высокий лог. уровень. Следовательно из за неправильной настройки порта не срабатывают прерывания на INT0.
DDRD |= (1<<2); // PD2 на вход (INT0) <--(это убрать)
PORTD |= (1 << 2); // Включение подтягивающего резистора
Надеюсь это единственная причина и это вам поможет, если вы сами это еще не нашли.

И да. Та часть что в бесконечном цикле тоже будет работать не правильно
while(1)
{
//---------------------------------
if (i>26)
{
BLUE_PWM = 0;
RED_PWM = 255;
GREEN_PWM = 0;
}

//----------------------------------
if (i>15)
{
BLUE_PWM = 250;
RED_PWM = 250;
GREEN_PWM = 250;
}


if (i<8)
{
BLUE_PWM = 0;
RED_PWM = 0; // зеленый
GREEN_PWM = 250;
}

}
Так как если і больше 26, то оно и больше 15, а по скольку у вас три независимых условия то оно всегда будет принимать значение того что выполняется последним. Их лучше расписать через else if()
Реклама
Аватара пользователя
wws63
Сверлит текстолит когтями
Сообщения: 1231
Зарегистрирован: Вс май 21, 2006 16:07:59
Откуда: Алтай

Re: прерывание от таймера 0

Сообщение wws63 »

Да, я с направлением порта напутал. Привык, что в ПИКушках 1- вход.
А по поводу цикла программы, если else будет громоздко.
Можно ли обойтись таким нелюбимым всеми оператором goto ?

Код: Выделить всё

while(1) 
	{
 //---------------------------------
m:
	    if (i>26)  
	        {
		    BLUE_PWM = 0;
		    RED_PWM  = 255;    
		    GREEN_PWM = 0;
                     goto  m;  
		   }
		
			 //----------------------------------
		 if (i>15)  
		      {
			 BLUE_PWM = 250;
			 RED_PWM  = 250;    
			 GREEN_PWM = 250;
                         goto m;
			 }
		
		       
	        if (i<8)  
	             {
		        BLUE_PWM = 0;
		        RED_PWM  = 0;    // зеленый
		        GREEN_PWM = 250;
                         goto  m;
			  }
         }
Аватара пользователя
bafomet911
Открыл глаза
Сообщения: 76
Зарегистрирован: Чт янв 31, 2019 18:49:04
Откуда: Воронежская область

Re: прерывание от таймера 0

Сообщение bafomet911 »

А если так:
Спойлерif(i<8){...}
if(i>8&&i<15){...}
if(i>15&&i<26){...}
if(i>26){...}
Не устроит?
Изображение
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
wws63
Сверлит текстолит когтями
Сообщения: 1231
Зарегистрирован: Вс май 21, 2006 16:07:59
Откуда: Алтай

Re: прерывание от таймера 0

Сообщение wws63 »

[uquote="bafomet911",url="/forum/viewtopic.php?p=3593428#p3593428"]А если так:
Не устроит?[/uquote]
Я приводил упрощенный пример.
В реальном проекте проверка идет от 8 до 26 каждое целое значение. Т.е 8, 9, 10...26
Наверное правильнее будет сделать мне сравнение с число
if (i>26) {}
if (i==26) {}
if (i==25) {}
.....
if(i==8) {}
if(i<8) {}
Реклама
Аватара пользователя
Ivanoff-iv
Друг Кота
Сообщения: 7077
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

Re: прерывание от таймера 0

Сообщение Ivanoff-iv »

ну, если это последовательный ряд чисел, то я бы применил массив...

Код: Выделить всё

if (i>26) i=26;
if (i<=8) {i=0;} else {i-=8;};
Blue=BLUE_PWM[i];
Red=RED_PWM[i];
Green=GREEN_PWM[i];
или свитч кейс:

Код: Выделить всё

 if (i>26) i=26;
switch (i)
{
case 26: ..... break;
case 25: ..... break;
..............,..........
case 9: ...... break;
default: .......
};
Последний раз редактировалось Ivanoff-iv Вс мар 17, 2019 12:27:51, всего редактировалось 1 раз.
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Реклама
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18546
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: прерывание от таймера 0

Сообщение ARV »

wws63 писал(а):если else будет громоздко
интересно, с чего вдруг?

Код: Выделить всё

if(cond_1){
  // первый выбор
} else if(cond_2){
  // второй выбор
} else if (cond_3){
  // третий выбор
} else {
  // если ничего не подошло
}
Добавлено after 3 minutes 36 seconds:
если сравнивате "цепочкой" по условию "больше" - начинайте с наибольшего. т.е. если сравниваем с числами 5, 10, 15 и 20, то надо писать в такой последователньости

Код: Выделить всё

if(x > 20){
  // x более 20
} else if(x > 15){
  // х более 15, но менее или равно 20
} else if(x > 10){
  // х более 10, но менее или равно 15
} else if(x > 5){
  // х более 5, но менее или равно 10
} else {
  // х менее или равно 5
}
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
wws63
Сверлит текстолит когтями
Сообщения: 1231
Зарегистрирован: Вс май 21, 2006 16:07:59
Откуда: Алтай

Re: прерывание от таймера 0

Сообщение wws63 »

[uquote="ARV",url="/forum/viewtopic.php?p=3593508#p3593508"]если сравнивате "цепочкой" по условию "больше" - начинайте с наибольшего.[/uquote]
А выход из процедуры при условии совпадения без goto ?

Код: Выделить всё

  if (i>26)  // больше 3100 об/мин
	       {
		    BLUE_PWM = 0;
		    RED_PWM  = 255;    // красный
		    GREEN_PWM = 0;
		    goto m; //----- убрать?
	       }
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18546
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: прерывание от таймера 0

Сообщение ARV »

какой выход? цепочка if - else if срабатывает только в одном месте, все остальные проходят мимо. "выход" не требуется, вся цепочка - это как бы один оператор.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
wws63
Сверлит текстолит когтями
Сообщения: 1231
Зарегистрирован: Вс май 21, 2006 16:07:59
Откуда: Алтай

Re: прерывание от таймера 0

Сообщение wws63 »

[uquote="ARV",url="/forum/viewtopic.php?p=3593594#p3593594"]вся цепочка - это как бы один оператор.[/uquote]
Спасибо, завтра посмотрю как в "железе" работает.
Аватара пользователя
Ivanoff-iv
Друг Кота
Сообщения: 7077
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

Re: прерывание от таймера 0

Сообщение Ivanoff-iv »

поправил прошлое сообщение (дописал код на кейсах)...
сейчас нет возможности проверить, но мне кажется, если массивы во флеш разместить то по ресурсоемкости метод "иф-елзе" будет самым громоздким... а может и нет, если оптимизатор правильно сработает... (может кто промерит объём кода и скорость выполнения)
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Аватара пользователя
wws63
Сверлит текстолит когтями
Сообщения: 1231
Зарегистрирован: Вс май 21, 2006 16:07:59
Откуда: Алтай

Re: прерывание от таймера 0

Сообщение wws63 »

[uquote="Ivanoff-iv",url="/forum/viewtopic.php?p=3593653#p3593653"]поправил прошлое сообщение (дописал код на кейсах)...[/uquote]
Буду пробовать все варианты
Аватара пользователя
wws63
Сверлит текстолит когтями
Сообщения: 1231
Зарегистрирован: Вс май 21, 2006 16:07:59
Откуда: Алтай

Re: прерывание от таймера 0

Сообщение wws63 »

Застрял на ровном месте. В Протеусе все работает на УРА, скважность с каждого канала ШИМ меняется в заданных параметрах, строго по частоте входного сигнала.
А в "железе" одни глюки. Светодиоды мигают хаотично, при этом изменение частоты входного сигнала не дает почти никаких изменений. Перепробовал все.
Снижал частоту генерации ШИМ (менее сотни Гц), думал может РЖБ - лента, изменял фронты сигнала на входе INT0, менял контроллер, игрался с тактовой частотой, менял пороги срабатывания ... Короче все , что можно. Разумеется, проверил монтаж на плате (сопли, обрывы). :dont_know:
В общем не знаю, в какую сторону копать :( Может есть какие то подводные камни с Атмегой 8?
Аватара пользователя
Ivanoff-iv
Друг Кота
Сообщения: 7077
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

Re: прерывание от таймера 0

Сообщение Ivanoff-iv »

питание мк стабльное?
блокировочные конденсаторы имеются?
ресет к плюсу притянут?
как разведены ключи лент?
схему давай!
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Аватара пользователя
wws63
Сверлит текстолит когтями
Сообщения: 1231
Зарегистрирован: Вс май 21, 2006 16:07:59
Откуда: Алтай

Re: прерывание от таймера 0

Сообщение wws63 »

[uquote="Ivanoff-iv",url="/forum/viewtopic.php?p=3594637#p3594637"]питание мк стабльное?
блокировочные конденсаторы имеются?
ресет к плюсу притянут?
как разведены ключи лент?
схему давай![/uquote]
Причина найдена!
Аватара пользователя
wws63
Сверлит текстолит когтями
Сообщения: 1231
Зарегистрирован: Вс май 21, 2006 16:07:59
Откуда: Алтай

Re: прерывание от таймера 0

Сообщение wws63 »

Вместо регистра MCUCR было записано MCUSR.
Студия 6 (как впрочем и 4) на ноутбуке нормально компилировала в хекс, приносил проект на другой комп там прошивал и ступор.
Когда попытался внести изменения в программу и заново откомпилировать уже на компе, студия 6 начала ругаться на MCUSR.
Мистика! :dont_know:
Едем дальше :write:
Ответить

Вернуться в «AVR»