реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Проблема при измерении периода синусоиды, ATmega8
straighter
сообщение Mar 4 2016, 23:31
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 20
Регистрация: 29-06-12
Пользователь №: 72 555



Уважаемые форумчане, помогите разобраться... ATmega8 работает с кварцем 8 Мгц. На вход встроенного компаратора подаю синусоиду 4 кГц от стабильного генератора. По положительному перепаду на выходе компаратора происходит захват значения в Timer/Counter1. Возникает прерывание, вычисляется разность между последним захваченным значением и предыдущим захваченным значением. По идее, эта разность должна быть равна 2000, т.к. 8МГц/4кГц=2000.
Но на самом деле получается 1000. Почему?

Это значение (1000) я могу наблюдать в виде последовательного кода на выходе PORTC.1 с помощью осциллографа.

Фрагмент программы, прерывание по захвату Таймера1:

i
Код
nterrupt [TIM1_CAPT] void timer1_capt_isr(void)
{
b=ICR1;
if (b>a) {
e=b-a;
};
a=b;
for(i=0; i < 16; i++)
{      
if(0x0001 & (e>>(15-i)))
        PORTC.1=1;                      //если бит-единица, то и выставляем единицу
        else PORTC.1=0;       //иначе - выставляем ноль        
     }
PORTC.1=0;
}


Сообщение отредактировал IgorKossak - Mar 5 2016, 10:40
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
Go to the top of the page
 
+Quote Post
akl
сообщение Mar 5 2016, 02:59
Сообщение #2


Частый гость
**

Группа: Свой
Сообщений: 126
Регистрация: 4-04-07
Из: Ижевск
Пользователь №: 26 773



Возможно, есть дребезг в моменты перехода полуволны синуса через уровень компарирования. Можно попробовать включить бит "шумодава" ICNC1.
Go to the top of the page
 
+Quote Post
zombi
сообщение Mar 5 2016, 12:24
Сообщение #3


Профессионал
*****

Группа: Свой
Сообщений: 1 933
Регистрация: 10-09-08
Пользователь №: 40 106



А если в прерывании просто инвертировать PORTC.1 какая частота на нём будет?
Go to the top of the page
 
+Quote Post
straighter
сообщение Mar 5 2016, 13:12
Сообщение #4


Участник
*

Группа: Участник
Сообщений: 20
Регистрация: 29-06-12
Пользователь №: 72 555



Цитата(zombi @ Mar 5 2016, 14:24) *
А если в прерывании просто инвертировать PORTC.1 какая частота на нём будет?


Это я тоже пробовал раньше. Тогда частота синусоиды была 25 кГц (период 40 мкс). А частота сигнала на выходе порта, который я инвертировал, была в два раза ниже, как и должно быть:

Прикрепленное изображение


А вот осциллограмма моего последнего эксперимента, о котором я писал в первом посте. Частота синусоиды 4 кГц. На осциллограмме показаны кодовая последовательность на выходе PORTC.1 и вспомогательные импульсы для облегчения разделения битов в кодовой последовательности. Если перевести кодовые пакеты в десятичную систему, то получается 1000 и 999:

Прикрепленное изображение


Вот в растянутом виде:

Прикрепленное изображение


Сообщение отредактировал straighter - Mar 5 2016, 13:19
Go to the top of the page
 
+Quote Post
zombi
сообщение Mar 5 2016, 14:41
Сообщение #5


Профессионал
*****

Группа: Свой
Сообщений: 1 933
Регистрация: 10-09-08
Пользователь №: 40 106



Или clkcpu не 8MHz или на счетчик поступает не clkcpu.
Go to the top of the page
 
+Quote Post
controller_m30
сообщение Mar 5 2016, 14:52
Сообщение #6


Местный
***

Группа: Участник
Сообщений: 273
Регистрация: 24-02-09
Пользователь №: 45 309



Приведите ещё настройки всех регистров компаратора и Таймера_1.
А ещё, если так можно, пусть программа прерывания TC1, выводит каждый раз не вычисленную разность, а просто текущее значение ICR1, которое там зафиксировалось. Желательно, чтоб на скрине поместилось два подряд идущих числа - чтоб можно было самим оценивать и их разность, и при этом видеть абсолютное значение каждого числа. Может это что-то подскажет...

