Реклама на сайте DatasheetsDatasheets

KAZUS.RUN - Электронный портал. Принципиальные схемы, Datasheets, Форум по электронике

Новости электроники Новости Литература, электронные книги Литература Документация, даташиты Документация Поиск даташитов (datasheets)Поиск PDF
  От производителей
Новости поставщиков
В мире электроники

  Сборник статей
Книги и журналы
FAQ по электронике

  Datasheets
Поиск SMD
Онлайн справочник

Принципиальные схемы Схемы Каталоги программ, сайтов Каталоги Общение, форум Общение Ваш аккаунтАккаунт
  Каталог схем
Схемы и проекты
Принципиальные схемы
  Программы
Каталог сайтов
Калькуляторы
  Форумы по электронике
Помощь проекту

Микроконтроллеры, АЦП, память и т.д Темы касающиеся микроконтроллеров разных производителей, памяти, АЦП/ЦАП, периферийных модулей...

 
Опции темы

Тахометр и спидометр на Atmega8l

Непрочитано 29.06.2010, 18:54  
GMVM
Прохожий
 
Регистрация: 29.06.2010
Сообщений: 8
Сказал спасибо: 2
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
GMVM на пути к лучшему
По умолчанию Тахометр и спидометр на Atmega8l

Здравствуйте! Нашел дома мегу8 и решил сделать тахометр и спидометр для скутера с отображением на LCD.Набросал программку и сделал модель в протеусе.Датчик с колеса подключается к ICP,с коленвала к INT1. Но столкнулся с проблемой:при работе 2 датчиков одновременно,спидометр выдает не корректные данные через небольшие промежутки времени.(т.е сначала данные правильные, а потом выскакивает число в1.5-2 раза больше, потом снова все норм).Тахометр выдает вообще рандомные числа.

Код:
#include ‹mega8.h›
#asm
.equ __lcd_port=0x12 ;PORTD
#endasm
#include ‹lcd.h›
#include ‹io.h›
#include ‹delay.h›
#include ‹stdio.h›

unsigned char OverflowC,OverflowC1;
unsigned long Edge1,Edge2;
unsigned long x,freq;

char buffer[20];
int i=1,i_int1=1;

void welcome(void)
{
lcd_gotoxy(4,0);
lcd_putsf("Digital");
lcd_gotoxy(7,1);
lcd_putsf("CDI ");
}

interrupt[9] void over(void)
{
OverflowC1++;
OverflowC++;
}

interrupt[6] void cap_icp(void)
{

if(i!=0)
{

Edge1=ICR1;
i=0;
//TCNT1=0;
OverflowC=0;
}
else
{
i=1;
Edge2=ICR1;
x=(unsigned long)Edge2-
(unsigned long)Edge1+
(unsigned long)OverflowC*0x10000;
freq=1000000*1.5*3.6/x;
sprintf(buffer,"%d",x);
lcd_gotoxy(4,2);
lcd_puts(buffer);
sprintf(buffer,"%u Km/h",freq);
lcd_gotoxy(4,3);
lcd_puts(buffer);
delay_ms(30);
}
}
interrupt[3] void int1_capture(void)
{
unsigned long T,f,Time1,Time2;

if(i_int1!=0)
{
Time1=TCNT1;
i_int1=0;
}
else
{
Time2=TCNT1;
i_int1=1;
T=(unsigned long)Time2-(unsigned long)Time1+(unsigned long)OverflowC*0x10000;
f=(unsigned long)10000000/T;
sprintf(buffer,"%u",f);
lcd_gotoxy(12,3);
lcd_puts(buffer);
}
}

void main(void)
{
lcd_init(20);
welcome();
DDRC=0xFF; // c- выход
TCCR1B=0xc2;; //подавление помех,icp по нараст., тс\1 вкл
TIMSK=0x24; //по ovf tc/1, icp
MCUCR=0x8;//int1 +
GICR=0x80;// int1 enable
#asm("SEI");
while (1);

}


