Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Счетчик частоты на SAM7S64
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > ARM, 32bit
abit
Здравствуйте.
Мне нужно было собрать измеритель частоты (от 1 до 4МГц) на SAM7S64 и передавать по usb в компьютер эту частоту... программирую в IAR...
встретился с проблемой - хотя там пишут про частоты в 47МГц...
реально например написана такая программа:
Код
do {counter++;} while (dataready!=0)

и стоит счетчик c прерыванием ровно на 1 секунду, который выставляет dataready...
программа успевает насчитать в counter до порядка 2 800 000... а мне ведь еще частоту в 4 000 000 мерить, а не просто счетчик пускать...
это можно как-то ускорить? может я неправильно что-то тактирую...
я просто впервые столкнулся с подобного рода программированием, подскажите пожалуйста в чем проблема...
kovigor
Цитата(abit @ Jul 26 2011, 16:01) *
подскажите пожалуйста в чем проблема...



Используйте аппаратный таймер-счетчик в режиме Capture:
"Capture Mode allows the TC channel to perform measurements such as pulse timing, frequency, period, duty cycle and phase on TIOA and TIOB signals which are considered as inputs" (это из даташита на данный МК).

P.S. Да, для быстрого старта можете скачать книжку Редькина по ARM7. Это почти дословный перевод даташита. Даташит она не заменит, но позволит быстро войти в курс дела ...
aaarrr
Так таймером считать надо. На тактовый вход ему подаете измеряемую частоту, по другому таймеру берете время.
abit
kovigor, aaarrr
Спасибо за ответы.
И оптимизм что это вообще теоретически возможно... а то я уж хотел забить и программировать ПЛИСку...
Я подозревал что код работает на бешеной 47МГц частоте и уж команда ADD (я так понял INC нету) выполнится по крайней мере 10Млн раз должна... а тут такой облом...

Книжка есть, но там даташиты с X256, распиновка не та.... а о программировании на ярких примерах - вообще не слова толком... просто перечисление регистров и битов... вообще запутался с теми таймерами что там за связи от TCLK0/1/2 к TIOA1/2 и TIOB1/2 и далее к XC0/XC1/XC2...
Я верно понял что сигнал надо вешать на TCLK0? чтобы его считать (мне нужно оба фронта)...

Где то можно найти готовый пример как переконфигурировать PA28 на TCLK, настроить на режим захвата по обоим фронтам и потом из таймера вынуть число что он насчитал там?

p.s. извините за дотошность... я никогда не программил МК до этого... просто пока я пытался запустить USB я потратил много времени (из-за того что у меня старая версия программатора и старая версия IAR (4) ни один готовый пример с usb не компилился... а с новыми IAR 5/6 программатор отказывался работать)... в итоге - USB в CDC режиме заработал... а тут встретил такое досадное быстродействие... и уж думал все убитое время - под хвост...
kovigor
Цитата(abit @ Jul 26 2011, 17:29) *
kovigor, aaarrr
я никогда не программил МК до этого... просто пока я пытался запустить USB я потратил много времени


В книжке описано семейство. Прочтите, вам будет гораздо легче понять даташит. Примеры можно посмотреть у того же Атмела, они дают огромный архив с самыми разными примерами:

http://www.atmel.com/dyn/products/tools_ca...sp?tool_id=4343

И задача ваша как минимум на порядок проще, чем запуск USB ...
aaarrr
Цитата(abit @ Jul 26 2011, 18:29) *
Я подозревал что код работает на бешеной 47МГц частоте и уж команда ADD (я так понял INC нету) выполнится по крайней мере 10Млн раз должна... а тут такой облом...

Код, положим, так и работает (если из RAM), только
Код
do {counter++;} while (dataready!=0)

- это отнюдь не одна команда инкремента.

Цитата(abit @ Jul 26 2011, 18:29) *
Я верно понял что сигнал надо вешать на TCLK0? чтобы его считать (мне нужно оба фронта)...

Для захвата - на TIOA, для счета - на TCLK.

Цитата(abit @ Jul 26 2011, 18:29) *
Где то можно найти готовый пример как переконфигурировать PA28 на TCLK, настроить на режим захвата по обоим фронтам и потом из таймера вынуть число что он насчитал там?

Если на вход подать 4MHz, то при 48MHz MCK между фронтами таймер успеет досчитать только до трех в лучшем случае. Устроит такая разрешающая способность?
Режим захвата можно использовать на низких частотах, если нужно измерить относительно высокую, то остается только считать число тактов за определенное время, то есть сигнал подать на тактовый вход таймера.
abit
kovigor
Я на этой страничке уже все скачивал, сам на нее выходил раньше гуглом - от туда ничего не компилется под IAR 4, суть в том что у них от версий 5 и 6 отличается сильно структура инклудов и вообще библиотеки не те... и ничего из новых версий IAR - так и не удалось скомпилить под старой... мой путь создания CDC-устройства вообще удивителен и я не понимаю как мне это удалось до сих пор...

Я понимаю что задача проще sm.gif мне нужно было узнать хотя бы возможность ее решения ) а то уже начал плату под циклон разводить было... но кстати в конце книжки Редькина таки на 600-от какой-то странице нашел пример работы с таймером... ну даже не с этим МК, но ладно - уже рад, завтра буду пробовать...

Спасибо за советы!!! Вы вселили мне надежду...

aaarrr
ну там действительно не одна... я глянул в дебагерре:

ldr регистр1, память
add регистр1, 1
str регистр1, память
ldr регистр2, память
mov регистр3,0
сmp регистр2, регистр3
bnq в начало

И это при максимальной оптимизации по времени исполнения! ерунда вообще... к чему эти пустые ldr, str? если можно выгрузить регистр потом... в итоге занимает 17 тактов процессора судя по всему (48 против 2.8)
вот пример того же кода на обычном IA:

l1:
inc регистр1
mov регистр2, память
test регистр2
bnq l1
mov память, регистр1

собстна этот вариант (со стандартной оптимизацией IA) - занимает 7 тактов процессора... что более чем в 2 раза быстрее...

Если я все правильно понял из ваших ответов - вроде нужно T0 повесить на выдачу прерываний по времени, T1 и T2 объединить в один, чтобы был 32-битный счетчик... (мне таки надо до 8 млн. досчитать в пределе... т.к. таймер времени - секунда, а ловлю я оба препада 4МГц)

Цитата
Для захвата - на TIOA, для счета - на TCLK

в чем отличие? я так понял из даташита tioa формируются из tclk после мультиплексера...
поясните в чем я ошибаюсь?

Цитата
Если на вход подать 4MHz, то при 48MHz MCK между фронтами таймер успеет досчитать только до трех в лучшем случае. Устроит такая разрешающая способность?
Режим захвата можно использовать на низких частотах, если нужно измерить относительно высокую, то остается только считать число тактов за определенное время, то есть сигнал подать на тактовый вход таймера.


меня в данный момент интересует максимально возможная разрешающая способность от этой МК... соответственно все таки вешаю на TCLK) про режим захвата - значит я неверно понял его смысл... хотя скорее ту блок-схему что дана в книжке... ведь судя по ней TIOA/TIOB - формируются из TCLK и нужны либо для вывода наружу знака переполнения либо для подключения второго каскада счетчка
prottoss
Если поможет - вот полное описание по микроконтроллерам AT91SAM7S
http://www.gaw.ru/html.cgi/txt/doc/micros/...sam7s/index.htm
aaarrr
Цитата(abit @ Jul 26 2011, 21:42) *
кстати в конце книжки Редькина таки на 600-от какой-то странице нашел пример работы с таймером... ну даже не с этим МК, но ладно - уже рад, завтра буду пробовать...

Не тратьте время зря. Трудно придумать что-то более убогое, нежели примеры из этой книжки.
Вам всего-то нужно прочитать описание таймера и спокойно сконфигурировать его в выбранном режиме.

Цитата(abit @ Jul 26 2011, 21:42) *
к чему эти пустые ldr, str? если можно выгрузить регистр потом...

Подозреваю, что как вы сами попросили, так компилятор и сделал. Ни один современный компилятор с включенной оптимизацией не станет зря гонять через память не-volatile переменную.

Цитата(abit @ Jul 26 2011, 21:42) *
Если я все правильно понял из ваших ответов - вроде нужно T0 повесить на выдачу прерываний по времени, T1 и T2 объединить в один, чтобы был 32-битный счетчик... (мне таки надо до 8 млн. досчитать в пределе... т.к. таймер времени - секунда, а ловлю я оба препада 4МГц)

Нельзя так ловить оба фронта, таймер работает только по одному. Да и зачем это нужно?

Цитата(abit @ Jul 26 2011, 21:42) *
меня в данный момент интересует максимально возможная разрешающая способность от этой МК... соответственно все таки вешаю на TCLK) про режим захвата - значит я неверно понял его смысл... хотя скорее ту блок-схему что дана в книжке... ведь судя по ней TIOA/TIOB - формируются из TCLK и нужны либо для вывода наружу знака переполнения либо для подключения второго каскада счетчка

Для чего нужны совершенно правильно поняли, только это waveform mode. В режиме захвата (capture) TIOA - это входной сигнал, по которому можно загрузить текущее значение таймера в RA/RB.
abit
aaarrr
Компилятор IARа с оптимизацией почему-то так и сделал...
более того инструкции
Код
while (dataready!=0) {counter++;}

и
Код
for (dataready=1;dataready!=0;)  {counter++;}

впадают в вечный цикл, хотя
Код
do {counter++;} while (dataready!=0)

работает... я видел много всего из области фантастики с циклом for, но с while впервые...

Цитата
Нельзя так ловить оба фронта, таймер работает только по одному. Да и зачем это нужно?

Почему нельзя? вроде в книжке говорится что можно по переднему, заднему и по обоим фронтам...
мне это нужно... смысл такой зачем это нужно:
исходная частота - порядка 1ГГц проходит через микросхему (назовем ее A), в которой есть предварительный 8-битный счетчик, от неё в МК я загоняю только старший бит (как раз порядка 4МГц) и по сигналу строба допустим раз в секунду сбрасываю из счетчика в регистр внутри A, а он вешает это число на ножки МК... далее я читаю состояние входов и одновременно должен убедиться что состояние старшего бита в прочитанном регистре совпадает с состоянием фронта той 4МГц частоты... если совпал - значит МК успел, если не совпал - значит нужно увеличить значение подсчитанной 4МГц частоты... ибо попался такой момент, что пока я читал регистр, там сменился фронт...
в общем путано, но как смог объяснил свою затею

и еще раз для ясности... просто сперва вы мне говорили
Цитата
Используйте аппаратный таймер-счетчик в режиме Capture:
"Capture Mode allows the TC channel to perform measurements such as pulse timing, frequency, period, duty cycle and phase on TIOA and TIOB signals which are considered as inputs" (это из даташита на данный МК).


Capture - это режим захвата насколько я помню английский...
а теперь говорите забудь про захват, используй режим счета...
хотя в книжке говорят о двух режимах: захвата и формирования....

Заранее благодарю за ответы!
Вы мне уже очень помогли.
kovigor
Цитата(abit @ Jul 27 2011, 10:51) *
просто сперва вы мне говорили

Capture - это режим захвата насколько я помню английский...
а теперь говорите забудь про захват, используй режим счета...


Про capture я говорил. А про счет - aaarrr. Его слушайте, он прав (прочтите чуть выше его комментарий про разрешающую способность в режиме Capture) ...
aaarrr
Цитата(abit @ Jul 27 2011, 11:51) *
работает... я видел много всего из области фантастики с циклом for, но с while впервые...

Не бывает чудес ни с for'ом, ни с while. Как объявлены counter и dataready?

Цитата(abit @ Jul 27 2011, 11:51) *
Почему нельзя? вроде в книжке говорится что можно по переднему, заднему и по обоим фронтам...

Захват можно сделать по любому фронту, считать таймер умеет только по одному.

Цитата(abit @ Jul 27 2011, 11:51) *
мне это нужно... смысл такой зачем это нужно:
...ибо попался такой момент, что пока я читал регистр, там сменился фронт...

Казалось бы, на одну четырехмиллионную можно смело плюнуть, нет?

Цитата(abit @ Jul 27 2011, 11:51) *
и еще раз для ясности... просто сперва вы мне говорили

