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

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

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

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

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

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

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

 
Опции темы
Непрочитано 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.RU
 
Регистрация: 13.12.2004
Сообщений: 3,172
Сказал спасибо: 11
Сказали Спасибо 692 раз(а) в 504 сообщении(ях)
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.RU
 
Регистрация: 28.02.2010
Сообщений: 2,297
Сказал спасибо: 53
Сказали Спасибо 461 раз(а) в 392 сообщении(ях)
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, время: 19:33.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot