Nyakоi
Ранг: Минаващ
Регистриран на: Вто Дек 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), и по-точно въобще не изпълнява каквото съм сложил вътре. Когато ми остане време продължавам и ще докладвам. Благодаря на всички за съветите!
|
Zdrav
Ранг: Форумен бог
Регистриран на: Сря Яну 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?
_________________ Най-опасният враг на истината и свободата е мнозинството.
|