ОК, еще раз: таймер может работать в режимах capture и waveform. Первый предназначен для измерения параметров сигнала, поданного на TIOA (частота, длительность и т.п.), второй - для формирования выходных сигналов на TIOA/B.
Сигнал у вас высокочастотный, поэтому измерять длительность его периода средствами capture бесполезно, т.к. получается слишком низкая разрешающая способность. Поэтому и нужно подать сигнал на TCLK, чтобы тактировать таймер непосредственно от измеряемого сигнала.
Такое подключение допускают оба режима - и capture, и waveform. Затем можно или каскадировать таймеры (тогда первый должен быть в режиме waveform, чтобы можно было сформировать перенос следующему), или сделать инкремент старшей половины счетчика программно, по прерыванию переполнения.
abit
Цитата(aaarrr @ Jul 27 2011, 13:21) *
Не бывает чудес ни с for'ом, ни с while. Как объявлены counter и dataready?


Я подобные "чудеса" много где встречал, каждый раз разные источники беды... я конечно МК не программировал, но программировал много чего другого...

ну если брать этот пример :
counter объявлен локально в main() во первых строках... как unsigned int counter;
dataready сразу после инклудов, глобально как unsigned char dataready;
чуть ниже этого объявления сразу идет функция обработчика прерывания, где код dataready=0; непосредственно перед выходом из прерывания...

почему while и for впадают в вечный цикл - ума не приложу... более того я внутрь этого цикла засунул выдачу содержимого dataready в usb - оно сперва вываливало 1, потом спутя секунду вываливает 0, т.е. значение явно сменилось... а цикл не завершался... в то время как do...while работает чудесно...

Цитата(aaarrr @ Jul 27 2011, 13:21) *
Захват можно сделать по любому фронту, считать таймер умеет только по одному.

Спасибо, я разобрался... там в книжке речь шла о синхронизации по обоим фронтам на триггере...

Цитата(aaarrr @ Jul 27 2011, 13:21) *
Казалось бы, на одну четырехмиллионную можно смело плюнуть, нет?

К сожалению это четырехмиллионная на самом деле в гигагерце превращается в 256Гц... что портит всю разрешающую способность и делает бессмысленным вообще тот регистр, которым я синхронизирую счетчик по стробам и читаю единицы герца.... так что фронт в момент строба иметь очень хотелось бы, чтобы мерить гигагерц до герца...

Цитата(aaarrr @ Jul 27 2011, 13:21) *
ОК, еще раз: таймер может работать в режимах capture и waveform. Первый предназначен для измерения параметров сигнала, поданного на TIOA (частота, длительность и т.п.), второй - для формирования выходных сигналов на TIOA/B.
Сигнал у вас высокочастотный, поэтому измерять длительность его периода средствами capture бесполезно, т.к. получается слишком низкая разрешающая способность. Поэтому и нужно подать сигнал на TCLK, чтобы тактировать таймер непосредственно от измеряемого сигнала.
Такое подключение допускают оба режима - и capture, и waveform. Затем можно или каскадировать таймеры (тогда первый должен быть в режиме waveform, чтобы можно было сформировать перенос следующему), или сделать инкремент старшей половины счетчика программно, по прерыванию переполнения.

Спасибо, сейчас буду пробывать по вашему рецепту...
не ясно только с тем загадочным триггером... вот внтуренний программный триггер можно использовать чтобы таймер времени и таймер счета T1связанный с T2 пустить одновременно / остановить одновременно по прерыванию от T0?
aaarrr
Цитата(abit @ Jul 27 2011, 14:42) *
почему while и for впадают в вечный цикл - ума не приложу...

Потому что dataready должна быть volatile unsigned char dataready.

Цитата(abit @ Jul 27 2011, 14:42) *
чтобы мерить гигагерц до герца...

Чтобы мерить гигагерц до герца, нужно прежде всего иметь опорный источник с сумасшедшей точностью и стабильностью. Он есть?

Цитата(abit @ Jul 27 2011, 14:42) *
Спасибо, сейчас буду пробывать по вашему рецепту...
не ясно только с тем загадочным триггером... вот внтуренний программный триггер можно использовать чтобы таймер времени и таймер счета T1связанный с T2 пустить одновременно / остановить одновременно по прерыванию от T0?

Таймер счета не нужно останавливать вообще, смотрите разницу между предыдущим и текущим значениями. Можно, например, при помощи T0 формировать импульс длительностью 1с на TIOA0, а затем этим сигналом маскировать клок (BURST) для T1. Получается такой режим работы:
1. Считали и запомнили текущее значение T1
2. Запустили T0, дождались окончания секундного интервала
3. Считали значение T1, вычли из него предыдущее - получили частоту клока T1
abit
Цитата(aaarrr @ Jul 27 2011, 16:09) *
Потому что dataready должна быть volatile unsigned char dataready.


