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

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

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

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

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

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

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

 
Опции темы
Непрочитано 29.07.2010, 01:27  
GRTH32
Частый гость
 
Регистрация: 17.11.2009
Адрес: Владивосток
Сообщений: 18
Сказал спасибо: 2
Сказали Спасибо 1 раз в 1 сообщении
GRTH32 на пути к лучшему
По умолчанию Помогите пожалуйста разобраться с частотным дискриминатором

Суть в чем: Нужно устройство которое про подаче на вход частоты больше 133 Гц зажигает светодиод.

Пытаюсь реализовать на ATTiny13

Логика следующая:
так как счетчик/таймер один то:
каждый такт плюсуем i++ (long int)

Прерывание на модуле совпадения таймера при совпадении на 0x85 (133)

в прерывании сравниваем i c тактовой частотой.
Если i больше тактовой, значит частота меньше 133
обнуляем i, TCNT0
PORTB.0=1

Иначе
обнуляем i, TCNT0
PORTB.0=0

Схема - проще некуда PortB.0 - выход, светодиод, PortB.2 - вход, счетчик/таймер

И ведь не рабатает. =(

Код:

interrupt [TIM0_COMPA] void timer0_compa_isr(void)
{
if (i›9600000)
{
PORTB.0=1;
i=0;
TCNT0=0x00;
}

else
{
PORTB.0=0;
i=0;
TCNT0=0x00;
};


}

#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif

PORTB=0x01;
DDRB=0x01;
TCCR0A=0x00;
TCCR0B=0x07;
TCNT0=0x00;
OCR0A=0x85;
OCR0B=0x00;
GIMSK=0x00;
MCUCR=0x00;

TIMSK0=0x0C;

ACSR=0x80;
ADCSRB=0x00;

#asm("sei")

while (1)
{
#asm("cli")

i++;

#asm("sei")
};
}
Реклама:

Последний раз редактировалось GRTH32; 29.07.2010 в 02:23. Причина: Обновил код
GRTH32 вне форума  
Непрочитано 29.07.2010, 01:45  
kison
Почётный гражданин KAZUS.RU
 
Регистрация: 13.12.2004
Сообщений: 3,172
Сказал спасибо: 11
Сказали Спасибо 692 раз(а) в 504 сообщении(ях)
kison на пути к лучшему
По умолчанию Re: Помогите пожалуйста разобраться с компаратором.

Сообщение от GRTH32 Посмотреть сообщение
каждый такт плюсуем i++ (long int)
Вы действительно думаете что увеличение 4-х байтной переменной можно сделать за 1 такт? Запустите в симуляторе, ну хоть в той же студии и посмотрите как на самом деле. Повезет если за 4 такта идет увеличение. Ну и повторить - это переход еще 2 такта. И все равно Ваш метод плохо применим - на время увеличения переменной надо запрещать прерывания.
И смените название темы - компаратор и модуль совпадения таймера совсем разные устройства.
kison вне форума  
Непрочитано 29.07.2010, 02:23  
GRTH32
Частый гость
 
Регистрация: 17.11.2009
Адрес: Владивосток
Сообщений: 18
Сказал спасибо: 2
Сказали Спасибо 1 раз в 1 сообщении
GRTH32 на пути к лучшему
По умолчанию Re: Помогите пожалуйста разобраться с компаратором.

Спасибо. Просто я новичек в деле освоения микроконтроллеров.
Да и в программировании тоже.
МОжет у Вас будет вариант более оптимально кода?
Как можно узнать, за сколько тактов происходит инкриминация?
--- Наверное можно попробовать загнать в AVR Studio и прогнать по шагам...
Да в железе пока и не собирал. Гоняю в протеусе.
Добавил запрет прерывания.
Посчитав количество тактов можно будет подобрать нужное значение i.
Просто инетерсно сделать именно на это микросхеме. На тини25 конечно проще.

Последний раз редактировалось GRTH32; 29.07.2010 в 02:26.
GRTH32 вне форума  
Непрочитано 29.07.2010, 02:50  
kison
Почётный гражданин KAZUS.RU
 
Регистрация: 13.12.2004
Сообщений: 3,172
Сказал спасибо: 11
Сказали Спасибо 692 раз(а) в 504 сообщении(ях)
kison на пути к лучшему
По умолчанию Re: Помогите пожалуйста разобраться с компаратором.

Сообщение от GRTH32 Посмотреть сообщение
МОжет у Вас будет вариант более оптимально кода?
А Вы задачу распишите подробно. Не забудьте указать диапазон частоты, которая может быть подана на вход. Ну и приемлемую ошибку определения порога срабатывания - типа +-1Гц или +-5Гц.
Сообщение от GRTH32 Посмотреть сообщение
Наверное можно попробовать загнать в AVR Studio и прогнать по шагам...
Конечно, это сразу расставит точки над е.
kison вне форума  
Непрочитано 29.07.2010, 03:01  
GRTH32
Частый гость
 
