|
Виж темите без отговор | Виж активните теми
Дата и час: Пон Юли 27, 2026 9:13 am
PIC 16F Смяна между светлинни ефекти с бутон
| Автор |
Съобщение |
|
Nyakоi
Ранг: Минаващ
Регистриран на: Вто Дек 20, 2016 7:39 pm Мнения: 32 Местоположение: Русе
|
 Re: PIC 16F Смяна между светлинни ефекти с бутон
Поиграх си още малко с програмката. Мисля, че се справих с двумерния масив, защото когато ръчно променям стойността на променливата effect между 0 и 1 чете първия и съответно втория ред на масива. До тук добре, но когато натисна бутона и програмата замръзва, не мога да си обясня защо обаче?! Малко си го измислих това while(debounce != 100), като че ли там умират нещата, въпреки, че ми звучи логично. С проверка if(debounce == 100) не се получава в този случай, ще трябва да се правят промени, но се сещам точно кое и как. Ако някой има идеи, добре дошли са  |  |  |  | Код: int counter, step, debounce, effect = 0;
char leds [2][10] = { {0x65, 0x9A, 0xA9, 0x56, 0xD1, 0x2E, 0xD1, 0x56, 0xA9, 0x9A}, {0x4, 0x1A, 0x8, 0x16, 0x10, 0xE, 0x20, 0xC1, 0x40, 0xA1} };
void Interrupt(){ if (TMR0IF_bit){ TMR0IF_bit = 0; TMR0 = 6; counter++; debounce++; } }
void main(){ while(1) {//main loop
if(counter == 100){ counter = 0; PORTB = leds[effect][step++]; if(step == 10){ step = 0; } } if(!RA6_bit){ debounce = 0; while(debounce != 100); effect++; }
} //end of main loop } |  |  |  |  |
Поздрави на всички!
_________________ Никола Богданов 16 години
Последна промяна Nyakоi на Сря Яну 11, 2017 11:31 pm, променена общо 1 път
|
| Сря Яну 11, 2017 10:10 pm |
|
 |
|
E1
Ранг: Почетен член
Регистриран на: Нед Юли 22, 2007 8:57 pm Мнения: 607 Местоположение: Белград
|
 Re: PIC 16F Смяна между светлинни ефекти с бутон
Къде правиш начална инициализация на counter, step и debounce?
Проблемът ти е тук: if(!RA6_bit) { debounce = 0; while(debounce != 100); effect++; }
Последна промяна E1 на Сря Яну 11, 2017 11:09 pm, променена общо 1 път
|
| Сря Яну 11, 2017 11:00 pm |
|
 |
|
Zdrav
Ранг: Форумен бог
Регистриран на: Сря Яну 26, 2005 2:01 pm Мнения: 1952 Местоположение: Варна
|
 Re: PIC 16F Смяна между светлинни ефекти с бутон
rev. 0.2  |  |  |  | Код: #define DEBOUNCE_LIMIT ((unsigned int)6) #define COUNTER_PERIOD ((unsigned int)6) #define EFFECTS_NUM (2) #define STEPS_NUM (10)
#define MOD(x) ((((signed int)(x)) >= 0) ? (unsigned int)(x):(unsigned int)((unsigned int)0 - (unsigned int)(x)))
volatile unsigned int counter, debounce, effect = 0; unsigned int step = 0;
char leds [EFFECTS_NUM][STEPS_NUM] = { {0x65, 0x9A, 0xA9, 0x56, 0xD1, 0x2E, 0xD1, 0x56, 0xA9, 0x9A}, {0x04, 0x1A, 0x08, 0x16, 0x10, 0x0E, 0x20, 0xC1, 0x40, 0xA1} };
void leds_step(); void next_effect();
void Interrupt(){ if(TMR0IF_bit){ TMR0IF_bit = 0; TMR0 = 100;
counter++;
if(!RA6_bit){ if(debounce < DEBOUNCE_LIMIT){ debounce++; } } else{ if(0 < debounce){ debounce--; } } } }
void leds_step() { PORTB = leds[effect][step++]; if(STEPS_NUM == step){ step = 0; } }
void next_effect() { if(effect < (EFFECTS_NUM - 1)){ effect++; } else{ effect = 0; } }
void main(){
unsigned char is_btn_pressed = 1; unsigned int counter_prev = counter;
while(1) { if(COUNTER_PERIOD <= MOD(counter - counter_prev)){ counter_prev += COUNTER_PERIOD; leds_step(); }
if(DEBOUNCE_LIMIT == debounce){ if(!is_btn_pressed){ is_btn_pressed = 1;
next_effect(); } } else if(0 == debounce){ is_btn_pressed = 0; } } }
|  |  |  |  |
_________________ Най-опасният враг на истината и свободата е мнозинството.
|
| Сря Яну 11, 2017 11:06 pm |
|
 |
|
ToHu
Ранг: Форумен бог
Регистриран на: Нед Сеп 26, 2004 9:21 pm Мнения: 30684 Местоположение: София
|
 Re: PIC 16F Смяна между светлинни ефекти с бутон
Да този While е проблем, избягвай го пп принцип ако не е наложително, а ако проверяваш нещо непредсказуемо винаги си оставяй някакъв изход. Както го е напосал колегата ще стане въпреки че аз гледам да стоя въжно най малко в прекъсване. Сетването на таймера за случая може да е ОК но по принцип по добре да добавяш, при малък прескалер докато стигнеш до там той вече ще се е инкремвнтнал с 1 и като запишеш 6 интервала става по-голям, а ако добавиш ще е 7.
|
| Чет Яну 12, 2017 3:43 am |
|
 |
|
Nyakоi
Ранг: Минаващ
Регистриран на: Вто Дек 20, 2016 7:39 pm Мнения: 32 Местоположение: Русе
|
 Re: PIC 16F Смяна между светлинни ефекти с бутон
Всъщност отговорът ми е написан още на първата страница, за което благодаря, защото снощи си скъсах нервите да мисля, и накрая реших да погледна даденият пример Потенциално проблемче беше това, че единият ефект е с дължина 10 стъпки, а другият - 12 стъпки. Ако задам дължина на масива 12, 10-стъпковия ефект имаше едно гадно положение, защото последните 2 стъпки държи порта нулиран, тъй като те липсват. Неща станаха като променям това 10 тук заедно с ефекта. Това: Стана така: , където maxstep се set-ва в суича, където сменям ефектите. Та кодът е този:  |  |  |  | Код: int counter, step, effect = 0, maxstep = 10; unsigned push = 0;
char leds [3][12] = { {0x00}, {0x65, 0x9A, 0xA9, 0x56, 0xD1, 0x2E, 0xD1, 0x56, 0xA9, 0x9A}, {0x4, 0x1A, 0x8, 0x16, 0x10, 0xE, 0x20, 0xC1, 0x40, 0xA1, 0x80, 0x61} };
void Interrupt(){ if (TMR0IF_bit){ TMR0IF_bit = 0; TMR0 = 6; counter++; } }
void main(){ TRISB = 0; TRISA = 1; PORTB = 0;
OPTION_REG = 0x81; TMR0 = 6; INTCON = 0xA0;
while(1){
if(counter == 100){ counter = 0; PORTB = leds[effect][step++]; if(step == maxstep){ step = 0;
if(push == 1){ push = 0; PORTB = 0x00; switch(effect){ case 0 : effect = 1; maxstep = 10; break; case 1 : effect = 2; maxstep = 12; break; case 2 : effect = 0; break; } } }
if(!RA6_bit){ push = 1; } } } } |  |  |  |  |
Изключеното засега съм го направил с нулиране на порт B, защото устройството няма да се захранва с батерии, просто не искам да мига когато е на OFF. Остана да допълня ефектите и да тествам хардуерно. Искам да благодаря на всички, които се включиха и помогнаха, тъй като нещата с таймерите ми бяха абсолютно непонятни. Следващият ми проект ще е да чета PWM, така че ще ми трябват таймерчета  .
_________________ Никола Богданов 16 години
|
| Чет Яну 12, 2017 2:22 pm |
|
 |
|
ToHu
Ранг: Форумен бог
Регистриран на: Нед Сеп 26, 2004 9:21 pm Мнения: 30684 Местоположение: София
|
 Re: PIC 16F Смяна между светлинни ефекти с бутон
Четенето на PWM ще стане най-добре с кепчър модула, той е там в таймерите на този проц. Иначе за ефектите, след като го докара тук е време за следващата стъпка, може да си направиш структури със самите ефекти, например : define max_step = 20; struct effect_type { char output_state [max_steps]; char steps ; unsigned int period; }; и след това си декларираш само масива със структури, колкото са ти ефектите например : struct effect_type efect[3]; а ако ще ти е винаги статично може да си го декларираш горе веднага след декларацията на структурата, и там и да си я инициализираш. Така в кода ти ще имаш следните проверки : за времето if(timer_count > effect[i].period) .... за дължината if(step>effect[i].steps) i=0 else if (step > max_steps) step = 0 else step++; и съотвенто порта PORTB=effect[i].output_state[step]; И така вече не буташ нищо в кода, ако искаш повече стъпки глобално, променяш max_steps дефиницията, а самите ефекти им задаваш броя стъпки, състояния и период на повторение в инициализацията на структурата, която пък по-нататък може да ти идва отвън .. абе идеята е че не буташ никъде в кода, е ако не броим инициализацията за код 
|
| Чет Яну 12, 2017 8:34 pm |
|
 |
|
E1
Ранг: Почетен член
Регистриран на: Нед Юли 22, 2007 8:57 pm Мнения: 607 Местоположение: Белград
|
 Re: PIC 16F Смяна между светлинни ефекти с бутон
В MikroC имаш PWM библиотека. Също така, на libstock (сайта за проекти на Mikroelektronika) има публикувана тази soft PWM библиотека.
|
| Чет Яну 12, 2017 10:57 pm |
|
 |
|
ToHu
Ранг: Форумен бог
Регистриран на: Нед Сеп 26, 2004 9:21 pm Мнения: 30684 Местоположение: София
|
 Re: PIC 16F Смяна между светлинни ефекти с бутон
Той май говори за мерене на PWM ама може и аз да не съм разбрал. Иначе правенето чак библиотека ... най-чистият вариант за софтуерен PWM е да си нарочиш някой таймер за базов и по него да въртиш колкото ти трябват PWM-ми , разбира се по добро от хардуерния няма, но в този имаш само еидн хардуерен.
|
| Чет Яну 12, 2017 11:16 pm |
|
 |
|
slav4o.com
Ранг: Форумен бог
Регистриран на: Нед Яну 01, 2012 8:04 pm Мнения: 2663 Местоположение: София / Велико Търново
|
 Re: PIC 16F Смяна между светлинни ефекти с бутон
Как да се мери PWM ? Период / честота може би.
|
| Пет Яну 13, 2017 12:23 am |
|
 |
|
Nyakоi
Ранг: Минаващ
Регистриран на: Вто Дек 20, 2016 7:39 pm Мнения: 32 Местоположение: Русе
|
 Re: PIC 16F Смяна между светлинни ефекти с бутон
Не честота, а време  . Става въпрос за контролери (спийд-контролер, за светлини и тн.) по радиоуправляем автомодел. Нещата стоят така: периодът е фиксиран на 20 милисекунди. Променя се дължината на импулса, която варира от 1ms(пълен реверс, заден ход при RC моделите) - 1,5ms(неутрално положение) - 2ms(100% газ напред). Идеята е да измервам този импулс (в интернет намирам чрез детектване на нарастващ и спадащ фронт, май точно capture mode се води), и спрямо него линейно да управлявам мощни мосфети в конфигурация H-мост, чрез който да управлявам четков електромотор. Примерно когато импулса е 1,6ms да се равнява на 20% газ, 1,7ms - 40%, 1,8ms - 60% и така до 100. Другото, за което си мисля, е модул за светлини, който пак ще стане чрез измерване на импулс, само че там вече ще има ако следват два импулса с една и съща продължителност се светват фарове, а ако са 3 импулсите - аварийни свтлини, мигачи и така нататък. Китаецът го е измислил, но аз обичам да преоткривам топлата вода, пък и нали се уча по този начин  П.п. Предавателя и приемника се водят 3 канални, 1 канал е за газта, 2ти канал е за завиването на модела чрез серво-машинка, и 3тия канал досега успешно използвах за фарове чрез готина flip-flop логическа схема със ИС 4013, но реших, че мога да използвам този 3ти канал доста по-пълноценно (да му накача много функции чрез различни комбинации и проверки от страна на микроконтролера).
_________________ Никола Богданов 16 години
|
| Пет Яну 13, 2017 1:02 am |
|
 |
|
ToHu
Ранг: Форумен бог
Регистриран на: Нед Сеп 26, 2004 9:21 pm Мнения: 30684 Местоположение: София
|
 Re: PIC 16F Смяна между светлинни ефекти с бутон
Мери се коефициент на запълване, в по-простият случай мериш само времето на високото ниво, но това е само ако си сигурен колко ти е периода, и за да не стават грешки най-добре да се мерят и двете и да се се смята отношението.
|
| Пет Яну 13, 2017 1:24 am |
|
 |
|
Nyakоi
Ранг: Минаващ
Регистриран на: Вто Дек 20, 2016 7:39 pm Мнения: 32 Местоположение: Русе
|
 Re: PIC 16F Смяна между светлинни ефекти с бутон
Смея да твърдя, че периодът не се променя. Не съм сигурен дали е 20ms, но би трябвало да е толкова, защото при тези системи нещата трябва да са с доста малки толеранси заради нужната висока точност на предаване на сигналите, при самолетите например, където каналите стигат и до 9. Гледал съм какво се случва на осцилоскоп, и ясно се вижда, че периодът остава същия. Променя се само дължината на импулса. Нея ако успея да измеря пак ще е нещо като за начало и за тестове.
_________________ Никола Богданов 16 години
|
| Пет Яну 13, 2017 1:28 am |
|
 |
|
ToHu
Ранг: Форумен бог
Регистриран на: Нед Сеп 26, 2004 9:21 pm Мнения: 30684 Местоположение: София
|
 Re: PIC 16F Смяна между светлинни ефекти с бутон
При управлението с pwm, най-вече при првдаване на информация периода няма никакво значение, важен е коефициента на запълване. Дали ще е 2 мс или 20 мс 10% са винаги 10%. Възможно е едно устройство да има 20 мс друго да е 18 а защо не и 10. За да си сигурен мериш и периода и импулса.
|
| Пет Яну 13, 2017 2:52 am |
|
 |
|
E1
Ранг: Почетен член
Регистриран на: Нед Юли 22, 2007 8:57 pm Мнения: 607 Местоположение: Белград
|
 Re: PIC 16F Смяна между светлинни ефекти с бутон
Това, което виждам е класическото управление на сервомоторчета. Управлението е чрез промяна продължителността на високото ниво. Може би това имаше предвид под "измерване на PWM". На практика се променя продължителността и на високото, и на ниското ниво, защото периодът не се променя(20ms), а зададеният ъгъл (0-180 градуса) е сбит в 1ms(1-2ms). За тази цел, струва ми се, че е най-удачно да се използва прекъсване при промяна на пин (например RB0), в комбинация с прекъсване от таймер. Пример за прекъсване от RB0 в MikroC има в примерите към компилатора: Project -> Open Examples Folder -> Internal MCU modules ->P18F4520 -> External Intrerrupt
|
| Пет Яну 13, 2017 12:02 pm |
|
 |
|
ToHu
Ранг: Форумен бог
Регистриран на: Нед Сеп 26, 2004 9:21 pm Мнения: 30684 Местоположение: София
|
 Re: PIC 16F Смяна между светлинни ефекти с бутон
Ами аз горе бях на път да напиша че това не е PWM ама си е точно това, свикнали сме да го изпозлваме за ргулиране, но то си е просто вид модулация, та наистина си е PWM  Иначе с другото съм съгласне с Е1, прекъсване и таймер, въпреки че може и с кепчър-а
|
| Пет Яну 13, 2017 12:36 pm |
|
|
Кой е на линия |
Потребители разглеждащи този форум: 0 регистрирани и 11 госта |
|
Вие не можете да пускате нови теми Вие не можете да отговаряте на теми Вие не можете да променяте собственото си мнение Вие не можете да изтривате собствените си мнения Вие не можете да прикачвате файл
|
|