Чтобы мерить гигагерц до герца, нужно прежде всего иметь опорный источник с сумасшедшей точностью и стабильностью. Он есть?


Таймер счета не нужно останавливать вообще, смотрите разницу между предыдущим и текущим значениями. Можно, например, при помощи T0 формировать импульс длительностью 1с на TIOA0, а затем этим сигналом маскировать клок (BURST) для T1. Получается такой режим работы:
1. Считали и запомнили текущее значение T1
2. Запустили T0, дождались окончания секундного интервала
3. Считали значение T1, вычли из него предыдущее - получили частоту клока T1


огромное спасибо,
сейчас почти все удалось...
опорный источник (который будет формировать строб)) с сумасшедшей точностью будет когда-нибудь...
сейчас по факту вот что удалось:
TС0 - повесил на счет времени по MCK/1024, в T0.RC=46800 (чтобы секунда была) по переполнению - выроботка прерывания
TС1 - в режиме формирования импульсов с установкой TIOA1 на RC=32767, и cбросом TIOA1 на RA=0 (режим (13<<15)|7)), тактируется TCLK2 (PA29)
TС2 - в режиме захвата (0x7), тактируется от TIOA1

И на мое удивление все заработало. Фиг знает что без вас бы делал...
хотя есть одна странность - TС2 почему то если есть такты TIOA1 - сбрасывается, если нет - не сбрасывается по AT91C_BASE_TC2->TC_CCR = AT91C_TC_SWTRG;
поэтому если снять сигнал с PA29 - TC1 сбрасывается, а TC2 сохраняет свое значение с последнего цикла измерения и висит в таком состоянии пока не подать снова сигнал на PA29...

Все бы хорошо, однако все бултыхается...
Сейчас на время отойдем от этих счетчиков и вернется к примитивному циклу...

вот отдельно код:
Код
while (1) do
{
         dataready=0;
      AT91C_BASE_TC1->TC_CCR = AT91C_TC_SWTRG;
      AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG;
          AT91C_BASE_TC2->TC_CCR = AT91C_TC_SWTRG;
        
        do
          {
                  UpperCounter++;    
          } while (dataready==0);

      for (i=8; i!=0; i--)
      {
            digit=(UpperCounter%10);
            UpperCounter=UpperCounter/10;
            infdd[i-1]='0'+digit;
          }
          
      pCDC.Write(&pCDC, infdd,10);    
}


смотрю выход USB-порта (значение UpperCounter):
Код
02819021
02819063
02819016
02819050
02819045
02819016
02819033
02819027
02819060
02819061
02819053


почему он так веляет от цикла к циклу? Это временной промежуток между прерываниями CT0 меняется, время исполнения команд или опорная частота плавает или еще чего? Можно ли как то это синхронизировать и все таймеры для кучи одновременно сбрасывать?
aaarrr
Цитата(abit @ Jul 27 2011, 17:58) *
хотя есть одна странность - TС2 почему то если есть такты TIOA1 - сбрасывается, если нет - не сбрасывается по AT91C_BASE_TC2->TC_CCR = AT91C_TC_SWTRG;
поэтому если снять сигнал с PA29 - TC1 сбрасывается, а TC2 сохраняет свое значение с последнего цикла измерения и висит в таком состоянии пока не подать снова сигнал на PA29...

Эта странность документирована:
Цитата
Regardless of the trigger used, it will be taken into account at the following active edge of the
selected clock. This means that the counter value can be read differently from zero just after a
trigger, especially when a low frequency signal is selected as the clock.

Только это не совсем правда: CPCTRG на деле срабатывает сразу.

Цитата(abit @ Jul 27 2011, 17:58) *
Все бы хорошо, однако все бултыхается...

А clock gating сделали, или просто смотрите значения TC1-2 по прерыванию? В последнем случае по определению будет все "бултыхаться".

Цитата(abit @ Jul 27 2011, 17:58) *
почему он так веляет от цикла к циклу?

А какие прерывания включены (SOF USB, например)? Используется ли где-нибудь PDC? Все это будет влиять на результат.