Сообщение отредактировал controller_m30 - Mar 5 2016, 14:55
Go to the top of the page
 
+Quote Post
zombi
сообщение Mar 5 2016, 14:52
Сообщение #7


Профессионал
*****

Группа: Свой
Сообщений: 1 933
Регистрация: 10-09-08
Пользователь №: 40 106



Цитата(straighter @ Mar 5 2016, 17:12) *
На осциллограмме показаны кодовая последовательность на выходе PORTC.1 и вспомогательные импульсы для облегчения разделения битов в кодовой последовательности.

А почему интервалы между "вспомогательные импульсы" разные?
Go to the top of the page
 
+Quote Post
straighter
сообщение Mar 5 2016, 18:14
Сообщение #8


Участник
*

Группа: Участник
Сообщений: 20
Регистрация: 29-06-12
Пользователь №: 72 555



Цитата(zombi @ Mar 5 2016, 16:52) *
А почему интервалы между "вспомогательные импульсы" разные?


Эти вспомогательные импульсы формируются тоже в цикле "for(i=0; i < 16; i++)", просто в моем первом посте я для упрощения кода их не показал. А интервалы между ними разные потому что эти интервалы зависят от количества сдвигаемых разрядов в данный момент цикла, т.е. от 15 до 0.

Цитата(controller_m30 @ Mar 5 2016, 16:52) *
Приведите ещё настройки всех регистров компаратора и Таймера_1.


Настройки регистров были произведены с помощью CodeVizardAVR:

CODE

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 8000,000 kHz
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Rising Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: On
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x41;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

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

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


Цитата(controller_m30 @ Mar 5 2016, 16:52) *
А ещё, если так можно, пусть программа прерывания TC1, выводит каждый раз не вычисленную разность, а просто текущее значение ICR1, которое там зафиксировалось. Желательно, чтоб на скрине поместилось два подряд идущих числа - чтоб можно было самим оценивать и их разность, и при этом видеть абсолютное значение каждого числа. Может это что-то подскажет...


Можно будет так попробовать. Но только уже после выходных...

Сообщение отредактировал straighter - Mar 5 2016, 18:15
Go to the top of the page
 
+Quote Post
zombi
сообщение Mar 5 2016, 19:37
Сообщение #9


Профессионал
*****

Группа: Свой
Сообщений: 1 933
Регистрация: 10-09-08
Пользователь №: 40 106



Судя по осциллограммам на формирование одного бита уходит в среднем 10 мкс = 80 тактов процессора.
Что-то много, не?
Go to the top of the page
 
+Quote Post
straighter
сообщение Mar 5 2016, 20:39
Сообщение #10


Участник
*

Группа: Участник
Сообщений: 20
Регистрация: 29-06-12
Пользователь №: 72 555



Цитата(zombi @ Mar 5 2016, 21:37) *
Судя по осциллограммам на формирование одного бита уходит в среднем 10 мкс = 80 тактов процессора.
Что-то много, не?


Не знаю, как посчитать, сколько тактов процессора требуется?
Полный фрагмент кода цикла for (вместе с вспомогательными импульсами на порте PORTC.3) такой:

Код
for(i=0; i < 16; i++)
{      
  PORTC.3=1;
  PORTC.3=0;

if(0x0001 & (e>>(15-i)))
        PORTC.1=1;//если бит-единица, то и выставляем единицу
        else PORTC.1=0;//иначе - выставляем ноль
        
     }


Я измерил длительность импульса "1" на PORTC.3 - получилось 250нс. Т.к. команда PORTC.3=1 (на ассемблере ей соответствует SBI 0x15,3) выполняется за два такта, то значит один такт равен 125нс, что соответствует частоте 8 Мгц. Вроде бы все правильно?
Go to the top of the page
 
+Quote Post
zombi
сообщение Mar 5 2016, 21:11
Сообщение #11


Профессионал
*****

Группа: Свой
Сообщений: 1 933
Регистрация: 10-09-08
Пользователь №: 40 106



Цитата(straighter @ Mar 5 2016, 23:39) *
Вроде бы все правильно?

