Как работать с таймерами ATmega48PA на C/C++ ?

Обсуждаем контроллеры компании Atmel.
Ответить
Друг Кота
Аватара пользователя
Сообщения: 15595
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

Если делать качественный светодиодный индикатор двух прерываний вряд-ли хватит, тем более при том, что помимо индикации еще и задачи ввода/обработки делать необходимо. И ВСЕ на одном кристалле.
Ежли вывести управление светодиодным табло на отдельную мелкосхемку с собственными мозгами - дело несколько упростится (то же касается индикаторов ЖКИ, имеющих свой контроллер).
Однако чаще стараются "мелкий" проект в одну корпусину запихерить, а в таком случае без кучки прерываний "с выпендрежом" не обойтись.
8)
Реклама
Zat
Встал на лапы
Аватара пользователя
Сообщения: 119
Зарегистрирован: Пн ноя 02, 2009 05:27:41
Откуда: С-Пб

Сообщение Zat »

[uquote="ozonn",url="/forum/viewtopic.php?p=3421930#p3421930"][uquote="afz",url="/forum/viewtopic.php?p=3421895#p3421895"]Сейчас нет. Потом, в процессе отладки или доработки понадобится второе, и приплыли.[/uquote]
а если и потом не понадобится? :)

я это все к тому, что надо все делать с умом. Делал я как-то ампервольтметр для своего ЛБП. Использовал два прерывания, АЦП и таймер, для индикации. Основной цикл пустой. Теперь вопрос: откуда тут могут взяться еще какие-то прерывания? :)[/uquote]
Ну ты троль. Если, когда, зачем... просто делай сразу так ,чтобы потом не было мучительно больно за
потраченное время на быдлокод. 500 мс задержки в прерывании - это вечность.
Реклама
Собутыльник Кота
Аватара пользователя
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

Встречаются два мужика в пустыне. Один тащит телефонную будку, второй рельсу.
Тот что с рельсой спрашивает:
- Нафига тебе телефонная будка?
- Ну а вдруг на меня лев нападет?! Я в будку спрячусь, и он меня не съест! А ты зачем рельсу таскаешь?
- А вдруг львы?!
- И что?
- Ну дак я рельсу брошу и налегке от них убегу!
Кого-то мне чувак с рельсой напоминает. :)
Вымогатель припоя
Сообщения: 522
Зарегистрирован: Чт янв 21, 2016 15:59:10

Сообщение ozonn »

[uquote="ARV",url="/forum/viewtopic.php?p=3421947#p3421947"]есть правильный подход, который ВСЕГДА дает хороший реззультат, а есть подход, который дает результат ЕСЛИ. знать о таком подходе - плюс, а пользоваться им повседневно на регулярной основе - минус.[/uquote]
я и не пользуюсь. Я просто не люблю усложнять на ровном месте :)
Реклама
Эиком - электронные компоненты и радиодетали
Прорезались зубы
Сообщения: 213
Зарегистрирован: Вт сен 09, 2008 18:17:27

Сообщение DENIS451 »

Теперь непонятные проблемы с таймером1 - ставлю такие настройки (внешний кварц 20мГц):

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

TCCR1B = 0;
TCCR1A = 0;	
TCCR1B |= (1<<WGM12); // устанавливаем режим СТС (сброс по совпадению) для первого таймера
// 	OCR1AH = 0xFF; //записываем в регистр число для сравнения - старшый байт
// 	OCR1AL = 0x7F; //записываем в регистр число для сравнения - младший байт
OCR1A = 4000; //записываем в регистр число для сравнения

TCCR1B |= ( 1 << CS12 ) | ( 1 << CS10 );//устанавливаем предделитель на 1024 
TIMSK1 |= (1<<OCIE1A);   // Разрешить прерывание по совпадению OCR1A
//TIMSK1 |= (1<<OCIE1B);   // Разрешить прерывание по совпадению OCR1B
//TIMSK1 |= (1<<TOIE1);    // Разрешить прерывание по переполнению
Канал B осциллографа в Протеусе подключён к ноге PC2, на которой в
ISR (TIMER1_COMPA_vect )меняется высокий уровень на низкий, каждый
полупериод меандра должен быть 205 милисек. = 1/(20000000/(4000*1024))
а он, почему то, то в 3 раза больше, то в 2 !

Почему так происходит?
Вложения
Безымянный.png
(79.87 КБ) 348 скачиваний
Реклама
Друг Кота
Аватара пользователя
Сообщения: 7077
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

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

может в прерывание входит не сразу (не разрешены по какой то причине, I, например нет), может в прерывании не сразу скидывает (код то не видно)... а поднимает ногу кто?

Добавлено after 2 minutes 15 seconds:
посмотрел видимую часть сигнала - сбрасывается он вроде регулярно (интервалы между спадающими фронтами равны), а вот поднятие идет както поразному...
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Реклама
Прорезались зубы
Сообщения: 213
Зарегистрирован: Вт сен 09, 2008 18:17:27

Сообщение DENIS451 »

Я выложил весь тестовый проект (Таймеры.zip) для Atmel studio 6.2, там же внутри проэкт для Proteus 8.7

Кстати, если закомментировать блок настроек относящиеся к таймеру0, то таймер1 перестаёт работать вообще
(кажется это происходит после одного срабатывания) !

Почему так происходит?
Спойлер

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