На самом деле, следует забыть о каких-либо программных измерениях. Хорошей точности не получите по определению.
Все должно делаться в железе.
abit
Цитата(aaarrr @ Jul 27 2011, 18:26) *
А clock gating сделали, или просто смотрите значения TC1-2 по прерыванию? В последнем случае по определению будет все "бултыхаться".


Я просто смотрю значение счетчиков... к своему стыду я не знаю что такое clock gating, слышал только что это что-то из области управления питанием для синхронных схем... а уж как его делать тем более не представляю, поэтому сомнительно что я его сделал случайно...
У меня тут есть программист ПЛИСок, может он знает... но он сейчас не ходит работать )))

Цитата(aaarrr @ Jul 27 2011, 18:26) *
А какие прерывания включены (SOF USB, например)? Используется ли где-нибудь PDC? Все это будет влиять на результат.

прерывания умышленно я включал только на таймер T0, никаких других не включал, PDC не использую...

вот весь кусок инициализации МК:
Код
void AT91F_USB_Open(void)
{
    AT91C_BASE_CKGR->CKGR_PLLR |= AT91C_CKGR_USBDIV_1;
    AT91C_BASE_PMC->PMC_SCER = AT91C_PMC_UDP;
    AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_UDP);
    AT91F_PIO_CfgOutput(AT91C_BASE_PIOA,AT91C_PIO_PA16);
    AT91F_PIO_ClearOutput(AT91C_BASE_PIOA,AT91C_PIO_PA16);
    AT91F_CDC_Open(&pCDC, AT91C_BASE_UDP);
}

void AT91F_TC_Open ( AT91PS_TC TC_pt, unsigned int Mode, unsigned int TimerId)
{
        TC_pt->TC_CCR = AT91C_TC_CLKDIS;
    TC_pt->TC_IDR = 0xFFFFFFFF;
    TC_pt->TC_CMR = Mode;
    TC_pt->TC_CCR = AT91C_TC_CLKEN;
}


void TC0_ISREntry( void )
{
unsigned long STATUS = AT91C_BASE_TC0->TC_SR;
AT91C_BASE_AIC->AIC_IVR = 0;
AT91C_BASE_AIC->AIC_ICCR = (1 << AT91C_ID_TC0);
dataready=1;
AT91C_BASE_AIC->AIC_EOICR = 0;
}


