| Микроконтролери и електроника http://mcu-bg.com/mcu_site/ |
|
| Zilog - Z8 Encore! F083A Series http://mcu-bg.com/mcu_site/viewtopic.php?f=3&t=15952 |
Страница 1 от 2 |
| Автор: | Metyyy [ Вто Юни 05, 2018 3:53 pm ] |
| Заглавие: | Zilog - Z8 Encore! F083A Series |
Здравейте, В момента разучавам таймера на горе посоченият микроконтролер. Искам да го конфигурирам в one-shot mode. Според спецификацията: One-Shot Mode Time-Out Period (s) = (Reload Value – Start Value) * Prescale / System Clock Frequency (Hz) След заместване: (65535 - 0) * 128 / 20MHz = 420ms (приблизително). "От горните изчисления излиза, че максималното време на препълване на таймера е 419424μs или приблизително 420ms, т.е.. периодът на правоъгълните импулси ще бъде 420ms * 2 = 840ms (1.2Hz)." Не разбирам, защо трябва да умножаваме 420ms * 2 ? Ако приемем, че T (период) = 420ms =>, че f = 1 / T => 1 / 0,42s (420ms) = 2,4Hz, но ако умножим 420ms * 2 = 840ms =>, че f = 1 / T => 1 / 0,84s (840ms) = 1,2Hz. Явно бъркам максималното време за препълване на таймера със периода? Наясно съм, че питам елементарни и глупави неща, но много бих се радвал, ако някой ми разясни как точно се случват нещата. Ами, ако искам да направя диода да свети на 5 или 10s ? Мисля, че няма да стане, тъй като максималния делител е 128? Благодаря, предварително! |
|
| Автор: | miro_atc [ Вто Юни 05, 2018 4:22 pm ] | ||||||||||||||||||
| Заглавие: | Re: Zilog - Z8 Encore! F083A Series | ||||||||||||||||||
Не познавам въпросния таймер, но това си е обща болест... При едно извъртане на таймера имаш 1 събитие. Ако искаш второ събитие се налага още веднъж да извъртиш или таймер с повече compare регистри. От друга страна за да генерираш правоъгълен импулс ти трябват две събития (по едното правиш преден фронт, по другото заден). И те така, първия път таймера като каже "щрак" имаш единия фронт. Втория път като каже "щрак" имаш и другия фронт. Както и да ги броим това са 2 щракания за един период
Когато надскочиш възможностите на хардуера се налага да пишеш софтуер. Демек софтуерно си правиш един брояч колко пъти е казал "щрак" таймера. За удобство може таймера да го настроиш на по-кръгло число, да кажем 100ms. И така като софтуерния брояч стане 25, палиш диода, след още 25 щракания гасиш. Ето ти ги 5s. За 10s ще се сетиш сам |
|||||||||||||||||||
| Автор: | itso.t [ Вто Юни 05, 2018 6:25 pm ] | |||||||||
| Заглавие: | Re: Zilog - Z8 Encore! F083A Series | |||||||||
Виж тая тема - http://www.mcu-bg.com/mcu_site/viewtopi ... =2&t=15883 Там са обсъждани различни начини да си мигаш и светкаш. |
||||||||||
| Автор: | ike [ Вто Юни 05, 2018 11:41 pm ] |
| Заглавие: | Re: Zilog - Z8 Encore! F083A Series |
Онази тема само ще го обърка още повече, особено ако сега почва. |
|
| Автор: | slav4o.com [ Сря Юни 06, 2018 12:02 am ] | |||||||||
| Заглавие: | Re: Zilog - Z8 Encore! F083A Series | |||||||||
Ами на 420ms ти се променя (обръща) изходното ниво (състояние). 420ms лог.1 420ms лог.0 . Получава се период на честотата 840ms или 1.19Hz. Повечето системи където има делене на честотата работят така. Всъщност това нещо което обръща изхода е примерно един JK тригер, който реално дели на две. Предимството както се вижда е, че при какъвто и да е коефициент на делене на брояча, се получава 50/50 коефициент на запълване, нещо което няма как да стане иначе при произволен коефициент. |
||||||||||
| Автор: | Metyyy [ Сря Юни 06, 2018 1:23 am ] |
| Заглавие: | Re: Zilog - Z8 Encore! F083A Series |
Благодаря на всички ! Може би, отговора на miro_atc е най-близко разбираем за моите възможности в момента Опитах се да направя delay 5s, но честно да си призная софтуерната част (Delay_Counter_5s == 11) с избора на числово 11 беше чисто и просто налучкване. Не мога да разбера, как получих 5s delay, при положение, че имам първоначално 0.82s и после 11? Съжалявам, ако отговора е очевиден. Откровено казано, темата пратена от itso.t, наистина ме обърка и все пак благодаря ! #include<ez8.h> /* Този хедър позволява да достъпваме вътрешните регистри като всички останали, чрез имената им. */ #define DD0_OFFSET (0) #define IRQE_OFFSET (7) #define TENH_OFFSET (5) #define TENL_OFFSET (5) #define TH_OFFSET (0) #define TL_OFFSET (0) #define TRH_VALUE (65535) #define TRL_VALUE (65535) #define TEN_BIT (7) #define TPOL_BIT (6) #define PRES_BIT_5 (5) #define PRES_BIT_4 (4) #define PRES_BIT_3 (3) #define TMODE_BIT_2 (2) #define TMODE_BIT_1 (1) #define TMODE_BIT_0 (0) #define TMODEHI_BIT (0) #define TCTL1_VALUE ((1<<TEN_BIT) | (0<<TPOL_BIT) | (1<<PRES_BIT_5) | (1<<PRES_BIT_4) | (1<<PRES_BIT_3) | (0<<TMODE_BIT_2) | (0<<TMODE_BIT_1) | (0<<TMODE_BIT_0)) #define POUT0_VALUE (0) typedef unsigned char u08; int main(void) { PADD &= ~(1<<DD0_OFFSET); /* За да конфигурираме извод PA0 като изход, трябва да нулираме бит 0 на регистър PADD */ IRQCTL |= 1<<IRQE_OFFSET; /* Прекъсванията се разрешават с глобалния бит IRQE в регистър IRQCTL. Бит IRQE се установява в 1 */ IRQ0ENL |= 1<<TENL_OFFSET; /* Достатъчно е да установим единия от двата или и двата бита. Младши бит 5 e за разрешаване на прекъсване от Таймер0. Всеки източник на прекъсване има локален механизъм за разрешаване. Този механизъм също се използва за задаване и на софтуерен приоритет на прекъсванията. Тъй като имаме само един източник на прекъсване в програмата, е без значение какво ниво на приоритет ще изберем. */ IRQ0ENH |= 1<<TENH_OFFSET; /* Достатъчно е да установим единия от двата или и двата бита. Младши бит 5 e за разрешаване на прекъсване от Таймер0. Всеки източник на прекъсване има локален механизъм за разрешаване. Този механизъм също се използва за задаване и на софтуерен приоритет на прекъсванията. Тъй като имаме само един източник на прекъсване в програмата, е без значение какво ниво на приоритет ще изберем. */ T0H = TH_OFFSET; /* Записваме начална стойност на таймера в броячните регистри TxH и TxL, т.е. ги нулираме */ T0L = TL_OFFSET; /* Записваме начална стойност на таймера в броячните регистри TxH и TxL, т.е. ги нулираме */ T0RH = TRH_VALUE; /* Регистрите съдържат макс. 16-битова броячна стойност до която брои таймера и тя е 65535 */ T0RL = TRL_VALUE; /* Регистрите съдържат макс. 16-битова броячна стойност до която брои таймера и тя е 65535 */ /* One-shot mode: T = (65535 - 0) * 128 / 20MHz = 419424 микросекунди = 420ms (приблизително) За да генерираме правоъгълен импулс ни трябват две събития (по едното правим преден фронт, по другото заден), затова и трябва да умножим 420ms * 2 = 840ms = 0.84s; T = 1 / 0,84 = 1.2Hz */ T0CTL0 = TMODEHI_BIT; /* Еднократен режим */ T0CTL1 = TCTL1_VALUE; /* Коефициент на деление 128 и стартиране на таймера */ while(1); } void interrupt Timer0_ISR(void) _At TIMER0 { static u08 Delay_Counter_5s = 0; if (Delay_Counter_5s == 11) { PAOUT ^= 1<<POUT0_VALUE; /* Превключване на нивото на извод PA0 */ Delay_Counter_5s=0; } else { Delay_Counter_5s++; } T0CTL1 |= 1<<TEN_BIT; /* Стартиране на таймера отново */ } |
|
| Автор: | ike [ Сря Юни 06, 2018 7:48 pm ] | |||||||||
| Заглавие: | Re: Zilog - Z8 Encore! F083A Series | |||||||||
420ms * 11 = 4620ms = 4.62s |
||||||||||
| Автор: | Metyyy [ Сря Юни 06, 2018 8:21 pm ] |
| Заглавие: | Re: Zilog - Z8 Encore! F083A Series |
По скоро 420 * 10 = 4200ms = 4.2s |
|
| Автор: | slav4o.com [ Сря Юни 06, 2018 8:27 pm ] |
| Заглавие: | Re: Zilog - Z8 Encore! F083A Series |
Не знам какво си направил. По принцип като изтече периода 420ms се вдига някакъв флаг. Ти или трябва да го проверяваш достатъчно често, или да викаш прекъсване. Когато видиш че е вдигнат флага, го изчистваш и правиш нещо, каквото ти е необходимо. Ако обръщаш изхода на всяко вдигане на флага ще имаш 420ms ниско и 420ms високо ниво. Реално честотата е двойно по-ниска от тази на вдигането на флага. От там идва това 2. Ако броиш 10 пъти вдигане на флага, да 10х420мс и си правиш там нещо като изброиш до 10, т.е. като мине закъснението от 4.2ms. Ако искаш може да броиш до 10 и да обръщаш изхода, така ще поучиш период 8.4s или 0.119Hz, което всъщност няма почти никакво смислено приложение. |
|
| Автор: | miro_atc [ Пет Юни 08, 2018 9:27 am ] |
| Заглавие: | Re: Zilog - Z8 Encore! F083A Series |
Не знам, не съм гледал и не искам да гледам документацията на твоя чеп... Но съм видял стотици други и навсякъде таймер се прави с един брояч и един компаратор, които клокваш с някакъв клок. Когато компараторът види еднакви стойности броячът се презарежда и имаш прекъсване. Елементарно е, само че сметките са малко по-различни от тия дето си дал. Ако приемем че броячът брои от 0 и се ресетва до 0, то най-малката стойност дето може да сложиш в компаратора е също нула. При това на всеки такт ще имаш прекъсване и броячът ще брои 0, 0, 0, 0, 0... Изходната честота ще ти е точно 2 пъти по-ниска. Ако сложиш 1 в компаратора, броячът ще брои 0,1,0,1,0,1.... демек ще имаш прекъсване на всеки два такта или с други думи изходната честота е 4 пъти по-ниска. Така че формулата би трябвало да е нещо от сорта: One-Shot Mode Time-Out Period (s) = (Reload Value +1 – Start Value) * 2* Prescale / System Clock Frequency (Hz) Нека да приемем prescale=1 и системен клок 1MHz Тогава в първия пример когато reload value=0 и start value=0 имаш X = (0+1-0)*2*1/1000000 = 2/1000000 = 2us Сега в твоя случай ако брои от 0 до 11, това са си 12 стойности или 12 клока за едно прекъсване или по друг начин казано 12 * 420ms =5.04s толкова получаваш нали? |
|
| Автор: | slav4o.com [ Съб Юни 09, 2018 12:25 am ] | |||||||||||||||||||||||||||
| Заглавие: | Re: Zilog - Z8 Encore! F083A Series | |||||||||||||||||||||||||||
Хм аз пък си мисля, че 250ms x 20 = 5s. Тааака избрал си все пак 200ms. Първо трябва да разбереш откъде взема тактов сигнал този таймер. Имаш прескалер, което значи че входната честота се дели. В случая тя се дели на 128 : 20MHz/128 = 156,25kHz. Периода е 1/156,25 = 6,4uS. Така. За да получиш заветните 200ms, брояча трябва да изброи: 200 000 / 6,4 = 31 250пъти (периода). Това ти е коефициента на брояча. Сега. Процесора ти не знам какъв е , но на PIC-овете първо се настройва таймера и се пуска да си цъка прекъсвания постоянно. Тук ако е така пускаш си го и ще ти генерира прекъсванията. Дотук добре. Ти си харесел период 200ms, което значи че трябва да изброиш 25 пъти докато направиш 5 секунди. Значи във прекъсването трябва да инкрементираш един брояч, който ще ти брои до 25. Да го кръстим unsigned char intcnt; Сега идва ключовият момент. Искаш да кажеш старт на хронометъра и да почнеш да отчиташ заветните 5 секунди. Понеже не знаеш какво число държи брояча на прекъсвания и какво брояча на таймера (понеже си вървят свободно) трябва да ги нулираш. Първо нулираш брояча на таймера , после брояча на прекъсвания, после пак брояча на таймера.
Умишлено го нулирам два пъти, първият път може брояча да е на 31 249. Това ми гарантира, че докато нулирам intcnt няма да се извика прекъсването (и да го инкрементира). След това нулирам отново брояча и забележи нулирам последно младшия байт. Така се получава минимално натрупване, докато почнеш да изпълняваш чакането на 5те сек. т.е. максимално точно да е. Така вече имаш функция с която стартираш хронометъра. Остава и да разбереш кога ти е изтекло времето.
Има и други начини, със стартиране и спиране на таймера. Аз обаче в моите програми не ги ползвам, тъй като таймера дава тайминги и на други процеси. Освен това не ми са критични толкова времената. Има и други варианти PICовете имат постскалери, постскалера е това което е intcnt. Само, че може да се настрои автоматично да брои примерно до 16 и тогава да ти се генерира прекъсване. Този процесор обаче е друг и не зная дали има. Пък и за теб е важно да знаеш принципно как се прави, а към съответния процесор ще се нагодиш лесно. Ако не ти трябва точност, може да се нулира само intcnt, т.е. софтуерният ти постскалер. |
||||||||||||||||||||||||||||
| Автор: | slav4o.com [ Съб Юни 09, 2018 1:02 am ] | |||||||||||||||||||||||||||
| Заглавие: | Re: Zilog - Z8 Encore! F083A Series | |||||||||||||||||||||||||||
Всъщност те подведох, intcnt ще се инкрементира винаги и след като се превърти, ще ще вика IztekloWreme(); затова ще използваме семафор BOOL timeout = true; с който ще указваме кога да се работи
когато влезеш в IztekloWreme(); "светваш" семафора и в прекъсванията ти няма да се броят пакетите от 200ms. Така докато не стартираш отново хронометъра. |
||||||||||||||||||||||||||||
| Автор: | Metyyy [ Нед Юни 10, 2018 12:23 pm ] |
| Заглавие: | Re: Zilog - Z8 Encore! F083A Series |
Благодаря ти за отговора ! Това е което аз направих: Имам системна честота - 20MHz => Честота на таймера - 20MHz / 128 (prescaler) = 156250Hz => Периода на таймера - 1 / 156250 = 0.0000064s или 6.4us => Таймера се увеличава с 1 на всеки 6.4us. "За да получиш заветните 200ms, брояча трябва да изброи: 200 000 / 6,4 = 31 250 пъти (периода). Това ти е коефициента на брояча." - Благодаря ти за това изречение ! Точно това исках да разбера. Също така си абсолютно прав, че трябва да избера 250ms, а не 200ms, защото за 5s при 200ms, ще имам 25 прекъсвания, а за 5s при 250ms, ще имам 20 прекъсвания, което са си 5 по-малко => началната стойност на таймера ще е 250 00 / 6.4 = 39062.5 пъти (периода) => ще брои от 39062.5 до 65535 => прекъсване и следния код: void interrupt Timer0_ISR(void) _At TIMER0 { static u08 Delay_Counter_5s = 1; if (Delay_Counter_5s == 11) { PAOUT ^= 1<<POUT0_VALUE; /* Превключване на нивото на извод PA0 */ Delay_Counter_5s=0; } else { Delay_Counter_5s++; } T0CTL1 |= 1<<TEN_BIT; /* Стартиране на таймера отново (One-shot mode) */ } Логиката ми е: Таймера почва да брои до 65535 => прекъсване - 1=11 (false) - брояча се увеличава => Таймера почва да брои до 65535 => прекъсване - 2=11 (false) - брояча се увеличава => Таймера почва да брои до 65535 => прекъсване - 3=11 (false) - брояча се увеличава => Таймера почва да брои до 65535 => прекъсване - 4=11 (false) - брояча се увеличава => Таймера почва да брои до 65535 => прекъсване - 5=11 (false) - брояча се увеличава => Таймера почва да брои до 65535 => прекъсване - 6=11 (false) - брояча се увеличава => Таймера почва да брои до 65535 => прекъсване - 7=11 (false) - брояча се увеличава => Таймера почва да брои до 65535 => прекъсване - 8=11 (false) - брояча се увеличава => Таймера почва да брои до 65535 => прекъсване - 9=11 (false) - брояча се увеличава => Таймера почва да брои до 65535 => прекъсване - 10=11 (false) - брояча се увеличава => Таймера почва да брои до 65535 => прекъсване - 11=11 (true) - светва диода и нулираме брояча Така, имаме 10 прекъсвания на таймера и 10 на софтуерния броят, демек общо 20 прекъсвания. Това ли трябва да ми е логиката ? Надявам се да, защото уж на пръв поглед един прост таймер ми отне толкова време за разбиране, че ужас Сега, като засека с хронометъра уж са 5s, но все пак не мога да съм абсолютно сигурен. |
|
| Автор: | palavrov [ Нед Юни 10, 2018 2:15 pm ] |
| Заглавие: | Re: Zilog - Z8 Encore! F083A Series |
Вземи си един евтин логически анализатор за няма и $10 и ще може да го измериш достатъчно точно + ще ти е в полза и в бъдеще. |
|
| Страница 1 от 2 | Часовете са според зоната UTC + 2 часа [ DST ] |
| Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |
|