Свежие обсуждения
Микроконтроллеры

А таймер реального времени ATMega128

1 2 4

Либо вариант - считаете, сколько полных переполнений в заданном периоде, грузите разницу между общим временем и 65536*число_переполнений, отсчитываете первый короткий период, а затем работаете по переполнениям.
PS. Почти то же, что предложил GM, только короткий - спереди.

 

Или настроить таймер на прерывания с частотой 1КГц, и увеличивать/уменьшать счётчик в прерывании.

 

раз часы не предусмотрены тогда - как я делаю:
1. использую кварц 7.372800
2. запускаю прогу "CodeVisionAVR C Compiler Evaluation"
3. Делаю настройки таймеров и всё копирую в проект.
Инструмент дело полезное. А вручную расчитывать , может и интересно,
но времени жалко.
Удачи.
п.с.
Если "CodeVisionAVR C Compiler Evaluation" не найдёшь , пиши в личку.

 

всем спасибо буду играцо
))

 

мдяс... все сделал... только таймер неточно работает

тормозит как будто...

кто знает что может быть?

 

Исходник выложите.

 

#include <mega128.h>

#asm
.equ __lcd_port=0x03 ;PORTE
#endasm
#include <lcd.h>
#include <stdio.h>
#include <delay.h>
int j,i=0;
char buff[10];
// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{

// Reinitialize Timer 0 value
lcd_putsf("f");
}

// Timer 1 overflow interrupt service routine
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
// Place your code here
TCNT1H=0xF7;
TCNT1L=0x2C;

j++;
if ((j%10)==0) {
lcd_clear();
sprintf(buff,"%d",j);
lcd_puts(buff);
}

}

void main(void)
{
// Declare your local variables here

PORTA=0x00;
DDRA=0x00;

PORTB=0x00;
DDRB=0x00;

PORTC=0x00;
DDRC=0x00;

PORTD=0x00;
DDRD=0x00;

PORTE=0x00;
DDRE=0x00;

PORTF=0x00;
DDRF=0xFF;

PORTG=0x00;
DDRG=0x00;

// Timer/Counter 0 initialization
// Clock source: TOSC1 pin
// Clock value: TOSC1/1024
// Mode: Normal top=FFh
// OC0 output: Disconnected
ASSR=0x08;
TCCR0=0x07;
TCNT0=0x00;
OCR0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 16,883 kHz
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// OC1C output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: On
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
// Compare C Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x04;
TCNT1H=0xF7;
TCNT1L=0x2C;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
OCR1CH=0x00;
OCR1CL=0x00;

EICRA=0x00;
EICRB=0x00;
EIMSK=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x05;
ETIMSK=0x00;

// LCD module initialization
lcd_init(20);

// Global enable interrupts
#asm("sei")
lcd_putsf("Ya Krevedko");
while (1)
{

};
}

Вот код... таймер 0 вообще не работает не понимаю почему

а по таймеру 1 - тормоза

кварц 4.322 МГц

 

Нескромный вопрос - почему вместо Compare match interrupt в таймере 1 используется экзотика с overflow? Из-за того, что между возникновением сигнала прерывания и вот этим присваиванием:
// Place your code here
TCNT1H=0xF7;
TCNT1L=0x2C;
выполняется некоторая кучка команд, у вас набегает систематическая погрешность. Мало того, вы из обработчика прерываний еще и на ЖКИ данные выводите. Это - тормоз еще тот, не исключено, что у вас вообще каждое 10-е прерывание от таймера просто-напросто теряется. Перепишите работу с таймером на Compare match и ничего лишнего в обработчиках не делайте (в том числе не считайте остаток от деления - команды деления в микроконтроллере нет, а программного кода для вычисления остатка там может быть вообще километр).

 

BCluster: Вот код... таймер 0 вообще не работает не понимаю почему
И не будет работать, если нет кварца на ногах pg3, pg4, поскольку этой командой ASSR=0x08 вы подключили его к этим ногам.

По таймеру 1. Не надо клок для таймера делить на 256, а потом бороться с кривыми временами. Если у вас частота системного клока 4322000 Гц, делите на 43220, в таймер1 надо записать 65536-43220=22316 (0х572С), таймер1 позволяет, получите частоту прерывания 10 Гц , т.е. требуемые 0.1 с, если не хотите делать, как chav1961 подсказал.

И не пишите lcd_putsf("Ya Krevedko") - это моветон, пишите лучше lcd_putsf("Держы дестанцею, Кросавчег") .

 

Compate Match - прерывание по сравнению с заданным значением... Вопрос - после того как происходит это прерывание, счетчик разве сбрасывается?
И ыще, я хоть там напишу PORTF=(PORTF^(17)) штоп мигать светодиодом все равно тормозить будет

Насчет команды деления... Может я не прав, но умножение и деление не одно и тоже ??

Дальше... Кварц висит на TOSC1...

4322000/43220 = 100 а не 10... и я на 256 не делю... там просто остались комменты... делил на 8

Дальше... Самое интереснойе - все заработало, заменил кварц на 12 мГц. Все тютелька в тютельку пашед...