|
И снова частотомер на Atmega8., нужен алгоритм |
|
|
|
Jul 10 2008, 23:45
|
Группа: Новичок
Сообщений: 10
Регистрация: 2-07-08
Пользователь №: 38 711

|
Добрый день всем! На этом форуме я вобщем новичек. Вот уже меня достал этот вопрос,бо я лажу-и везде готовые схемы,без самой идеи как оно работает! Не надо мне готовые варианты нада сама идея!!! Вобщем в чем суть то вопроса Сваял так сказать частотомер на Atmega8+LMXxxxx пределитель,с выводом на МЭЛТ MT10T7-7. Тут запортачка с самим принципом измерения! Пишу на ассемблере,писать на С для таких контролеров,как по мне это полное извращение! И так. Использую 2 таймера-8битный Т0,и 16 битный Т1. Измерительная частота поступает сразу на вход Т1(PD5). После инициализацие портов,дисплея и LMX,инициализирую таймеры-- на Т0 пускаю сигнал с кварца,поделенный на 8, вход T1 подкл к источнику сигнала. А забыл-в Т0 записую константу,что бы прерывание от него наступило после 100 импульсов поступивших на него. Потом запускаю бесконечный цикл. Наступает прирывани через 100имульсов тактируемые частотой 1МГЦ(8МГЦ/8). Останавлваем Т1,изымаем даные с регистров,преобразуем 16бит в 5 десятичных знаков,выводим на экран. запускаем таймеры-счетчики,возвращаемся в бесконечный цикл. Так вот в чем глюк! Когда тестил прогу,тестил ее на частах до 2х Мгц,т е 8 бит 16битного счетчика,потом прикурил LMX,тут чюдеса когда значение в Т1 больше 255,почемуто не корректно просходит преобразование двоичного числа в десятичное...один алгорит нарыл преобразования,а все остальное бред какойто...возникли сомнения -правильно ли у меня преобразование 2х 8битных регистров с T1 в десятичный код? бо в инете токо один пример нарыл,остальное для школы 11 класса! Вопрос. Будет ли работать моя идея??? И какие тут подводные камни,и точность.Вобще работает,но я не уверен чт идея верна И как реализуют алгоритм на одном 8 битном таймере? ведь прерывание,изьятие из регистра и запись,это погрешность ,и приличная! Почитав это http://electronix.ru/forum/index.php?showt...29796&st=75 ,я пришол в УЖАС!!! Мне хватит и 5 разрядов. Сразу скажу частоту мерять до 3 ГГц,точность +-0.5МГЦ не критично! Схема собрана,работает,но вот с алгоритмом измерения походу не то. Посмотрел тут схемы,почемуто народ использует 8 битный таймер-счетчик...да и прошивы все hex,пришлось дизасемблить и смотреть....ну просто бесит..что нигде ни кто подробно не описал по человечиски.... Жду коментарием. За любой ответ буду благодарен.
Сообщение отредактировал Peeoner - Jul 10 2008, 23:59
|
|
|
|
|
Jul 11 2008, 00:10
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(Peeoner @ Jul 11 2008, 02:45)  Пишу на ассемблере, .... тут чюдеса когда значение в Т1 больше 255,почемуто не корректно просходит преобразование двоичного числа в десятичное...один алгорит нарыл преобразования,а все остальное бред какойто...возникли сомнения -правильно ли у меня преобразование 2х 8битных регистров с T1 в десятичный код? Если проблема только с преобразованием, то это пустяки. Алгоритм преобразования - собирать остатки от деления на 10 пока частное не 0. Алгоритм деления на 10 16-ти разрадного числа используя только умножение и сдвиг: y = (x * 0xCCCD) >> 19 Общие рекомендации для продожения беседы,  1. Проверьте порядок доступа к спаренным регистрам ( L регистр должен читаться перед H) 2. Ознакомьтесь с режимом таймера Input Capture, возможно пригодится или натолкнет на новую идею. 3. Поищите по форуму еще ;> =GM= тут толкал много интересных идей. А вообще ваш вариант вполне работоспособен.
|
|
|
|
|
Jul 11 2008, 00:23
|
Группа: Новичок
Сообщений: 10
Регистрация: 2-07-08
Пользователь №: 38 711

|
Вот участок кода самого цикла измерения,сильно не пинать. Я варрировал тут с изменением циклов измерения,так как у меня предделитель выставлен на 1280,в этом примере 8МГЦ/1024 и тактируем Т0, то что тут команды поставлены немного не корректно,т е T1 подстичает еще 5-10имульсов,для теста не критично,подправлю когда все будет нормально работать. С Input Capture негодиться,бо там низкая частота,а сам по себе таймер считает намного быстрее(вроде)..хотя я подумаю,10 разрядов было бы интересно заполнить,но там матиматека нифиговая получиться... Код ;Инициализация таймера 0 ldi tmp,(1<<toie0) out timsk,tmp
;Инициализация 16 битноо таймера 1 ldi tmp,0x07;07 mov lw,tmp ldi tmp,0x03 out tifr,tmp ldi tmp,0x9c;9c ;запись в регистр таймера периода счета out tcnt0,tmp ldi tmp,0x03;02 mov k,tmp ldi tmp,0x00 ;подготовка константы для остановки t1 out tccr0,k ;Тактовые импульсы с кварца /1024 out tccr1b,lw;Подключения входа таймера к внешнему источнику ser nxx
sei ;разрешение прерываний
loop: rjmp loop
tim0: ;Прерывания от таймера формирующего пириод измерения
push nxx ;Сохранение регистров в стеке (станет необходимым in nxx,sreg ;когда основная программа будет выполнять push nxx ;какие-либо действия)
out tccr1b,tmp ;Остановка 16 битного счетчика импульсо in lw,tcnt1l ;Копируем младший байт со счетчика входных импульсов in hi,tcnt1h ;Копируем старший байт
ldi tmp,0x00 out tcnt1l,tmp ;Очищяем счетчик импульсов out tcnt1h,tmp ;
out tccr0,tmp ;Останавливаем таймер периода счета out tcnt0,tmp ;очищяем таймер периода счета
;Преобразуем двоичное 16битное число в десятичное
;.def lw=r17 ;.def hi=r18 ;************************************************************************ ;Преобразуем двоичное 16битное число в десятичное вида ;{0x0(цифра 10000)} {тысячи,сотни} {десятки,единицы} ;************************************************************************ ; ; ; ; ; ;.def lw =r17 ;двоичное значение, младший байт ;.def hi =r18 ;двоичное значение, старший байт ;.def dig0 =r18 ;BCD значение, цифры 1 и 0 ;.def dig1 =r19 ;BCD значение, цифры 3 и 2 ;.def dig2 =r20 ;BCD значение, цифра 4 ;Примечание: Переменные hi и dig0 должны размещаться в одном ;регистре. ;*************************************************************************
BCD5: ldi dig2, -1 BCD5_loop_1: inc dig2 subi lw, low(10000) sbci hi, high(10000) brsh BCD5_loop_1 subi lw, low(-10000) sbci hi, high(-10000) ldi dig1, -0x11 BCD5_loop_2: subi dig1, -0x10 subi lw, low(1000) sbci hi, high(1000) brsh BCD5_loop_2 subi lw, low(-1000) sbci hi, high(-1000) BCD5_loop_3: inc dig1 subi lw, low(100) sbci hi, high(100) brsh BCD5_loop_3 subi lw, -100 ldi dig0, -0x10 BCD5_loop_4: subi dig0, -0x10 subi lw, 10 brsh BCD5_loop_4 subi lw, -10 add dig0,lw
Сообщение отредактировал zltigo - Jul 11 2008, 15:17
|
|
|
|
|
Jul 11 2008, 03:42
|
Группа: Новичок
Сообщений: 10
Регистрация: 2-07-08
Пользователь №: 38 711