/////////////////////////////////////////////////////////////////
#define F_CPU 20000000L
#include <avr/io.h>
#include <Util/delay.h>
#include <avr/interrupt.h>
/////////////////////////////////////////////////////////////////
void timers_ini(void)
{
/////////////////////////////////////////////////////////////////////////

//====/Настройка таймера0/===================
TCCR0A = 0;
TCCR0B = 0;
TCCR0A |= (1<<WGM01);                   // Режим CTC (сброс по совпадению)
//TCCR0B |= (1<<CS00);                      // Тактирование от CLK.
// Если нужен предделитель :
// TCCR0B = (1<<CS01);                   // CLK/8
// TCCR0B = (1<<CS00)|(1<<CS01); // CLK/64
// TCCR0B = (1<<CS02);                   // CLK/256
 TCCR0B = (1<<CS00)|(1<<CS02); // CLK/1024

// Верхняя граница счета. Диапазон от 0 до 255.
OCR0A = 255;                                   // Частота прерываний A будет = Fclk/(N*(1+OCR0A))
OCR0B = 255;                                   // Частота прерываний B будет = Fclk/(N*(1+OCR0B))
// где N - коэф. предделителя (1, 8, 64, 256 или 1024)
TIMSK0 |= (1<<OCIE0A);                  // Разрешить прерывание по совпадению A
//TIMSK0 |= (1<<OCIE0B);                  // Разрешить прерывание по совпадению B
//TIMSK0 |= (1<<TOIE0);                    // Разрешить прерывание по переполнению
	
//====/Настройка таймера1/===================
  TCCR1B = 0;
  TCCR1A = 0;
  TCCR1B |= (1<<WGM12);                    // Режим CTC (сброс по совпадению)
  //TCCR1B |= (1<<CS10);                       // Тактирование от CLK.
  // Если нужен предделитель :
  // TCCR1B |= (1<<CS11);                   // CLK/8
  // TCCR1B |= (1<<CS10)|(1<<CS11); // CLK/64
  // TCCR1B |= (1<<CS12);                   // CLK/256
   TCCR1B |= (1<<CS10)|(1<<CS12); // CLK/1024

  // Верхняя граница счета. Диапазон от 0 до 65535.
  OCR1A = 2678;                                   // Частота прерываний A будет = Fclk/(N*(1+OCR1A))
  OCR1B = 2678;                                   // Частота прерываний A будет = Fclk/(N*(1+OCR1B))
  // где N - коэф. предделителя (1, 8, 64, 256 или 1024)
  TIMSK1 |= (1<<OCIE1A);                    // Разрешить прерывание по совпадению A
  //TIMSK1 |= (1<<OCIE1B);                    // Разрешить прерывание по совпадению B
  //TIMSK1 |= (1<<TOIE1);                      // Разрешить прерывание по переполнению	

////////////////////////////////////////////////////////////////////////////////////////////////////
}
ISR (TIMER0_COMPA_vect)	// вектор прерывания по совпадению таймера 0
{
/////////////////////////////////////////////////////////////////	
if ((PINC&0b00000001))
 {
 PORTC &= ~(1<<0); //записать в PC0 ноль
 }	
 else
  {
  PORTC |= (1<<0); //записать в PC0 единицу		 		
  }
  
////////////////////////////////////////////////////////////////////  
}
ISR (TIMER1_COMPA_vect )
{
/////////////////////////////////////////////////////////////////////	
if ((PINC&0b00000001))
  {
  PORTC &= ~(1<<2); //записать в PC0 ноль
  }
  else
   {
   PORTC |= (1<<2); //записать в PC0 единицу
   }
///////////////////////////////////////////////////////////////////	
}
int main(void)
{
//=========================	
	
	DDRC |= (1<<0); //записать в PC0 единицу (что бы выставить его на выход) 
   PORTC &= ~(1<<0); //записать в PC0 ноль
    DDRC &= ~(1<<1); 
   PORTC |= (1<<1);
    DDRC |= (1<<2); //записать в PC2 единицу (что бы выставить его на выход)
   PORTC &= ~(1<<2);//записать в PC2 ноль
   
   timers_ini();
	sei();//разрешить прерывания
	
	
//=========================		
	while(1)
	{
		if (false == (PINB&0b00000010))
		{	
	
		//_delay_ms(500);			
		}
		
	}
//========	
}
Вложения
Таймеры.zip
(197.94 КБ) 144 скачивания
Последний раз редактировалось DENIS451 Пт июл 20, 2018 14:42:59, всего редактировалось 1 раз.
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18677
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

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

Мой уютный бложик... заходите!
Контактная информация:
Прорезались зубы
Сообщения: 213
Зарегистрирован: Вт сен 09, 2008 18:17:27

Сообщение DENIS451 »

О точно, спасибо ARV, глаз замылился и я не вижу, что проверяю PC0 вместо того, что бы проверять PC2,
в обработчике ISR (TIMER1_COMPA_vect )!
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18677
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

DENIS451 писал(а):глаз замылился и я не вижу, что проверяю PC0 вместо того, что бы проверять PC2
чтобы не попадать в подобную ситуацию, крайне настоятельно рекомендую избавиться от магических чисел при помощи соответствующих макросов
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Вымогатель припоя
Сообщения: 522
Зарегистрирован: Чт янв 21, 2016 15:59:10

Сообщение ozonn »

[uquote="Zat",url="/forum/viewtopic.php?p=3421960#p3421960"]Ну ты троль. Если, когда, зачем... просто делай сразу так ,чтобы потом не было мучительно больно за
потраченное время на быдлокод. 500 мс задержки в прерывании - это вечность.[/uquote]
я сразу сделал "не так" и мне не больно, все работет. А у тебя я спросил, откуда в вольтметре возьмется еще одно прерыване. От сырости?

Вы как роботы, сказали вам что в прерывании низзя и все тут. Нет шоп моск включить, хотя бы на мгновение :)
Ответить

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