Реально ли вообще организовать два устройства на одном контроллере?
Вложения:
Тип файла: rar Proteus.rar (18.9 Кб, 223 просмотров)
Реклама:
GMVM вне форума  
Непрочитано 29.06.2010, 19:40  
Vetal-soft
Временная регистрация
 
Регистрация: 04.08.2006
Сообщений: 67
Сказал спасибо: 2
Сказали Спасибо 20 раз(а) в 11 сообщении(ях)
Vetal-soft на пути к лучшему
По умолчанию Re: Тахометр и спидометр на Atmega8l

Сообщение от GMVM Посмотреть сообщение
Реально ли вообще организовать два устройства на одном контроллере?
Реально, но...
Нужно чтобы весь вывод на LCD находился в main и ни одного в прерываниях !!!
Vetal-soft вне форума  
Непрочитано 29.06.2010, 19:48  
kison
Почётный гражданин KAZUS.RUN
 
Регистрация: 13.12.2004
Сообщений: 3,168
Сказал спасибо: 11
Сказали Спасибо 691 раз(а) в 503 сообщении(ях)
kison на пути к лучшему
По умолчанию Re: Тахометр и спидометр на Atmega8l

Более того - умножать/делить переменные в плавучке тоже неплохо вне обработчиков.
Это же относится и к функции sprintf.
kison вне форума  
Непрочитано 30.06.2010, 18:35  
GMVM
Прохожий
 
Регистрация: 29.06.2010
Сообщений: 8
Сказал спасибо: 2
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
GMVM на пути к лучшему
По умолчанию Re: Тахометр и спидометр на Atmega8l

Переделал код. Под вывод в main. Но число f все-равно "пляшет".Что я делаю не так?



#include ‹mega8.h›
#asm
.equ __lcd_port=0x12 ;PORTD
#endasm
#include ‹lcd.h›
#include ‹io.h›
#include ‹delay.h›
#include ‹stdio.h›

unsigned int OverT0;
unsigned long f;
unsigned long Time2;

char buffer[20];
char i_int1=0,access=0;

void welcome(void)
{
#asm("cli");
lcd_gotoxy(4,0);
lcd_putsf("Digital");
lcd_gotoxy(7,1);
lcd_putsf("CDI ");
if(access==1){
f=(unsigned long)Time2+(unsigned long)OverT0*0x100;
access=0;
sprintf(buffer,"%d",f);
lcd_puts(buffer);
}
delay_ms(3);
#asm("SEI");
}


interrupt[10] void tim0_ovf(void)
{
OverT0++;
}


interrupt[3] void int1_capture(void)
{
if(i_int1!=1)
{

TCNT0=0;
OverT0=0;
i_int1=1;

}
else
{

Time2=TCNT0;
i_int1=0;
access=1;
}

}

void main(void)
{

lcd_init(20);

TIMSK=0x1;
MCUCR=0x8;
TCCR0=0x2;
GICR=0x80;
#asm("SEI");
while (1)
{
welcome();
};

}
GMVM вне форума  
Непрочитано 30.06.2010, 18:49  
MasterMushi
Вид на жительство
 
Регистрация: 14.10.2009
Сообщений: 338
Сказал спасибо: 35
Сказали Спасибо 92 раз(а) в 73 сообщении(ях)
MasterMushi на пути к лучшему
По умолчанию Re: Тахометр и спидометр на Atmega8l

Виноват (подозреваю) датчик. Какого он у тебя типа? Геркон? или оптический? или датчик холла?

Если геркон, то у тебя нет контроля дребезга в программе! А подозреваю что и на входе аппаратного анти-дребезга тоже нет. Добавь на ноги которые идут блипы от датчика подтяжку 10к на +Пит. и кондер 47-100nF на землю. Это конечно ограничит максимальную скорость до 400-500 километров в час, но думаю тебе это не критично ))))
__________________
Найди путь или проложи сам!
MasterMushi вне форума  
Непрочитано 30.06.2010, 18:52  
OlegNZH
Почётный гражданин KAZUS.RUN
 