|
Ну вот все проверил,дествительно глюк именно в преобразование чисел, до 255 оно нормально показуеть а после 255,начинают мелькать цифры,как бы случайная величина образуеться... вывод цифр на дисплей нормально работает. глюкас в этом алгоритме,который я взял с атмеловского сайта http://www.atmel.ru/Articles/Atmel13_app1.htm а он оказуеться глюконутый! А в инете не одного примера,только этот. Вот умножение и деление это хорошо,вот только в Avr нет прямого модуля деления и умножения,а как умножать и делить посредством других команд,понятия не имею,опять же литературы не фига нету... в инете тоже не нарыл. Может кто хоть название подскажет каких нить книженцей которые скачать моно? Или у кого готовый алгоритм на ассемлере есть? Теперь камень предкновения,то што я не умею преобразовать 2байта таймера в 5 цифр...вот пипец.....
Сообщение отредактировал Peeoner - Jul 11 2008, 03:45
|
|
|
|
|
Jul 11 2008, 05:45
|

Знающий
   
Группа: Свой
Сообщений: 723
Регистрация: 29-08-05
Из: Березовский
Пользователь №: 8 065

|
Цитата(Peeoner @ Jul 11 2008, 09:42)  Теперь камень предкновения,то што я не умею преобразовать 2байта таймера в 5 цифр...вот пипец..... Может все-таки перейти на Си? Смотрите как просто: Код char mystring[10]; unsigned int counter; counter = 12345; // число 12345 -- только как пример [b] sprintf(mystring, "", counter);[/b] // Вывод числа на МЭЛТ for (i = 0; i < strlen(mystring); i++) { МЭЛТ = mystring[i]; // эта строка -- только пример. Код не рабочий!!! } Жирным выделена строка, которая делает преобразование, которое наводит на Вас ужас. Все просто и красиво. Более того, программу напишите намного быстрее, чем на ассеблере. Работать программа будет не чуть не медленнее, т.к. счетом занимается аппаратура, а не программный код. Не хочу оскорблять Ваши религиозные чувства относительно языков программирования, просто предлагаю рассматреть и другие варианты решения задачи.
--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
|
|
|
|
|
Jul 11 2008, 10:21
|

За битами по регистрам гоняюсь
  
Группа: Свой
Сообщений: 457
Регистрация: 24-04-06
Из: Таганрог
Пользователь №: 16 446

|
Цитата(Peeoner @ Jul 11 2008, 07:42)  ...Вот умножение и деление это хорошо,вот только в Avr нет прямого модуля деления и умножения,а как умножать и делить посредством других команд,понятия не имею,опять же литературы не фига нету... Вообще-то у ATmega есть команды умножения и деления, но это так, к слову ... А вот здесь есть куча подпрограмм на экологически чистом ассемблере: http://elm-chan.org/cc_e.html
--------------------
Курсор влево, курсор вправо - считается хакерством. FORMAT C: производится без предупреждения
|
|
|
|
|
Jul 11 2008, 12:33
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(Peeoner @ Jul 10 2008, 22:45)  Посмотрел вашу ссылку, там моя переписка с Яrik'ом (кстати, он довёл-таки точность измерения частоты 1 МГц программой на си до 1 Гц), никакого ужаса не заметил, зато почитав ваши сообщения, понял, что вы учились в олбанской школе и были там хорошистом или даже отличником. Потом посмотрел вашу программу и тут пришёл в тихий ужас: нет ни одного завершённого фрагмента, просто какие-то куски кода. По делу. Алгоритм измерения частоты методом ворот достаточно примитивен. Берёте некий счётчик, открываете его на некоторый период времени - счётчик начинает считать приходящие импульсы, закрываете - перестаёт считать. Если окно было открыто на 1 секунду, то искомая частота в герцах равна количеству импульсов в счётчике. Если окно открыто на 0.1с, то частота в десятках герц и т.д. Если окно некратно таких числам, то придётся каждый раз пересчитывать, поэтому все стараются выставить кратное окно. У вас, кстати, длительность окна не кратна, надо пересчитывать. Да и длительность какая-то смехотворная - порядка 40 мс, подойдёт только для оценки величины частоты. Видите ли, частотомер это точный измерительный прибор, и разработчики всегда стараются выжать максимум из разрабатываемого устройства, так они устроены. А уж что выводить на дисплей, 5-6-7-8-9-10 разрядов, это отдельная песня.
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Jul 11 2008, 12:58
|
Частый гость
 