Вроде да.
Go to the top of the page
 
+Quote Post
controller_m30
сообщение Mar 5 2016, 21:53
Сообщение #12


Местный
***

Группа: Участник
Сообщений: 273
Регистрация: 24-02-09
Пользователь №: 45 309



Цитата(straighter @ Mar 5 2016, 23:39) *
Полный фрагмент кода цикла for (вместе с вспомогательными импульсами на порте PORTC.3) такой:

У меня есть предположение по поводу приведённого кода. Этот код, как мне кажется, выводит импульс синхронизации с опережением на один бит по отношению к битам данных. Потому данные получаются сдвинутыми на один бит вправо - т.е. поделенными на 2.
Возможно что там всё-таки выводится число 2000, но из-за опережающих синхроимпульсов оно читается не верно.

Могу ошибаться, т.к. пишу только на асме, но эта последовательность команд очень на то похожа.
Это можно проверить, если вывести таким способом заранее известную константу (например 0х8001), и посмотреть расположение битов данных относительно синхроимпульсов.
Go to the top of the page
 
+Quote Post
zombi
сообщение Mar 6 2016, 04:45
Сообщение #13


Профессионал
*****

Группа: Свой
Сообщений: 1 933
Регистрация: 10-09-08
Пользователь №: 40 106



Цитата(controller_m30 @ Mar 6 2016, 00:53) *
Этот код, как мне кажется, выводит импульс синхронизации с опережением на один бит по отношению к битам данных. Потому данные получаются сдвинутыми на один бит вправо - т.е. поделенными на 2.

100%
Формирование строба до формирования данных - абсурд.

А после прочтения :
Цитата(straighter @ Mar 5 2016, 23:39) *
Не знаю, как посчитать, сколько тактов процессора требуется?

Цитата(straighter @ Mar 5 2016, 23:39) *
Я измерил длительность импульса "1" на PORTC.3 - получилось 250нс. Т.к. команда PORTC.3=1 (на ассемблере ей соответствует SBI 0x15,3) выполняется за два такта, то значит один такт равен 125нс, что соответствует частоте 8 Мгц.

мне кажется что это просто очередной ребус. biggrin.gif
Go to the top of the page
 
+Quote Post
straighter
сообщение Mar 6 2016, 08:28
Сообщение #14


Участник
*

Группа: Участник
Сообщений: 20
Регистрация: 29-06-12
Пользователь №: 72 555



Цитата(controller_m30 @ Mar 5 2016, 23:53) *
... Этот код, как мне кажется, выводит импульс синхронизации с опережением на один бит по отношению к битам данных.


Почему с опережением на целый бит? У нас длительность бита примерно 10мкс, а время выполнения команд "PORTC.3=1; PORTC.3=0;" примерно 0,5мкс.

Цитата(controller_m30 @ Mar 5 2016, 23:53) *
Это можно проверить, если вывести таким способом заранее известную константу (например 0х8001), и посмотреть расположение битов данных относительно синхроимпульсов.


Да, это можно будет проверить.
Go to the top of the page
 
+Quote Post
zombi
сообщение Mar 6 2016, 11:52
Сообщение #15


Профессионал
*****

Группа: Свой
Сообщений: 1 933
Регистрация: 10-09-08
Пользователь №: 40 106



Цитата(straighter @ Mar 6 2016, 00:39) *
Я измерил длительность импульса "1" на PORTC.3 - получилось 250нс.

Цитата(straighter @ Mar 6 2016, 12:28) *
а время выполнения команд "PORTC.3=1; PORTC.3=0;" примерно 0,5мкс.

biggrin.gif biggrin.gif biggrin.gif

Напишите вот так и не морочьте людям голову
Код
for(i=0; i < 16; i++)
{      
if(0x0001 & (e>>(15-i)))
        PORTC.1=1;//если бит-единица, то и выставляем единицу
        else PORTC.1=0;//иначе - выставляем ноль
  PORTC.3=1;
  PORTC.3=0;
}

Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 28th May 2017 - 03:05
Рейтинг@Mail.ru


Страница сгенерированна за 0.01503 секунд с 7
ELECTRONIX ©2004-2016