Регистрация: 28.02.2010
Сообщений: 2,294
Сказал спасибо: 52
Сказали Спасибо 460 раз(а) в 391 сообщении(ях)
OlegNZH на пути к лучшему
По умолчанию Re: Тахометр и спидометр на Atmega8l

Вы попробуйте оценить время выполнения welcome() (или на отладчике,или в железе)- у Вас-же прерывания разрешаются всего на несколько тактов,в момент вызова welcoma - не могут ли прерывания "сдвоиться" во время запрета?тогда одно будет потеряно.
OlegNZH вне форума  
Непрочитано 30.06.2010, 19:25  
Vetal-soft
Временная регистрация
 
Регистрация: 04.08.2006
Сообщений: 67
Сказал спасибо: 2
Сказали Спасибо 20 раз(а) в 11 сообщении(ях)
Vetal-soft на пути к лучшему
По умолчанию Re: Тахометр и спидометр на Atmega8l

1. Переменные которые изменяются в прерывании должны объявляться с модификатором volatile.
2. Функцию welcome упразднить, а ее код перенести в main.
3. Основная причина глюков. У вас постоянно глобально включаются и выключаются прерывания.
4. Когда выкладываете на форуме код, используйте для этого теги CODE. Символ решетки в расширенном режиме отправки сообщений.

Добавил:
5. Скромные комментарии в коде не лишне.

Последний раз редактировалось Vetal-soft; 30.06.2010 в 19:28.
Vetal-soft вне форума  
Непрочитано 01.07.2010, 22:39  
GMVM
Прохожий
 
Регистрация: 29.06.2010
Сообщений: 8
Сказал спасибо: 2
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
GMVM на пути к лучшему
По умолчанию Re: Тахометр и спидометр на Atmega8l

Прогу переделал. Теперь значения не прыгают. Но появилась проблема:
у меня стоит деление 1/8 на таймере. Частота проца=8Мгц. Соответственно при подаче импульсов на вход с частотой 100Гц, счетчик должен считать до 10000. Но у меня считает только до 78!. В чем может быть проблема?
Код:
Код:
#include ‹mega8.h›

// Alphanumeric LCD Module functions
#asm
   .equ __lcd_port=0x12 ;PORTD
#endasm
#include ‹lcd.h›
#include ‹stdio.h›
#include ‹delay.h›

unsigned long r;
volatile unsigned long f,TC0_ovf;
char buffer[20];


 

 

// External Interrupt 1 service routine
interrupt [EXT_INT1] void ext_int1_isr(void)
{
 if(TCCR0==0x0)       //если тс\0 выключен
 {
  TCNT0=0;            //обнуляем счетчик
  TC0_ovf=0;         // и счетчик переполнений
  TCCR0=0x05;        // включаем счетчик
 } 
 else
 {
  TCCR0=0;          //  выключаем счетчик
  f=TCNT0;          // считываем показания
  }
}
// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
TC0_ovf++;   //счетчик переполнений
}


void main(void)
{

// Input/Output Ports initialization
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTB=0x00;
DDRB=0x00;

// Port C initialization
// Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTC=0x00;
DDRC=0x00;

// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTD=0x00;
DDRD=0x00;

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


// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: On
// INT1 Mode: Rising Edge
GICR|=0x80;
MCUCR=0x0C;
GIFR=0x80;

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

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;

// LCD module initialization
lcd_init(20);


#asm("SEI");

while (1)
  {
                                          
    r=(unsigned long)f+(unsigned long)TC0_ovf*0x100;    // находим суммарное значение счетчика
    r=(unsigned long)1000000/r;                        // вычисляем частоту
    sprintf(buffer,"HZ %u",r);                          // записываем ее в буфер
    lcd_clear();
    lcd_gotoxy(1,0);
    lcd_puts(buffer);
    delay_ms(300);
 
  }
}
GMVM вне форума  
Непрочитано 02.07.2010, 23:46  
oleg_harp
Прописка
 