Группа: Свой
Сообщений: 127
Регистрация: 4-04-07
Из: Ижевск
Пользователь №: 26 773

|
Цитата(Peeoner @ Jul 11 2008, 04:45)  ...везде готовые схемы,без самой идеи как оно работает! Не надо мне готовые варианты нада сама идея!!! И так. ...И как реализуют алгоритм на одном 8 битном таймере? ведь прерывание,изьятие из регистра и запись,это погрешность ,и приличная! Почитав это http://electronix.ru/forum/index.php?showt...29796&st=75 ,я пришол в УЖАС!!! Мне хватит и 5 разрядов. Сразу скажу частоту мерять до 3 ГГц,точность +-0.5МГЦ не критично! Схема собрана,работает,но вот с алгоритмом измерения походу не то. ...нигде ни кто подробно не описал по человечиски.... Жду коментарием. За любой ответ буду благодарен. Цитата(defunct @ Jul 11 2008, 05:10)  ... 2. Ознакомьтесь с режимом таймера Input Capture, возможно пригодится или натолкнет на новую идею. 3. Поищите по форуму еще ;> =GM= тут толкал много интересных идей.
А вообще ваш вариант вполне работоспособен. Как Вам такой алгоритм: Тизм=Тх*Nx*A и Тизм=to*nox, где Тизм- принятое время измерения; Тх-период измеряемой частоты; Nx-целое число периодов измеряемой частоты; to-период тактовой частоты микроконтроллера Fo; nox-целое число периодов тактовой частоты микроконтроллера Fo; A-коэффициент деления LMX. Делаем преобразование Тх*Nx*A=to*nox Тх=to*nox/Nx*A или Fx=Fo*Nx*A/nox!!! Для примера: Принимаем время измерения примерно 0.25 сек. Fo=8'000'000 Hz Принимаем A=234'560. Допустим, что измеряется Fx=3'210'987'000 Hz 3'210'987'000 Hz/234'560=13'698.405xxx Hz-> 1'000'000мкс/13'698.405xxx=73.049ххх мкс за время измерения пройдет 250000/73.049ххх=3422.351ххх периодов Nx. Дожидаемся окончания текущего периода Nx=3423-> 73.049ххх*3423=250073.049ххх мкс и nox=200379. Подставляем в выражение Fx=8'000'000*3423*234560/200379=3'210'987'037 Hz. Достоинством данного метода, особенно для любительских условий, является: -Fo-может меняться в широких пределах. Просто она должна быть известна -отсутствие жесткого требования выдержки измерительного интервала, кратного единице времени -легкая реализация на любом микроконтроллере. Загрубить полученный результат можно всегда. Пристальнее рассмотрите возможности Input Capture, на которые обращает внимание =GM=Удачи! PS Пока писал Вам ответил =GM=, но, думаю, мое сообщение будет не лишнее.
|
|
|
|
|
Jul 11 2008, 12:59
|
Местный
  
Группа: Свой
Сообщений: 408
Регистрация: 21-10-06
Из: Санкт-Петербург
Пользователь №: 21 527

|
Цитата(Peeoner @ Jul 11 2008, 07:42)  глюкас в этом алгоритме,который я взял с атмеловского сайта http://www.atmel.ru/Articles/Atmel13_app1.htm а он оказуеться глюконутый! А в инете не одного примера,только этот. Этот алгоритм используют сотни людей, и У ВСЕХ он работает нормально. Тем более, что он очень простой. Просто применять его нужно правильно.
|
|
|
|
|
Jul 11 2008, 15:09
|
Группа: Новичок
Сообщений: 10
Регистрация: 2-07-08
Пользователь №: 38 711

