Cинхронизация таймера-счетчика

На всякий случай, может понадобится
http://www.gaw.ru/pdf/Atmel/app/avr/AVR182.pdf

Спасибо:)

На старом форуме были димеры с управлением через таймеры. Покопайся там.

1 лайк

Ни в коем разе! Он принцип понял, будет полезней самому докумекать. Копипастеров и так хоть стерилизуй.

Вот набросал для экперимента

int pin = 12;  
void setup() 
{
  pinMode(pin, OUTPUT); 
  digitalWrite(pin, 0); 
  TCCR0A|=(1<<WGM01);
  TCCR0B|=(1<<CS02)|(1<<CS00);
  OCR0A=0x7c;
  TIMSK0|=(1<<OCIE0A);
  
  TCCR2A|=(1<<WGM01);
  TCCR2B&=~((1<<CS02)|(1<<CS01)|(1<<CS00));
  OCR2A=0x0c;
  TIMSK2|=(1<<OCIE2A);
}
ISR(TIMER0_COMPA_vect) {
 digitalWrite(pin, 1);
 TCCR2B|=(1<<CS02)|(1<<CS00);//запускаем счетчик
}
ISR(TIMER2_COMPA_vect) { 
 digitalWrite(pin, 0);
TCCR2B&=~((1<<CS02)|(1<<CS01)|(1<<CS00));//стоп счетчик  
}
void loop() {
}

Ожидаю на ноге 12 МЕГИ импульсы длиной 1/10 от периода повторения,
вечером дома проверю

Ну примерно так, проверить не могу сейчас. Но я б, раз уж за регистры взялись, пинами бы управлял аналогично: PORTx|=(1<<p).
Да и значения в десятичном счислении лучше воспринимаются)

Их есть у меня ( обьект нога-прямой доступ через регистры, методы установки и снятия состояний, и из него произростает обьект кнопка), его здесь использовать не могу - он дома на компе :frowning:

Зачем такие извращения? Почему не просто = 0?

А почему бы не пошалить :slight_smile:

Да шалите, если хотите.
Но с таким внимательней следует быть: TCCR0B|=…
Сегодня TCCR0B - нуль, завтра 128 и весь счёт пойдёт по п…

1 лайк

@sadman41 подобные записи с битовыми масками приучают к изменению нужных битов. А то мало ли, обнулишь весь регистр вместе с ненужными битами.
Всё равно скомпилируется в одну команду.

Ну, хорошо, пусь балуется. Главное, чтобы ассемблер не расчёсывал.

3 лайка

Ёлооочка,зажгись! Тьфу, ты… @dedivan проснись!:smile:

Попробовал на одном таймере, для 328р 16MHz

Спойлер
#include <avr/io.h>
#include <avr/interrupt.h>

  volatile unsigned char FLAG = 0;

   int main() 
  {
  DDRB |= 1 << PB0; //  импульсы длительностью 1мс с периодом 10мс на PB0
  PORTB &= ~(1 << PB0);  
  TCCR0A |=(1<<WGM01);
  OCR0A = 140; // 9ms
  TIMSK0 |=(1<<OCIE0A);
  TCCR0B |= (1<<CS02)|(1<<CS00);//  /1024
   sei();

   while(1);
   return 0;
 }

ISR(TIMER0_COMPA_vect) {
 if(!FLAG){
  FLAG = 1;
  PINB = 1;
 OCR0A = 15; //1ms точнее 0.96ms 
 }
 else{
  FLAG = 0;
  PINB = 1;
  OCR0A = 140;// 9ms  точнее  8.96ms
  }
 }

Если точнее надо - можно Timer1 взять

Спойлер

1 деление - 1мс

1 лайк

Чёй то? В двоичном и шеснадцатиричном сразу видно где ноль где еденица, а десячичный ещё переводить надо.