Регистрация: 17.11.2009
Адрес: Владивосток
Сообщений: 18
Сказал спасибо: 2
Сказали Спасибо 1 раз в 1 сообщении
GRTH32 на пути к лучшему
По умолчанию Re: Помогите пожалуйста разобраться с компаратором.

Задача в следующем - в целях освоения микроконтроллеров я хочу сделать схему, которая будет зажигать светодиод при оборотах коленвала в районе 8000 об.м
Соответственно минимальные обороты 1000об.м (16Гц), срабатывание 8000об.м (133Гц), максимальные 12000 (200Гц).
Приемлимая ошибка... примерно +-200 об.мин, те 3Гц
Схема и обвязка пока меня не интересуют. Хочу отладить логику и программу.

Инкриминация происходит за 39тактов. Те моё i надо делить как минимум на 39 (блин, еще же переход на прерывание, обработка и выход... пойду дальше мучать студию...). и еще:
Не смотря на то, что в проекте CodeVisionAVR выставлена частота 9.МГц, AVR Studio указал 4МГц. Где искать ошибку?

Последний раз редактировалось GRTH32; 29.07.2010 в 03:03.
GRTH32 вне форума  
Непрочитано 29.07.2010, 03:58  
MasterMushi
Вид на жительство
 
Регистрация: 14.10.2009
Сообщений: 338
Сказал спасибо: 35
Сказали Спасибо 92 раз(а) в 73 сообщении(ях)
MasterMushi на пути к лучшему
По умолчанию Re: Помогите пожалуйста разобраться с компаратором.

GRTH32,
Ну, начнем с простого - зачем компаратор?

Построй логику так. У нас есть наша частота теоретическая вращения коленвала.
К примеру это 10000 оборотов

У нас есть таймер. Таймер выставляем на частоту обороты * 2 или лучше *3
Тоесть частота повторов должна быть к примеру 30000 прерываний в секунду. так как прерывание само по себе отбирает порядка 20 тактов, то нужно частоту микроконтроллера выбрать с запасом это

30000*20 + 1мгц= 1.6Мгц Этого будет достаточно для нормальной удобной и экономичной работы. Если нет на 1.6 то можно поставить 2 или 4 мгц. Нам важно просто иметь запас.

Так вот в каждом прерывании по таймеру мы плюсуем i

PORTB.1 мы устанавливаем как ПРЕРЫВАНИЕ (задействуем функцию INT0)

На эту ногу подключаем датчик с вала.

Теперь что делаем в программе...

Мы смотрим по прерыванию от датчика сколько у нас i если меньше трех то загораем светодиод.


PHP код:

#include ‹tiny13.h›

unsigned int i=0;