|
Цитата Посмотрел вашу ссылку, там моя переписка с Яrik'ом (кстати, он довёл-таки точность измерения частоты 1 МГц программой на си до 1 Гц), никакого ужаса не заметил, зато почитав ваши сообщения, понял, что вы учились в олбанской школе и были там хорошистом или даже отличником. Потом посмотрел вашу программу и тут пришёл в тихий ужас: нет ни одного завершённого фрагмента, просто какие-то куски кода.
По делу. Алгоритм измерения частоты методом ворот достаточно примитивен. Берёте некий счётчик, открываете его на некоторый период времени - счётчик начинает считать приходящие импульсы, закрываете - перестаёт считать. Если окно было открыто на 1 секунду, то искомая частота в герцах равна количеству импульсов в счётчике. Если окно открыто на 0.1с, то частота в десятках герц и т.д. Если окно некратно таких числам, то придётся каждый раз пересчитывать, поэтому все стараются выставить кратное окно. У вас, кстати, длительность окна не кратна, надо пересчитывать. Да и длительность какая-то смехотворная - порядка 40 мс, подойдёт только для оценки величины частоты. Видите ли, частотомер это точный измерительный прибор, и разработчики всегда стараются выжать максимум из разрабатываемого устройства, так они устроены. А уж что выводить на дисплей, 5-6-7-8-9-10 разрядов, это отдельная песня. Ну в албанской школе не учюся,давно уже отучился,грамматика на форуме ,думаю, это не столь критично.Да и коменты в тексте программы чисто для себя,что бы не пришлось думать "а што же я тут делал" кода прога поваляеться пол года на компе,и придеться что то править. Код в програме завершен,я просто привел кусок который относиться к циклу измерения,просто незнаю нужен ли весь код,вроде и так понятно А на диспелй выводить цифры,ни какой песни нету,все достаточно легко,как по мне проще чем число преобразовать))) Я прекрасно понимаю что частотомер точный прибор,но мне не нужно сверх точности. Вот скажем на частоте в 3 000 МГЦ,поделеную на 1280 какую вы точность получите???? Используя обычный китайский КВАРЦ на 8мгц... Я все же подумаю над идеей =GM= ... Устройство для себя разрабатывалось. >Этот алгоритм используют сотни людей, и У ВСЕХ он работает нормально. Тем более, что он очень простой. Просто применять его нужно правильн Ну может конешно и я ошибся,поверю вам наслово. А вы его сами применяли хоть раз??? А по поводу С--напишите 100 строчек кода,откомпильте и посмотрите сколько hex файл у вас бедет весить,а потом напишите на ассемблере и сравните! А всякая оптимизация и прочее не дают особого эффекта
Сообщение отредактировал Peeoner - Jul 11 2008, 15:16
|
|
|
|
|
Jul 11 2008, 15:22
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(Peeoner @ Jul 11 2008, 17:09)  Ну в албанской школе не учюся,давно уже отучился,грамматика на форуме ,думаю, это не столь критично. Moderator: Всему есть предел. Настойчиво рекомендую ознакомится с правилами данного форума.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jul 11 2008, 15:34
|
Группа: Новичок
Сообщений: 10
Регистрация: 2-07-08
Пользователь №: 38 711

|
Правила читал.Вроде не че такого не сказал,забаните,сам разберусь.
Сообщение отредактировал Peeoner - Jul 11 2008, 15:44
|
|
|
|
|
Jul 11 2008, 15:37
|

Знающий
   
Группа: Свой
Сообщений: 723
Регистрация: 29-08-05
Из: Березовский
Пользователь №: 8 065

|
Цитата(zltigo @ Jul 11 2008, 21:22)  Moderator: Всему есть предел. Настойчиво рекомендую ознакомится с правилами данного форума. Не могу при людно не выразить уважение zltigo. Четко, сильно, политкорректно. Молодец! Я снова приникся уважением. Respects to you!
--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
|
|
|
|
|
Jul 11 2008, 15:45
|
Группа: Новичок
Сообщений: 10
Регистрация: 2-07-08
Пользователь №: 38 711

|
Спасибо,понял. Народ почемуто тут везде исходники сует на форуме,во все окно,буду иметь ввиду.
Сообщение отредактировал Peeoner - Jul 11 2008, 15:47
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|