Отговори на тема  [ 33 мнения ]  Отиди на страница Предишна  1, 2, 3
Измерване на период с PIC16F 
Автор Съобщение
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Вто Дек 20, 2016 6:39 pm
Мнения: 32
Местоположение: Русе
Мнение Re: Измерване на период с PIC16F
Все пак реших да обърна внимание на предложението на zdrav относно преместването на времеотнемащите функции от обработчика на прекъсването в основния цикъл. Ще се радвам на малко разяснения, тъй като цяло схващам идеята, но на места не ми достигат знания за да мога да пренапиша/променя кода като за mikroC. Ако трябва да съм конкретен на първо време tx_buf[tx_buf_head % TX_BUF_SIZE][T1_FALL] = t1val, както и първите три реда относно дефинирането (#define TX_BUF_SIZE (8), ...) са ми интересни (друг еквивалентен начин?).
Също така ми е проблемен while(1), и по-точно въобще не изпълнява каквото съм сложил вътре.
Когато ми остане време продължавам и ще докладвам.
Благодаря на всички за съветите!


Вто Дек 19, 2017 9:07 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Сря Яну 26, 2005 1:01 pm
Мнения: 1952
Местоположение: Варна
Мнение Re: Измерване на период с PIC16F
tx_buf е "кръгов" буфер. Израза в квадратните скоби: tx_buf_head % TX_BUF_SIZE, с който се индексира масива на буфера, всъщност е прост начин да превърнеш монотонно нарастваща променлива в "кръгова". Индекса в този случай монотонно нараства до (TX_BUF_SIZE - 1) и после се "превърта" до 0, и така в кръг. При това индекса не излиза от размера на масива от паметта определен за буфера.
Еквивалентен израз е:
tx_buf[tx_buf_head & (TX_BUF_SIZE - 1)][T1_FALL] = t1val;
но този вариант работи само ако размера на буфера,TX_BUF_SIZE, е степен на двойката. 2,4,8,16,32,... Докато варианта с остатъка от деленето работи с всякакви размери на буфера.
Ако оптимизатора на компилатора е достатъчно умен да съобрази, че в конкретния случай TX_BUF_SIZE е 8 (т.е. степен на двойката) е възможно да замести намирането на остатъка от делене(операцията %) с маскиране - логическа операция &. т.е. еквивалентния израз, който за някои МЦУ-та е доста по-бърз за изпълнение. Пробвай еквивалентния вариант, но тогава отговорността да внимаваш TX_BUF_SIZE, винаги докато поддържаш този код, да е степен на двойката е твоя.

#define TX_BUF_SIZE (8)
е израз за С препроцесора. Това е изключително просто и мощно средство. С две думи, препроцесора се извиква преди компилатора и обработва С сорса като текст. Просто казано в случая ще замести текста TX_BUF_SIZE навсякъде където го срещне в С кода, с числото 8. Скобите около 8 са против уроки - добра практика, която ще ти се отплати, когато почнеш да пишеш по сложни макроси за препроцесора.
Съответно другите макроси:
#define T1_RISE (0)
#define T1_FALL (1)
, така да се каже параметризират кода. Позволяват ти да използваш вместо число символно име(измислено от теб). Това на всеки който чете кода ти ще му говори, че тази нула тук и онази там всъщност винаги са една константа с една и съща стойност. Ако ползваш директно числа, може да попаднеш в ситуацията, когато решиш да промениш стойността/числото и трябва да обиколиш всички места на които то се използва и да го смениш, ръчно. Ако същата константа е дефинирана като символно име с макрос за препроцесора, ще ти се наложи да промениш стойността само в реда от сорса, където е дефиниран макроса. Препроцесора ще промени стойността на всякъде където то е използвано със символното име от макроса вместо теб. И ще го прави всеки път, когато компилираш.
Всичко това разбира се можеш да прочетеш в учебниците и дебелите книги разбира се.

Това, че кода в while(1){} цикъла не се изпълнява, може да означава, че или времето в което процесора стои в прекъсване(всички обработчици на прекъсвания, които имаш) е толкова голямо, че не остава време за фоновите задачи в основния цикъл или, може да означава още, че си зациклил в прекъсване. Например не изчистваш съответния флаг, който да позволи ядрото да излезе от прекъсване.
Ако е първия вариант, значи "софтуерните гимнастики" са му дошли в повече на твоя PIC16F628. Може да е време да помислиш за друго решение.
По принцип меренето на отрязък от време е хардуерна задача. И както колегите подхвърлиха най-оптималния вариант е да ползваш възможностите на периферните модули.
Там те ще ти обясняват. Да видим на какъв език ще ги пишат ферманите. Описването на решението със софтуер, например на С, има незаменимото предимство, че може да бъде сведено до разбираем вид и за машината(МЦУ-то, PC-то) и за човека. И колкото по-абстрактно, толкова по-лесно преносимо на други МЦУ-та, хардуери, платформи, компилатори... не е обвързано със специфичен хардуер, но може да бъде адаптирано за такъв.

Освен това винаги може да пробваш първо да вдигнеш клока. Май беше споменал че осцилатора ти е на 4 MHz. Това МЦУ би трябвало да може повече.
Или да включиш оптимизацията на компилатора на "optimize for speed" или както там му викат в света на microC.
Или да махнеш най-сетне висенето в изпращане по UART от обработчика на прекъсването.

ПС: Скоростта на UART-a би трябвало да можеш да вдигнеш още. Пробва ли с 38400, 57600, 115200?

_________________
Най-опасният враг на истината и свободата е мнозинството.


Вто Дек 19, 2017 10:16 pm
Профил
Ранг: Ориентиран
Ранг: Ориентиран

Регистриран на: Вто Фев 06, 2007 1:45 am
Мнения: 260
Мнение Re: Измерване на период с PIC16F
Това микроЦ няма ли дефиниран 16-битов TMR1 регистър?


Сря Дек 20, 2017 12:40 pm
Профил
Покажи мненията от миналия:  Сортирай по  
Отговори на тема   [ 33 мнения ]  Отиди на страница Предишна  1, 2, 3

Кой е на линия

Потребители разглеждащи този форум: 0 регистрирани и 3 госта


Вие не можете да пускате нови теми
Вие не можете да отговаряте на теми
Вие не можете да променяте собственото си мнение
Вие не можете да изтривате собствените си мнения
Вие не можете да прикачвате файл

Търсене:
Иди на:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.
Хостинг и Домейни