Страница 1 из 2

как получить интервал 1 сек с помошью таймера atmega 8

Добавлено: Пн июл 14, 2014 12:07:44
zsxdcf
здравствуйте
хочу получить интервал в 1 сек с помощью таймера TCNT0 атмега 8 с кварцем 4 мгц
Ставлю предделитель на 4 .
использую прерывание по переполнению с исходным числом 6.
запускаю счетчте на 40 000 на выходе которого должен быит по идее 1 гц но увы частотьа гораздо ниже
в чем может быть причина?
моя логика верна?
спасибо заранее.

Re: как получить интервал 1 сек с помошью таймера atmega 8

Добавлено: Пн июл 14, 2014 12:12:13
igor-x
если гораздо ниже - значит МК работает на внутреннем генераторе.
для проверки можно отпаять кварц - МК продолжит работу

Re: как получить интервал 1 сек с помошью таймера atmega 8

Добавлено: Пн июл 14, 2014 12:53:28
pavel123
А фьюзы выставлены на меге для работы с кварцем?
Заводские установки меги - внутренний генератор и как раз на 1 Мгц...
После деления на 4 получается невесть что.

ЗЫ для большей точности можно взять часовой кварц... 32768 Гц

Re: как получить интервал 1 сек с помошью таймера atmega 8

Добавлено: Пн июл 14, 2014 14:45:02
Pink-Pank
zsxdcf писал(а):использую прерывание по переполнению с исходным числом 6. запускаю счетчте на 40 000
Это как так? :o у вас прерывание по переполнению или по совпадению? И в каком режиме таймер работает?
И если че, то (6+1) * 40 000 * 4 = 1 120 000 Гц. А у Вас 4 МГц.

P.S. Используйте таймер Т1 - он 16-битный (макс значение 65535)

Re: как получить интервал 1 сек с помошью таймера atmega 8

Добавлено: Пн июл 14, 2014 14:51:05
metan
zsxdcf писал(а):Ставлю предделитель на 4 .
Это чем таким вы TCCR0 накормили, чтоб такой коэффициент прескалера получить?

Re: как получить интервал 1 сек с помошью таймера atmega 8

Добавлено: Пн июл 14, 2014 16:16:40
Pink-Pank
мож он основной предделитель ставит

Re: как получить интервал 1 сек с помошью таймера atmega 8

Добавлено: Пн июл 14, 2014 16:39:10
metan
Pink-Pank писал(а):основной предделитель
Это еще кто?

Re: как получить интервал 1 сек с помошью таймера atmega 8

Добавлено: Пн июл 14, 2014 20:18:57
m.ix
без МК
может и не туда так на всякий

561ИЕ15
512ПС10

Re: как получить интервал 1 сек с помошью таймера atmega 8

Добавлено: Пн июл 14, 2014 20:23:51
Pink-Pank
metan писал(а):Это еще кто?
Предделитель основного тактового сигнала

Re: как получить интервал 1 сек с помошью таймера atmega 8

Добавлено: Пн июл 14, 2014 20:45:29
m.ix
иногда это называют скалер
что им только не называют хез :roll:
делитель частоты.

======
я прескалер покупал для частотометра
8ми ногая микра.

Re: как получить интервал 1 сек с помошью таймера atmega 8

Добавлено: Пн июл 14, 2014 21:10:12
metan
Pink-Pank писал(а):Предделитель основного тактового сигнала
Вы меня запутали :)
А как управлять этим основным предделителем?
Если вы имеете в виду переключение частот 1/2/4/8 Мгц, управляемое фьюзами, так это никакого отношения к предделителю не имеет и не делением частоты регулируется.

Re: как получить интервал 1 сек с помошью таймера atmega 8

Добавлено: Пн июл 14, 2014 22:15:49
Pink-Pank
нет, не фьюзами. ) Программно. Почитайте документацию .) Система тактирования. Предделитель тактового сигнала.

Re: как получить интервал 1 сек с помошью таймера atmega 8

Добавлено: Вт июл 15, 2014 07:19:23
akl
zsxdcf писал(а):...хочу получить интервал в 1 сек с помощью таймера TCNT0 атмега 8 с кварцем 4 мгц
Можно так

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

.equ	Fo=4000000

.equ	N=Fo/256		; N=4'000'000/256=15'625

.equ	M=Fo-N*256		; M=4'000'000-15'625*256=0

;.equ	Fo=4003769

;.equ	N=Fo/256		; N=4'003'769/256=15'639

;.equ	M=Fo-N*256		; M=4'003'769-15'639*256=185
В TCNT0 заносится -1-M-∆, где -учёт задержки обработки и занесения M. Затем счётчик переполнений N декрементируется до 0. Комментирован пример более реальной частоты кварца.

Re: как получить интервал 1 сек с помошью таймера atmega 8

Добавлено: Вт июл 15, 2014 13:36:13
zsxdcf
Я использую генератор кода CVAVR.
там ставится галочки на предделитель TCNTO и указывается какая частота поступает на вход таймера
Так вот при кварце 4 мгц и делителе 4 на вхо поступает 1 мгц и чтобы получить 1 сек с учетом разрядности таймера( он как известно 8 разрадный) нужно поделить взодную частоту на 1 000 000
Таймер делит на 256-6=250 ,а счетчик на 40 000 и вроде все дела но увы не получается в протеусе частота гораздо ниже и на практике к стати тоже.
во задача!?