int main ( void )
{

    AT91C_BASE_RSTC->RSTC_RMR = AT91C_RSTC_URSTEN | (0x4<<8) | (unsigned int)(0xA5<<24);
     AT91F_PMC_EnablePeriphClock ( AT91C_BASE_PMC, (1 << AT91C_ID_PIOA) | (1 << AT91C_ID_TC0) | (1 << AT91C_ID_TC1) | (1 << AT91C_ID_TC2));

    

    AT91F_PIO_CfgOutput( AT91C_BASE_PIOA, LED_MASK );
    AT91F_PIO_SetOutput( AT91C_BASE_PIOA, LED_MASK );
    AT91F_PIO_ClearOutput( AT91C_BASE_PIOA, LED1 );
    


   AT91C_BASE_TCB->TCB_BMR = AT91C_TCB_TC2XC2S_TIOA1; //(1<<5)|(1<<6);    
    
    
   infdd[12]='\r';
   infdd[13]='\n';

    AT91F_USB_Open();
    while (!pCDC.IsConfigured(&pCDC));
    

//AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC0);
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;
AT91C_BASE_TC0->TC_IDR = 0xFFFFFFFF;
AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV5_CLOCK | AT91C_TC_CPCTRG;
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN;
AT91C_BASE_TC0->TC_RC = 46800;  // MCK / 1024 = 47,4МГц / 1024 => 1 сек
AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG;
AT91C_BASE_TC0->TC_IER = AT91C_TC_CPCS;

AT91C_BASE_AIC->AIC_IDCR = (1 << AT91C_ID_TC0);
AT91C_BASE_AIC->AIC_SVR[AT91C_ID_TC0] = (unsigned int) TC0_ISREntry;
AT91C_BASE_AIC->AIC_SMR[AT91C_ID_TC0] = AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL | 0x3;
         AT91C_BASE_AIC->AIC_ICCR = (1 << AT91C_ID_TC0);
         AT91C_BASE_AIC->AIC_IECR = (1 << AT91C_ID_TC0);
    
              dataready=0;
              
   AT91F_TC_Open(AT91C_BASE_TC1,13 << 15 | 7,AT91C_ID_TC1);
   AT91F_TC_Open(AT91C_BASE_TC2,0x7,AT91C_ID_TC1);

Цитата(aaarrr @ Jul 27 2011, 18:26) *
На самом деле, следует забыть о каких-либо программных измерениях. Хорошей точности не получите по определению.
Все должно делаться в железе.

Это не мой каприз(((
Подноготная вопроса тяжелая - я работаю на заводе, который поделен на много предприятий... одно из них с гордым началом НИИ замутило все это... я им еще год назад говорил купите мне ПЛИСку за 500рублей и я вам все сделаю, нет, они понабрали этой шляпы, лицензию на IAR дороже рынка... явная отмывка денег, наняли программистов... год не пойми чем занимались - а в конце мая резко уволили всех программистов... стали искать по заводу - а кроме нашей скромной лабораторией (мы собстна 3 человека из области программирования станков, УЧПУ и ПЛИСок) с этим никогда не сталкивались - а кроме нас - некому... потому что по контракту должен завод отвечать... вот нам уже 2 месяца не платят зарплату, пока не сделаем хоть чего-то... поэтому я и взялся делать из того что есть, а потом уж переделаем нормально
aaarrr
Цитата(abit @ Jul 28 2011, 14:40) *
Я просто смотрю значение счетчиков... к своему стыду я не знаю что такое clock gating, слышал только что это что-то из области управления питанием для синхронных схем... а уж как его делать тем более не представляю, поэтому сомнительно что я его сделал случайно...

Это то, о чем я писал в №14 - фича таймера.
Таймером 0 формируете строб в одну секунду на TIOA0, этим стробом разрешаете клок на таймере 1. Таким образом все будет подсчитано железкой без вмешательства ПО.

Цитата(abit @ Jul 28 2011, 14:40) *
Это не мой каприз(((
Подноготная вопроса тяжелая - я работаю на заводе, который поделен на много предприятий... одно из них с гордым началом НИИ замутило все это... я им еще год назад говорил купите мне ПЛИСку за 500рублей и я вам все сделаю, нет, они понабрали этой шляпы, лицензию на IAR дороже рынка... явная отмывка денег, наняли программистов... год не пойми чем занимались - а в конце мая резко уволили всех программистов... стали искать по заводу - а кроме нашей скромной лабораторией (мы собстна 3 человека из области программирования станков, УЧПУ и ПЛИСок) с этим никогда не сталкивались - а кроме нас - некому... потому что по контракту должен завод отвечать...

Под железом я в данном случае имел в виду ресурсы самого МК. Хотя ПЛИС уместнее, конечно, для такой задачи.

Цитата(abit @ Jul 28 2011, 14:40) *
вот нам уже 2 месяца не платят зарплату, пока не сделаем хоть чего-то... поэтому я и взялся делать из того что есть, а потом уж переделаем нормально

Так может, ну его, такого работодателя?
abit
Цитата(aaarrr @ Jul 28 2011, 14:51) *
Это то, о чем я писал в №14 - фича таймера.
Таймером 0 формируете строб в одну секунду на TIOA0, этим стробом разрешаете клок на таймере 1. Таким образом все будет подсчитано железкой без вмешательства ПО.

Всё работает!!! Спасибо, перевел TС0 в режим формирования, затем TIOA0 - сделал установкой лог.1 на RA=0 и лог. 0 на RC=46800 и повесил TIOA0 на XC1 затем XC1 на burst счетчика TC1...
я в шоке, как все было просто сделать - и все заработало, спасибо вам просто огромнейшее... я бы в жизни не догадался что burst - это Clock Enable, хотя неск. раз пролиставал эту блок-схему... скорее всего главная ошибка автора книжки - что они не внесли в общую блок-схему (самую первую) этот burst/или не озвучили его далее как CE... в итоге - все прыгает теперь около 30Гц от 4МГц, это я понимаю погрешность опорного кварца 18МГц на плате... у него как раз стоит точность 10^-4, нужно повесить тот самый сверхточный генератор...
и я уже было начал писать об этом результат работы... как понял...
не все так гладко - пусть точность пока 10^-4, но ведь строб то нефига не аппаратный, а программный по прерыванию...
если возможно - завтра тогда настрою канал TIOB0 на выход из платы, чтобы генерить сигнал строба так же аппаратно... в итоге - весь измеритель будет аппаратным на этих трех счетчиках... и похоже плиска уже не нужна - все будет итак с точностью квраца на плате SAM7S64... надо точнее - пусть кварц выравнивают емкостями или генератор делают точный...

Еще раз благодарю за советы... особенно за тактирование TCLK и наводку про burst, фиг знает как бы это сделал без вас... сейчас дело осталось разве что за TIOB0 наружу для строба, но думаю завтра разберусь....



Цитата(aaarrr @ Jul 28 2011, 14:51) *
Так может, ну его, такого работодателя?

к сожалению нельзя, сам работодатель (мой директор) не виноват в нечестности соседних контор... а общий начальник завода - всех винит что кто-то оплошал..
а я своего директора очень уважаю, он честный человек...
но в любом случае - я тут кроме работы еще прохожу аспирантуру... в общем, лучше пока тут оставаться, чтобы получить кандидата наук, не метаться по разным конторам и быть спокойным... ибо уволюсь - не видать кандидата...
aaarrr
Цитата(abit @ Jul 28 2011, 23:59) *
и я уже было начал писать об этом результат работы... как понял...
не все так гладко - пусть точность пока 10^-4, но ведь строб то нефига не аппаратный, а программный по прерыванию...

Стоп. Почему же не аппаратный, если сформирован непосредственно таймером T0, и этот сигнал заведен в качестве гейта на клок T1?
abit
Цитата(aaarrr @ Jul 29 2011, 01:55) *
Стоп. Почему же не аппаратный, если сформирован непосредственно таймером T0, и этот сигнал заведен в качестве гейта на клок T1?

так тут речь шла о стробе не который burst для T1 формирует (так сказать ворота, а по вашему - clock gating)... а о стробе по которому синхронизуется регистр в той микросхеме, которая ГГц на себя берет и снижает до 4МГц своим счетчиком... вот) про тот строб что на нее дается, чтобы младший регистр прочитать с нее...
Задача этого строба была сформировать короткий импульс в момент открытия ворот счета (burst) и в момент закрытия на ту микросхему... однако даже TIOB0 не помог - сделать оказалось не реально... одних RB и RC не хватало при любых Wavesel... в итоге чтобы не делать строб для ГГцовой микросхеме программно - вывел tioa0 наружу (pa0) и спаял на советской К555ЛП5 + кондюк для задержки + резистор для превращения выхода в 3.3V тупую логику для формирования короткого строба по смене фронта tioa0
далее спаял кварцованный генератор на 2МГц (на 4 не нашел кварца...) его откалибровал на Ч3-84, кстати оказался в одном экземпляре этот частотомер на заводе - полдня ждал пока принесут...
как только этот замечательный прибор, способный замерять частоту и длительность любого фронта попал мне в руки - выяснилось две вещи...
1) Кварц 18.с копейками МГц не соответствует действительности по этим копейкам - в итоге вместо 46800 секунде соответствует 47034 на счетчике в T0.RC... при MCK/1024
2) С этого генератора 2МГц - частота держится в 2 000 004 по измерениям атмельки... ничего не болтается... ну вернее там просто секунда не совсем соответствует фактической секунде - так что все хорошо... дело в том что при изменении RC с 47034 на 47035 в "ворота" попадает сразу 2 000 0046 импульсов... вместо 2 000 004... так что тут ничего не поделаешь, ровную секунду не сформировать... надо на компе пересчитывать

главное что сейчас с точностью прибора ЧЗ-84 успешно все измеряется! стоит и не болтается...
и спасибо ВАМ ЗА ПОМОЩЬ!!! Я бы сам вряд ли справился так быстро...
aaarrr
Цитата(abit @ Jul 30 2011, 00:37) *
1) Кварц 18.с копейками МГц не соответствует действительности по этим копейкам - в итоге вместо 46800 секунде соответствует 47034 на счетчике в T0.RC... при MCK/1024

Не хочу вас расстраивать, но это несколько подозрительно. А что если померить тем же ЧЗ-84 частоту кварца?

Зарплату теперь дадут? sm.gif


Даже совсем подозрительно - ровно 0.5% blink.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.