реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Отстает секундомер, ATmega8
LexRoss
сообщение Oct 23 2010, 08:34
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 377
Регистрация: 31-01-09
Пользователь №: 44 202



Отстает секундомер на 2 минуты за полчаса. И в протеусе и в железе примерно так же. Резонатор керамический 1 МГц, ATmega8L. Компилятор WinAvr. Что не так?
Код
#include <avr/io.h>
#define F_CPU 1000000
#include <util/delay.h>
#include <avr/interrupt.h>
#include <string.h>
#include <stdlib.h>
#include <lcd_lib.h>
#include <lcd_lib.c>
#include <avr/signal.h>

unsigned int counter; // счетчик для секундомера: 488 прерываний = 1 секунда
unsigned char sec,minut,hour; // сек.,мин.,часы для секундомера
unsigned char c[5];

ISR(TIMER0_OVF_vect)
{
counter++;
if (counter==488)
{  
   Lcd_Goto(0,0);  
   Lcd_WriteData('t');
   Lcd_WriteData('i');
   Lcd_WriteData('m');
   Lcd_WriteData('e');
   Lcd_WriteData(' ');
   itoa(hour,c,10);
   if (hour<10)
   {
    Lcd_WriteData('0');
    Lcd_WriteData(c[0]);
   }
   else
   {
    Lcd_WriteData(c[0]);
    Lcd_WriteData(c[1]);
   }
   Lcd_WriteData(':');
   itoa(minut,c,10);
   if (minut<10)
   {
    Lcd_WriteData('0');
    Lcd_WriteData(c[0]);
   }
   else
   {
    Lcd_WriteData(c[0]);
    Lcd_WriteData(c[1]);
   }
   Lcd_WriteData(':');
   itoa(sec,c,10);
   if (sec<10)
   {
    Lcd_WriteData('0');
    Lcd_WriteData(c[0]);
   }
   else
   {
    Lcd_WriteData(c[0]);
    Lcd_WriteData(c[1]);
   }
   Lcd_WriteData(' ');
   Lcd_WriteData(' ');
   Lcd_WriteData(' ');
    
  counter=0;                
  sec++;
  
   if (sec==60)
   {
    sec=0;
    minut++;
    if (minut==60)
    {
     minut=0;
       hour++;
    }
   }
}
}


int main (void) {
   Lcd_Init();
   DDRD = 0b00000001;
   sei();
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 125,000 kHz
TCCR0=0x02;
TCNT0=0x00;
TIMSK=0b00000001; // разреш. прерыв. timer0
while (1)
{
}
  return 0;
}

Эскизы прикрепленных изображений
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
kolobok0
сообщение Oct 23 2010, 08:43
Сообщение #2


практикующий тех. волшебник
*****

Группа: Участник
Сообщений: 1 190
Регистрация: 9-09-05
Пользователь №: 8 417



Цитата(LexRoss @ Oct 23 2010, 12:34) *
Отстает секундомер на 2 минуты за полчаса. ...
Код
....
ISR(TIMER0_OVF_vect)
{
....
   Lcd_Goto(0,0);  
   Lcd_WriteData('t');
   Lcd_WriteData('i');
   Lcd_WriteData('m');
....



Загляните в функции вывода на дисплей.
Там увидите либо задержку либо опрос готовности.
Как вы думаете
а) зачем это сделано?
б) сколько это занимает времени?

(круглый)
ЗЫ
Прерывания (особенно железные) - это как выстрел. откидал регистры и забыл(С)
Исключение составляет когда программа сделана по принципу переключения логики. основной код, прерываем - логически переключаемся на другую тему, возвращаемся к нормальному циклу...(надеюсь не сумбурно пояснил исключение smile.gif )
Go to the top of the page
 
+Quote Post
Палыч
сообщение Oct 23 2010, 08:44
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(LexRoss @ Oct 23 2010, 12:34) *
Что не так?

Вероятно, слишком долгое выполнение процедуры прерывания от таймера: вызов всех процедур работы с экраном столь долог, что пропускаются часть прерываний. У Вас бесконечный цикл в main пустой - почему бы не вынести из прерывания в этот цикл вывод на экран.
Go to the top of the page
 
+Quote Post
Vasily_
сообщение Oct 23 2010, 08:53
Сообщение #4


Знающий
****

Группа: Модераторы
Сообщений: 925
Регистрация: 25-01-09
Из: Рига
Пользователь №: 43 909



Секундомер на керамическом резонаторе? забавно! а что кварц нормальный поставить нельзя?
Go to the top of the page
 
+Quote Post
DpInRock
сообщение Oct 23 2010, 08:56
Сообщение #5


Гуру
******

Группа: Участник
Сообщений: 2 254
Регистрация: 4-05-07
Из: Moscow
Пользователь №: 27 515



И когда вынесите процедуру вывода на экран наружу, установите часы минуты секунды как volatile.
Ну, естественно, вывод - по отдельному флагу, тоже volatile. Т.е. некая переменная, которая устанавливается, когда меняется счетчик секунд. В майне вы ея опять в ноль будуте устанавливать после вывода.


--------------------
On the road again (Canned Heat)
Go to the top of the page
 
+Quote Post
LexRoss
сообщение Oct 23 2010, 09:17
Сообщение #6


Местный
***

Группа: Свой
Сообщений: 377
Регистрация: 31-01-09
Пользователь №: 44 202



Вынес вывод на экран в main. Вроде лучше стало.
Керамический резонатор, т.к. другого не нашел. Питание от батарейки, поэтому 1мгц.
Цитата
И когда вынесите процедуру вывода на экран наружу, установите часы минуты секунды как volatile.

Зачем volatile ?
Цитата
Ну, естественно, вывод - по отдельному флагу, тоже volatile. Т.е. некая переменная, которая устанавливается, когда меняется счетчик секунд. В майне вы ея опять в ноль будуте устанавливать после вывода.

Ничего не понял sad.gif

Теперь даже спешат немного. За полчаса на 15сек.
Go to the top of the page
 
+Quote Post
DpInRock
сообщение Oct 23 2010, 10:00
Сообщение #7


Гуру
******

Группа: Участник
Сообщений: 2 254
Регистрация: 4-05-07
Из: Moscow
Пользователь №: 27 515



Ну, вообще-то математика доступная.
Резонатор 0.5% точности. 0.2% температурной нестабильности. Еще вы конденсаторами его придавили. Предположим, 1%

Полчаса = 1800 сек. 1% = 18 секунд.

А про volatile - рекомендую почитать на форуме. Очень полезная вещь.


--------------------
On the road again (Canned Heat)
Go to the top of the page
 
+Quote Post
kolobok0
сообщение Oct 23 2010, 10:01
Сообщение #8


практикующий тех. волшебник
*****

Группа: Участник
Сообщений: 1 190
Регистрация: 9-09-05
Пользователь №: 8 417



Цитата(LexRoss @ Oct 23 2010, 13:17) *
..Теперь даже спешат немного. За полчаса на 15сек.


это уже похоже на резонатор(ставте кварц, нафик вам гимор то?) либо чистоту кода (ну там всякие блокировки прерываний не вовремя и прочая шняга).

(круглый)
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Oct 23 2010, 11:09
Сообщение #9


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(DpInRock @ Oct 23 2010, 14:00) *
А про volatile - рекомендую почитать на форуме. Очень полезная вещь.
Даже больше - необходимая!


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
chief_olimp
сообщение Oct 23 2010, 13:08
Сообщение #10


Местный
***

Группа: Участник
Сообщений: 249
Регистрация: 31-10-05
Из: Украина Нетешин
Пользователь №: 10 344



Цитата(LexRoss @ Oct 23 2010, 12:17) *
Питание от батарейки, поэтому 1мгц.
Дело в том, что 1 Мгц не совсем хороший кварц для этих целей. Чаще используют кварцы 1.8432, 2.4576, 3.2768 ... На таких кварцах отсутствует погрешнось в временных диапазонах. Ну неточность и температурный дрейф не в счет. Ну или программную коррекцию вводите.
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Oct 23 2010, 13:56
Сообщение #11


Профессионал
*****

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



Почему бы просто не задействоать асинхронный таймер с 32,768 Кгц если уж стоит задача СЕКУНДОМЕР


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post
LexRoss
сообщение Oct 23 2010, 14:41
Сообщение #12


Местный
***

Группа: Свой
Сообщений: 377
Регистрация: 31-01-09
Пользователь №: 44 202



Цитата(ILYAUL @ Oct 23 2010, 17:56) *
Почему бы просто не задействоать асинхронный таймер с 32,768 Кгц если уж стоит задача СЕКУНДОМЕР

На самом деле будет велокомпьютер. 32,768 в данном случае мало.
Сейчас положу в холодильник, посмотрю как будет плавать от температуры, если не сильно, то программно подкорректирую.
Go to the top of the page
 
+Quote Post
Xenia
сообщение Oct 23 2010, 15:01
Сообщение #13


Гуру
******

Группа: Модератор FTP
Сообщений: 4 479
Регистрация: 20-02-08
Из: Москва
Пользователь №: 35 237



Ваши часы шли бы точнее, если бы вы нормально запрограммировали таймер на 1-секундный период, а не гоняли его по полтыщи раз в холостую, каждый раз вызывая тормозное прерывание.
Go to the top of the page
 
+Quote Post
ukpyr
сообщение Oct 23 2010, 15:02
Сообщение #14


Профессионал
*****

Группа: Участник
Сообщений: 1 264
Регистрация: 17-06-08
Из: бандустан
Пользователь №: 38 347



сначала измените программу - в прерывании таймера 3 вызова itoa (мягко говоря небыстрой функции) и куча обращений к LCD. Вынесите все это в основной цикл. Заведите переменную - флаг обновления LCD, в прерывании пишите туда 1, в основном цикле проверяйте это значение, спокойно обновляйте индикацию и переходите в Sleep.
Еще - обновлять индикацию нужно после инкремента секунд-минут а не перед этим.

Сообщение отредактировал ukpyr - Oct 23 2010, 15:03
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Oct 23 2010, 15:07
Сообщение #15


Профессионал
*****

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



Цитата(LexRoss @ Oct 23 2010, 18:41) *
32,768 в данном случае мало.

Не понял , как так может быть , что вдруг для секундомера стало мало часового кварца ?


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 23rd June 2025 - 12:47
Рейтинг@Mail.ru


Страница сгенерированна за 0.01481 секунд с 7
ELECTRONIX ©2004-2016