Re: как получить интервал 1 сек с помошью таймера atmega 8

Добавлено: Вт июл 15, 2014 13:50:37
akl
Где Вы увидели предделитель на 4 у T0? Думаю, частота на выходе существенно ниже потому, что обработчик просто проглатывает прерывание -6 единиц.
Изображение

Re: как получить интервал 1 сек с помошью таймера atmega 8

Добавлено: Вт июл 15, 2014 14:44:18
a_skr
Предделитель таймера действительно нельзя установить на деление на 4. Можно, например, на 64. При начальном значении счетчика, равном 6, получим частоту прерываний по переполнению: 4000000/64/(256-6) = 250 Гц. В прерывании заведите программный счетчик ещё на 250. И получите 1 Гц. Как-то так:

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

#include <avr/io.h>
#include <avr/interrupt.h>

// 62500 / (256-6) = 250 Hz
ISR(TIMER0_OVF_vect)
{
  static uint8_t cnt=0;
  TCNT0 = 6;
  if(++cnt == 250) // 62500 / (256-6) / 250 = 1 Hz
  {
    PORTB ^= 1;
    cnt = 0;
  }
}

int main (void) 
{
  DDRB = 1;
  TCNT0 = 6;
  TCCR0 = _BV(CS01) | _BV(CS00); // 4000000 / 64 = 62500
  TIMSK = _BV(TOIE0); // timer0 overflow int
  sei();
  while(1);
}

Re: как получить интервал 1 сек с помошью таймера atmega 8

Добавлено: Вт июл 15, 2014 20:17:40
metan
Pink-Pank писал(а):нет, не фьюзами. ) Программно. Почитайте документацию
Уф.. Сдаюс. :) Весь даташит на 8 мегу прочесал, нету доступа к основному предделителю. В 88 кстати есть. Не томите, скажите, какой регистр за это отвечает?
zsxdcf писал(а):Так вот при кварце 4 мгц и делителе 4 на вхо поступает 1 мгц
Еще раз говорю, такого не бывает. При кварце в 4 МГц на вход таймера можно подать ТОЛЬКО 4 МГц, 0,5 МГц, 62,5 кГц, 15625 Гц и 3906 Гц

Re: как получить интервал 1 сек с помошью таймера atmega 8

Добавлено: Вт июл 15, 2014 20:42:06
zsxdcf
вот код
совсе ничего не понял сейчас показывает 1 кгц
в чем ощибка?
Спойлер

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

-------------------------------------


Chip type           : ATmega8
Program type        : Application
Clock frequency     : 8,000000 MHz
Memory model        : Small
External SRAM size  : 0
Data Stack size     : 256
*****************************************************/

#include <mega8.h>
  unsigned int a;

// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
TCNT0=6;
a++;
if(a==0x9C40) //40000
a=0;
PORTB.0=PORTB.0^1;
}

// Declare your global variables here

void main(void)
{

PORTB=0x00;
DDRB=0xFF;

PORTC=0x00;
DDRC=0x00;


PORTD=0x00;
DDRD=0x00;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 1000,000 kHz
TCCR0=0x02;
TCNT0=0x00;


// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x01;

// Global enable interrupts
#asm("sei")

while (1)
      {
   

      };
}

Re: как получить интервал 1 сек с помошью таймера atmega 8

Добавлено: Вт июл 15, 2014 20:52:44
zsxdcf
извиняюсь
вот сейчас гораздо ниже 1 гц
Спойлер

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

hip type : ATmega8
Program type : Application
Clock frequency : 8,000000 MHz
Memory model : Small
External SRAM size : 0
Data Stack size : 256
*****************************************************/

#include <mega8.h>
 unsigned int a;

// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
TCNT0=6;
a++;
if(a==0x9C40) //40000
{
a=0;
PORTB.0=PORTB.0^1;
}
}

// Declare your global variables here

void main(void)
{

PORTB=0x00;
DDRB=0xFF;

PORTC=0x00;
DDRC=0x00;


PORTD=0x00;
DDRD=0x00;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 1000,000 kHz
TCCR0=0x02;
TCNT0=0x00;


// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x01;

// Global enable interrupts
#asm("sei")

while (1)
 {


 };
}

Re: как получить интервал 1 сек с помошью таймера atmega 8

Добавлено: Вт июл 15, 2014 21:02:32
a_skr
Определитесь с источником тактирования МК. В коде у Вас:
Clock frequency : 8,000000 MHz - соотв. делитель У Вас настраивается на 8. И частота тактирования таймера предполагается 1 Мгц. Частота прерываний переполнений 1000000/250=4кГц. Программно делите на 40000 = 1/10 Гц. Все сходится - меньше 1 Гц.

А в теме Вы пишете 4 МГц. Я Вам дал пример для 1 Гц и 4МГц. Для CodeVision TCCR0=0x03; - делим на 64 - тактирование таймера 62500 Гц.
Делим на 250 (256-6) = 250 Гц. Далее программный счетчик еще на 250 - 1 Гц.

P.S. Естественно, смена уровня на ножке "PORTB ^= 1;" будет вызываться с частотой 1Гц, а меандр на ножке будет 0.5Гц.
Можно померить частоту короткого импульса:
вместо PORTB ^= 1;
записать:
PORTB |= 1;
PORTB &= ~1;