Регистрация: 25.08.2007
Сообщений: 193
Сказал спасибо: 11
Сказали Спасибо 57 раз(а) в 33 сообщении(ях)
oleg_harp на пути к лучшему
По умолчанию Re: Тахометр и спидометр на Atmega8l

Сообщение от GMVM Посмотреть сообщение
у меня стоит деление 1/8 на таймере
У Вас 1/1024
Сообщение от GMVM Посмотреть сообщение
TCCR0=0x05; // включаем счетчик
В этом и ошибка.
oleg_harp вне форума  
Непрочитано 04.07.2010, 16:01  
GMVM
Прохожий
 
Регистрация: 29.06.2010
Сообщений: 8
Сказал спасибо: 2
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
GMVM на пути к лучшему
По умолчанию Re: Тахометр и спидометр на Atmega8l

Спасибо! Не заметил.

Опять возникла проблема..вожусь уже пол дня. Делаю задержку циклом. Если задержка внутри условия if в main(), все работает нормально, но если цикл в самой main() то значения на экране опять начинают "прыгать".
Код:
#include ‹mega8.h›

// Alphanumeric LCD Module functions
#asm
   .equ __lcd_port=0x18 ;PORTD
#endasm
#include ‹lcd.h›
#include ‹stdio.h›
#include ‹delay.h›

unsigned long r,i;
volatile unsigned long f,TC0_ovf;
char buffer[20];


 

 

// External Interrupt 1 service routine
interrupt [EXT_INT1] void ext_int1_isr(void)
{
 if(TCCR0==0x0)       //если тс\0 выключен
 {
  TCNT0=0;            //обнуляем счетчик
  TC0_ovf=0;         // и счетчик переполнений
  TCCR0=0x02;        // включаем счетчик
 } 
 else
 {
  TCCR0=0;          //  выключаем счетчик
  f=TCNT0;          // считываем показания
  }
}
// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
TC0_ovf++;   //счетчик переполнений
}


void main(void)
{

// Input/Output Ports initialization
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTB=0x00;
DDRB=0x00;

// Port C initialization
// Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTC=0x00;
DDRC=0xFF;

// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTD=0x00;
DDRD=0x00;

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


// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: On
// INT1 Mode: Rising Edge
GICR|=0x80;
MCUCR=0x0C;
GIFR=0x80;

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

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;

// LCD module initialization
lcd_init(20);


#asm("SEI");

while (1)
  {
    if(f›0)
    { 
      r=1000000/((unsigned long)f+(unsigned long)TC0_ovf*0x100);    // находим суммарное значение счетчика вычисляем частоту
      sprintf(buffer,"HZ %u",r);
                                           // записываем ее в буфер
      i=0xfff;
      while(i›0)     //задержка 
      {
        i--;
      }
    f=0;
    }
    lcd_gotoxy(1,0);
    lcd_puts(buffer);
      
   
   
  }
}
GMVM вне форума  
 
Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Спидометр SunriseMoto Электроника средств транспорта 18 13.05.2010 17:57
Тахометр sserg_ey Электроника средств транспорта 1 08.04.2010 09:21
Помогите с Фузи битами ATmega8L ewgen404 Микроконтроллеры, АЦП, память и т.д 2 03.03.2010 02:12
Как переключить ATmega8L на внешний кварц? ewgen404 Микроконтроллеры, АЦП, память и т.д 1 01.03.2010 22:15
Тахометр для А/М ДенIS Электроника средств транспорта 3 26.10.2009 18:47


Часовой пояс GMT +4, время: 01:34.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.