Микроконтроллеры, АЦП, память и т.д Темы касающиеся микроконтроллеров разных производителей, памяти, АЦП/ЦАП, периферийных модулей... |
26.04.2011, 11:18
|
|
Гражданин KAZUS.RU
Регистрация: 18.07.2006
Сообщений: 866
Сказал спасибо: 230
Сказали Спасибо 29 раз(а) в 27 сообщении(ях)
|
Скоректируйте программу частотомера
друзья доброго всем здоровья!
Решил сделать программу частотомера.
Конечно, таких программ в инете много, но сами понимаете нужно самому научится творить программы
Пусть скромные но свои.
Так ,вот начал с элементарного понятия частоты -это число импульсов за определенный период времени
Берем интервал в 1 сек и считаем количество импульсов за это время (метод временных ворот)
Взял доступную ATtiny2313 с внешним кварцем 8 192 000 Гц.
В переди поставил схему совпадения(см прилоеженный рисунок) на первый вход которого подаю импулсы измеряемой частоты ,а на другой сформированный микрокортроллерем односекундный импульс.С выхода схемы совпадения импульсы подаются на вход T0 таймера счетчика
TCNT0,который работает в режиме внешнего счета.
Ниже приводится программа( без подпрограммы для LCD использование которой не вызывает затруднении) на Ваше обсуждение:
T1 задействован для формирования интервала 1 сек.
Для этого он должен посчитать 8 192 000 импульсов и остановится, но так как сам таймер считает только до 65536, то приходится многократно посчитать переполнение ,пока в сумме не получим число 8 192 000 .
Такой счет идет в переменной "d".
Получаем 8 192 000/ 65536 =125 (dec) = 0x7D (HEX)
Chip type : ATtiny2313
Clock frequency : 10,0000 MHz
Memory model : Tiny
External SRAM size : 0
Data Stack size : 32
************************************************** ***/
#include ‹tiny2313.h›
#include ‹delay.h›
unsigned long int a,b,c,d;//задаем переменные
char r;
//----------------------------------------------
// Timer 1 overflow interrupt service routine //прерывание по переполнению таймера 1.
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
d++;
}
//-----------------------------------------------
// Timer 0 overflow interrupt service routine //прерывание по переполнению таймера 0.
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
c++;
}
void main(void)
{
// Declare your local variables here
// Crystal Oscillator division factor: 1
#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif
PORTA=0x00;
DDRA=0x00;
PORTB=0xFF;
DDRB=0x00;
PORTD=0x54;
DDRD=0x2B;
// Timer/Counter 0 initialization
// Clock source: T0 pin Rising Edge
// Mode: Normal top=FFh
// OC0A output: Disconnected
// OC0B output: Disconnected
TCCR0A=0x00;
TCCR0B=0x07;
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B 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
TCCR1A=0x00;
TCCR1B=0x01;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// Interrupt on any change on pins PCINT0-7: Off
GIMSK=0x00;
MCUCR=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x82;
// Universal Serial Interface initialization
// Mode: Disabled
// Clock source: Register & Counter=no clk.
// USI Counter Overflow Interrupt: Off
USICR=0x00;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
// Global enable interrupts
#asm("sei")
while (1)
{
if(d›=0x7D)
{
PORTD.5=0;
TCCR1B=0x00;
a=((c*0x100)+TCNT0); // определяемая частота
d=0;
c=0;
TCNT0=0;
TCNT1=0;
delay_ms(20);
TCCR1B=0x01;
PORTD.5=1;
}
};
}
Дорогие друзья ,знатоки, прокотролируйте пожалуйсто мою програмку. Все ли у меня верно,
Не будут ли мешать два прерывания друг другу и если да, как от этого избавится?
В ПРОТЕУСе ,в окне где смотрят переменные и регистры, числа получались одни и те же,
а в самом деле как будет не знаю.
Хотелось бы услышать Ваше авторитентное мнение, ато мне кажется, что так просто это не должно быть. Так в чем моя неграмотность?
Заранее благодарен за любые коментарии.
|
|
|
|
26.04.2011, 11:52
|
|
Почётный гражданин KAZUS.RU
Регистрация: 10.05.2005
Адрес: Саратов.ru
Сообщений: 1,548
Сказал спасибо: 384
Сказали Спасибо 737 раз(а) в 417 сообщении(ях)
|
Re: скоректируйте программу частотомера
Схема совпадения не нужна - Fin подавайте напрямую на PD4/T0. Секундный импульс можно сделать и программно
Код:
|
volatile unsigned long int a,c,d; //задаем переменные
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
if (!d) TCNT0 = 0; //начало секундного импульса
else if (d›0x7D)
{
a = (c‹‹8)+TCNT0; //в a - результат измерения
c = d = 0;
}
d++;
}
...
void main(void)
{
...
// в a уже есть определяемая частота
} |
Результат лучше фиксировать в прерывании от секундного таймера - точность не будет зависеть от длительности основного цикла.
Последний раз редактировалось AJScorp; 26.04.2011 в 12:39.
|
|
|
|
26.04.2011, 12:34
|
|
Почётный гражданин KAZUS.RU
Регистрация: 20.06.2006
Адрес: Украина, Запорожье
Сообщений: 7,982
Сказал спасибо: 0
Сказали Спасибо 4,941 раз(а) в 2,370 сообщении(ях)
|
Re: Скоректируйте программу частотомера
begun,
а может лучше взять чужую, взять скальпель и препарировать, потом поменять уши с лапами, хвост с носом и посмотреть результат? ![Очень смешно](images/smilies/icon_veryhappy.gif) такие примеры есть на ремэксперте, да и здесь наверняка.
я тоже начинал с рассмотрения чужих, добавления/изъятия команд, написания дополнительных процедур. правда, я писал на асме и с даташитом в обнимку.
мой совет - возьмите готовое и изучите, быстрее будет и нагляднее, заодно и замысел программиста разгадаете. да, и без знания железа в совершенстве хорошую программу не напишете.
|
|
|
|
26.04.2011, 14:19
|
|
Почётный гражданин KAZUS.RU
Регистрация: 25.05.2010
Адрес: г. Королёв
Сообщений: 8,497
Сказал спасибо: 30
Сказали Спасибо 3,072 раз(а) в 2,013 сообщении(ях)
|
Re: Скоректируйте программу частотомера
1. Частотомер в данном случае получится жиденький. До 4 мегагерц в лучшем случае. Это связано с архитектурой ядра.
2. В прерывании переполнения считать некорректно. Точность будет низкой. При входе в прерывание выполняемая МК команда в любом случае завершается. А она бывает на разное количество тактов. Это делается в основном цикле по флагу переполнения таймера(флаг прерывания).
Лучше послушайте jump и посмотрите, как это делают другие.
|
|
|
Сказали "Спасибо" omercury
|
|
|
26.04.2011, 15:04
|
|
Заблокирован
Регистрация: 08.08.2007
Сообщений: 2,843
Сказал спасибо: 378
Сказали Спасибо 1,368 раз(а) в 746 сообщении(ях)
|
Re: Скоректируйте программу частотомера
Сообщение от omercury
|
1. Частотомер в данном случае получится жиденький. До 4 мегагерц в лучшем случае. Это связано с архитектурой ядра.
|
А кто мешает поставить на входе делитель? При использовании делителя, архитектура ядра мешать не будет...
|
|
|
|
26.04.2011, 15:48
|
|
Почётный гражданин KAZUS.RU
Регистрация: 07.10.2007
Адрес: Луганск
Сообщений: 1,816
Сказал спасибо: 13
Сказали Спасибо 399 раз(а) в 214 сообщении(ях)
|
Re: Скоректируйте программу частотомера
Сообщение от RY723
|
А кто мешает поставить на входе делитель? При использовании делителя, архитектура ядра мешать не будет...
|
Увеличтся дискретность измерения и стоимость. Проще взять PIC16Fxxx и будет работать до 120 мгц с дискретностью 1 Гц и без прерываний.
__________________
"picavr(ГАВ)мыло.ру" USB_Analyzer, Digital_Storage_Oscilloscope "picavr.kr1.ru" заказы в Китай компонентов/изготовление: плат/ЖКИ/мембраных клавиатур/имп трансформаторов
|
|
|
|
26.04.2011, 18:07
|
|
Гражданин KAZUS.RU
Регистрация: 18.07.2006
Сообщений: 866
Сказал спасибо: 230
Сказали Спасибо 29 раз(а) в 27 сообщении(ях)
|
Re: Скоректируйте программу частотомера
Я пытался разобраться в чужих программах ,но вобщем то, не очень легко получается ,особенно если и к тому, коментариев мало.
Но из Ваших пожелании мне в урок, что некорректно в прерывании переполнения считать .
Мне бы хотелось услышать от Вас пару слов на сщет двух препывании.
Они друг другу мешать не будут. Так можно сделать?, или чтото надо при этом учесть ?
Спасибо.
|
|
|
|
26.04.2011, 20:50
|
|
Вид на жительство
Регистрация: 21.10.2009
Сообщений: 343
Сказал спасибо: 180
Сказали Спасибо 64 раз(а) в 56 сообщении(ях)
|
Re: Скоректируйте программу частотомера
Сообщение от begun
|
Я пытался разобраться в чужих программах ,но вобщем то, не очень легко получается ,особенно если и к тому, коментариев мало.
Но из Ваших пожелании мне в урок, что некорректно в прерывании переполнения считать .
Мне бы хотелось услышать от Вас пару слов на сщет двух препывании.
Они друг другу мешать не будут. Так можно сделать?, или чтото надо при этом учесть ?
Спасибо.
|
Вы считаете количество импульсов за 1 сек,
попробуйте измерить время необходимое для принятия N импульсов.
Это увеличит точность измерений. Все это можете сделать на таймерах или например так
Цитата:
|
Сделайте простую программу без прерываний по следующему алгоритму.
1) Проверить, что уровень входного сигнала нулевой. Если нет, то подождать.
2) Дождаться перехода входного сигнала из 0 в 1. Запустить таймер. Обнулить счётчик периодов M.
3) Дождаться перехода входного сигнала из 1 в 0.
4) Дождаться перехода входного сигнала из 0 в 1. Инкрементировать счётчик периодов M.
5) Если количество периодов равно заданному, остановить таймер. Если нет, перейти к п. 3.
6) Взять значение таймера N и вычислить период по формуле Tx=To*N/M.
|
Это совет =GM= от 2007 года.
Последний раз редактировалось CodeNameHawk; 26.04.2011 в 20:54.
|
|
|
Сказали "Спасибо" CodeNameHawk
|
|
|
26.04.2011, 21:03
|
|
Заблокирован
Регистрация: 26.12.2009
Сообщений: 3,124
Сказал спасибо: 116
Сказали Спасибо 867 раз(а) в 614 сообщении(ях)
|
Re: Скоректируйте программу частотомера
Угу... ![Рот до ушей](images/smilies/icon_doushei.gif)
При входной частоте 100Гц и полной шкале в восемь разрядов... включи - и езжай в отпуск...
|
|
|
|
26.04.2011, 22:48
|
|
Почётный гражданин KAZUS.RU
Регистрация: 25.05.2010
Адрес: г. Королёв
Сообщений: 8,497
Сказал спасибо: 30
Сказали Спасибо 3,072 раз(а) в 2,013 сообщении(ях)
|
Re: Скоректируйте программу частотомера
Сообщение от CodeNameHawk
|
Это совет =GM= от 2007 года.
|
Можно измерить длительность периода, а потом рассчитать частоту.
Работать, конечно, как-то будет, но есть засада. На высокой входной частоте пострадает точность, вверху диапазона очень сильно(реальная частота может почти в 2 раза отличаться от отображаемой). Про низкую частоту очень образно сказал st_1, хотя точность в этом случае будет весьма высока. Этот метод используется именно для измерения периода.
Счётный метод намного точнее: точность - единица младшего разряда. Но в нём есть свои "чудеса". Прерывания в частотомере недопустимы(если не наплевать на точность). Всё делается в основном цикле программы и выверяется по тактам МК.
picavr здесь прав. МК от Microchip отличаются тем, что имеют в своём составе асинхронные таймеры-счётчики. Они могут работать на частоте выше тактовой. Максимальная частота зависит от "высокочастотности" каждого экземпляра индивидуально - как повезёт. В этом принципиальное различие с тем же AVR(в них счёт фиксируется по перепаду сигнала тактового генератора).
Пока посмотрите это. http://www.google.ru/search?q=%D0%A7...client=firefox
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 21:48.
|
|