//Прерывание от данных пришедших с вала двигателя
interrupt [EXT_INT0void ext_int0_isr(void)
{

 if (
‹ 3//если i не успевает приплюсоваться до трех значит частота на валу Больше чем ограничение.
    
PORTB.0=1;
 else 
PORTB.0=0;
 
i=0//наплюсовали - надо  снулить нашу i дабы снова она начала плюсоваться

}

// Прерывание по таймеру 25 килогерц проц 1.60 мегагерц
interrupt [TIM0_OVFvoid timer0_ovf_isr(void)
{
TCNT0=0x01;
i++;
if (
›= 65535i=0;
}


void main(void)
{
// Crystal Oscillator division factor: 1
#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif

PORTB=0x00;
DDRB=0b01//PORTB.0 у нас будет выходом на светодиод

// Организуем таймер на: 25,000 kHz
TCCR0A=0x00;
TCCR0B=0x03;
TCNT0=0x01;
OCR0A=0x00;
OCR0B=0x00;

// Зададим выпадание в прерывание если идет падающий сигнал от датчика на валу
GIMSK=0x40;
MCUCR=0x02;
GIFR=0x40;


Прочее
TIMSK0
=0x02;
ACSR=0x80;
ADCSRB=0x00;

#asm("sei")

while (1)
      {
//Траляля три рубля =))) Нифига тут нам не надо         
      
};

__________________
Найди путь или проложи сам!

Последний раз редактировалось MasterMushi; 29.07.2010 в 04:00.
MasterMushi вне форума  
Непрочитано 29.07.2010, 04:34  
kison
Почётный гражданин KAZUS.RU
 
Регистрация: 13.12.2004
Сообщений: 3,172
Сказал спасибо: 11
Сказали Спасибо 692 раз(а) в 504 сообщении(ях)
kison на пути к лучшему
По умолчанию Re: Помогите пожалуйста разобраться с компаратором.

Сообщение от GRTH32 Посмотреть сообщение
Соответственно минимальные обороты 1000об.м (16Гц), срабатывание 8000об.м (133Гц), максимальные 12000 (200Гц).
Это мотоцикл?
Измеряйте период, а не частоту. Дальше скользящее среднее по 4-8 отсчетам, сравнение и индикация превышения если нужно.
kison вне форума  
Непрочитано 29.07.2010, 07:06  
GRTH32
Частый гость
 
Регистрация: 17.11.2009
Адрес: Владивосток
Сообщений: 18
Сказал спасибо: 2
Сказали Спасибо 1 раз в 1 сообщении
GRTH32 на пути к лучшему
По умолчанию Re: Помогите пожалуйста разобраться с компаратором.

Сообщение от MasterMushi Посмотреть сообщение
GRTH32,
Ну, начнем с простого - зачем компаратор?

Построй логику так. У нас есть наша частота теоретическая вращения коленвала.
К примеру это 10000 оборотов

У нас есть таймер. Таймер выставляем на частоту обороты * 2 или лучше *3
Тоесть частота повторов должна быть к примеру 30000 прерываний в секунду. так как прерывание само по себе отбирает порядка 20 тактов, то нужно частоту микроконтроллера выбрать с запасом это

30000*20 + 1мгц= 1.6Мгц Этого будет достаточно для нормальной удобной и экономичной работы. Если нет на 1.6 то можно поставить 2 или 4 мгц. Нам важно просто иметь запас.

Так вот в каждом прерывании по таймеру мы плюсуем i

PORTB.1 мы устанавливаем как ПРЕРЫВАНИЕ (задействуем функцию INT0)

На эту ногу подключаем датчик с вала.

Теперь что делаем в программе...

Мы смотрим по прерыванию от датчика сколько у нас i если меньше трех то загораем светодиод.


PHP код:

#include ‹tiny13.h›

unsigned int i=0;

//Прерывание от данных пришедших с вала двигателя
interrupt [EXT_INT0void ext_int0_isr(void)
{

 if (
‹ 3//если i не успевает приплюсоваться до трех значит частота на валу Больше чем ограничение.
    
PORTB.0=1;
 else 
PORTB.0=0;
 
i=0//наплюсовали - надо  снулить нашу i дабы снова она начала плюсоваться

}

// Прерывание по таймеру 25 килогерц проц 1.60 мегагерц
interrupt [TIM0_OVFvoid timer0_ovf_isr(void)
{
TCNT0=0x01;
i++;
if (
›= 65535i=0; - [COLOR="#ff0000"]этокак я понимаюна случай очень низкой частоты?[/COLOR]
}


void main(void)
{
// Crystal Oscillator division factor: 1
#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif

PORTB=0x00;
DDRB=0b01//PORTB.0 у нас будет выходом на светодиод

// Организуем таймер на: 25,000 kHz
TCCR0A=0x00;
TCCR0B=0x03;
TCNT0=0x01; [COLOR="Red"]- это компенсация какого-то такта?[/COLOR]
OCR0A=0x00;
OCR0B=0x00;

// Зададим выпадание в прерывание если идет падающий сигнал от датчика на валу
GIMSK=0x40;
MCUCR=0x02;
GIFR=0x40;


Прочее
TIMSK0
=0x02;
ACSR=0x80;
ADCSRB=0x00;

#asm("sei")

while (1)
      {
//Траляля три рубля =))) Нифига тут нам не надо         
      
};

Построй логику так. У нас есть наша частота теоретическая вращения коленвала.
К примеру это 10000 оборотов - немного не верно - 10000об = 10000/60 = 166.(6)Гц

У нас есть таймер. Таймер выставляем на частоту обороты * 2 или лучше *3
Тоесть частота повторов должна быть к примеру 30000 прерываний в секунду. Те тут несколько перебор с прерываниями... так как прерывание само по себе отбирает порядка 20 тактов, то нужно частоту микроконтроллера выбрать с запасом это


// Прерывание по таймеру 25 килогерц проц 1.60 мегагерц
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
TCNT0=0x01;
i++;
if (i ›= 65535) i=0; - это, как я понимаю, на случай очень низкой частоты?
}


// Организуем таймер на: 25,000 kHz
TCCR0A=0x00;
TCCR0B=0x03;
TCNT0=0x01; - это компенсация какого-то такта?
OCR0A=0x00;
OCR0B=0x00;

//Прерывание от данных пришедших с вала двигателя
interrupt [EXT_INT0] void ext_int0_isr(void)
{

if (i ‹ 3) //если i не успевает приплюсоваться до трех значит частота на валу Больше чем ограничение.
PORTB.0=1; - PORTB.0 и есть INT0 -ошибся, PORTB.1!!!
else PORTB.0=0;
i=0; //наплюсовали - надо снулить нашу i дабы снова она начала плюсоваться

}

И ещё вопрос - как тактуется Tiny13? выхода и входа XTAL у нее нет. Как я понял с даташита - есть внутренний осцилятор на 128кГц, 4.8МГц и 9.6МГц... И какое-то внешнее тактование.
Сейчас попробую адаптировать Ваш код под себя.
Блин. Как просто и красиво. =)

Последний раз редактировалось GRTH32; 29.07.2010 в 08:13.
GRTH32 вне форума  
Непрочитано 29.07.2010, 07:11  
GRTH32
Частый гость
 
Регистрация: 17.11.2009
Адрес: Владивосток
Сообщений: 18
Сказал спасибо: 2
Сказали Спасибо 1 раз в 1 сообщении
GRTH32 на пути к лучшему
По умолчанию Re: Помогите пожалуйста разобраться с компаратором.

Сообщение от kison Посмотреть сообщение
Это мотоцикл?
Измеряйте период, а не частоту. Дальше скользящее среднее по 4-8 отсчетам, сравнение и индикация превышения если нужно.
Да, мотоцикл.
Скользящее среднее, я так понимаю, для большей стабильности показаний?
Городить расчеты в прерывании, наверное, не хорошо, а делать это в теле цикла основной программы - я пока не смогу посчитать поправки на такты. =(
Сначала попробую более простой вариант, затем буду уже усложнять.
Спасибо.
GRTH32 вне форума  
Непрочитано 29.07.2010, 08:33  
GRTH32
Частый гость
 
Регистрация: 17.11.2009
Адрес: Владивосток
Сообщений: 18
Сказал спасибо: 2
Сказали Спасибо 1 раз в 1 сообщении
GRTH32 на пути к лучшему
По умолчанию Re: Помогите пожалуйста разобраться с компаратором.

В общем, код приобрел следующий вид:

PHP код:

#include ‹tiny13.h›

unsigned int i=0;

//Прерывание от данных пришедших с вала двигателя
interrupt [EXT_INT0void ext_int0_isr(void)
{

 if (
‹ 70//если i не успевает приплюсоваться до 70 значит частота на валу Больше чем ограничение.
    
PORTB.3=0;
 else 
PORTB.3=1;
 
i=0//наплюсовали - надо  снулить нашу i дабы снова она начала плюсоваться

}

// Прерывание по таймеру 9375 Герц проц 9.60 МегаГерц
interrupt [TIM0_OVFvoid timer0_ovf_isr(void)
{
TCNT0=0x01;
i++;
if (
›= 65535i=0;
}


void main(void)
{
// Crystal Oscillator division factor: 1

#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif

PORTB=0b001000// Ставим бит в PORTB.3, так как диод на VCC.
DDRB=0b001000//PORTB.3 у нас будет выходом на светодиод

// Организуем таймер на: 9375 Hz
TCCR0A=0x00;
TCCR0B=0x05;   //делим 9600000 на 1024 = 9375 Гц
TCNT0=0x01;    /// Зачем?
OCR0A=0x00;
OCR0B=0x00;

// Зададим выпадание в прерывание если идет падающий сигнал от датчика на валу
GIMSK=0x40// Прерывание по INT0
MCUCR=0x03// Прерывание на INT0 нарастающему фронту
GIFR=0x40;


//Прочее
TIMSK0=0x02;
ACSR=0x80;
ADCSRB=0x00;

#asm("sei")

while (1)
      {
//Траляля три рубля =))) Нифига тут нам не надо        
      
};

Соответственно не работает. =)

Прерывание по INT0 обрабатывается.

Что вызывает внимание:

1) AVR Studio всё время указывает частоту 4МГц, как сменить на 9.6Мгц?

P.S. Наверное, хорошим тоном до прерывания по INT0 отправлять контроллер в спячку?

Последний раз редактировалось GRTH32; 29.07.2010 в 09:09.
GRTH32 вне форума  
 

Закладки
Опции темы

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

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

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

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Помогите разобраться с ADS 7816 sserg_ey Микроконтроллеры, АЦП, память и т.д 6 27.07.2010 16:54
[Решено] Помогите разобраться с генератором igor1000 Электроника средств транспорта 10 05.07.2010 12:53
Помогите разобраться в схеме микросхемы koiah Электроника - это просто 85 14.05.2010 17:53
Помогите разобраться с прошивкой Edinolichnik Микроконтроллеры, АЦП, память и т.д 5 26.04.2010 22:24
Помогите, пожалуйста, разобраться в простейшей схеме.. Светлана Электроника - это просто 18 17.11.2009 01:10


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


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