Микроконтролери и електроника
http://mcu-bg.com/mcu_site/

Играчка закачка с PIC16F887
http://mcu-bg.com/mcu_site/viewtopic.php?f=3&t=13529
Страница 1 от 1

Автор:  dgeorgiev92 [ Сря Яну 21, 2015 1:19 am ]
Заглавие:  Играчка закачка с PIC16F887

Привет на всички. Нов съм във форума и ако правя грешно моля да ми кажете за да се поправя. Начинаещ съм със Microchip микроконтролерите имам повече опит със Arduino средата та стига съм ви занимавал с мен. Имам задача с въпросния контролер която се състой в следното, с два потенциометъра да задавам честота на два канала. Аз използвах един таймер но може й двата да се използват. Програмата която успях да сътворя работи но честотата се изменя по логаритмичен закон а на мен ми трябва да е линейно. давам кода който съм сътворил й моля кажете от къде идва това явление и как да го оправя.
Поздрави Деян.

Код:
void interrupt MainIsr (void)
{
    //Опит само със един таймер да работят и двата канала
    unsigned int uiWork;
    if (TMR1IF)         //Timer 1 interrupt - stepper control
    {
        TMR1IE  = FALSE;    //Disable timer 1 interrupt
        TMR1IF  = FALSE;    //Clear interrupt flag
        DIR2    = TRUE;     //painter spin is always negative
       
        uiWork = (1024-uiPot1) >> 3;
        if (++uiCnt1 > uiWork)
        {
            STEP    = TRUE ;     //Generate pulse for the RC2
            uiCnt1  = 0;
        }

        uiWork = (1024 - uiPot2) >> 2;
        if (++uiCnt2 > uiWork)
        {
            STEP2    = TRUE ;     //Generate pulse for the RC0
            uiCnt2  = 0;
        }

        TMR1L   = MAX_SPEED;// (unsigned char)(uiSpeedScaled);
        TMR1H   = MAX_SPEED>>8;//(unsigned char)(uiSpeedScaled>>8);
//End Speed controller
        TMR1IE  = TRUE;         //Enable the timer 1 interrupt again
        STEP    = FALSE;       //reset the step signal - one pulse generated
        STEP2   = FALSE;        //reset the step signal - one pulse generated

}//of main interrupt service routine

Автор:  vesko_hard [ Сря Яну 21, 2015 10:05 am ]
Заглавие:  Re: Играчка закачка с PIC16F887

А сигурен ли си дали потенциометрите не са логаритмични ?

Автор:  rumen65 [ Сря Яну 21, 2015 10:24 am ]
Заглавие:  Re: Играчка закачка с PIC16F887

Нормално да е така. Задаваш периода пропорционално на напрежението, а ти трябва честотата. За да го направиш, първо от напрежението сметни нужната ти честота, а след това периода за тази честота. И тъй като ще има и деление, не е подходящо за този процесор сметките да ги правиш в прекъсването, а в главната програма.

Автор:  dgeorgiev92 [ Сря Яну 21, 2015 4:35 pm ]
Заглавие:  Re: Играчка закачка с PIC16F887

Потенциометрите са линейни. Да аз променям периода защото не е важно колко е продължителноста на импусите. Важно е да не се изменя логаритмично периода и със прескачания между отделните честоти (колкото се може по плавно да става). Опитах се да направя както каза rumen65 но като преместя изчисленията в майна и не иска изобщо да цъка изхода.

Автор:  rumen65 [ Сря Яну 21, 2015 5:01 pm ]
Заглавие:  Re: Играчка закачка с PIC16F887

Последно, кое трябва да се променя линейно - периода или честотата. Защото връзката между тях не е линейна F=1/T. Ако едното се променя линейно, другото няма.

Прикачени файлове:
func1x.gif
func1x.gif [ 3.76 KiB | Прегледано 5820 пъти ]

Автор:  dgeorgiev92 [ Сря Яну 21, 2015 5:29 pm ]
Заглавие:  Re: Играчка закачка с PIC16F887

Периода трябва да се изменя линейно.

Автор:  stoyanoff [ Сря Яну 21, 2015 10:46 pm ]
Заглавие:  Re: Играчка закачка с PIC16F887

По-скоро мисля, че имаш проблем с програмата, а не с алгоритъма, след като изобщо не иска да цъка!
А може и с двете! Пусни един дебъгер и виж какво става!

Автор:  Н'бабане Гт'муан'га [ Сря Яну 21, 2015 11:14 pm ]
Заглавие:  Re: Играчка закачка с PIC16F887

Според това което си дал импулсите STEP които генерираш ще са дълги по няколко наносекунди.
Опитай ето така:
Код:
void interrupt MainIsr (void)
{
    //Опит само със един таймер да работят и двата канала
    unsigned int uiWork;
    if (TMR1IF)         //Timer 1 interrupt - stepper control
    {
        TMR1IF  = FALSE;    //Clear interrupt flag
        DIR2    = TRUE;     //painter spin is always negative

        TMR1L   = MAX_SPEED;// (unsigned char)(uiSpeedScaled);
        TMR1H   = MAX_SPEED>>8;//(unsigned char)(uiSpeedScaled>>8);
         
        uiWork = (1024-uiPot1) >> 3;
        if (++uiCnt1 > uiWork)
        {
            STEP    = TRUE ;     //Generate pulse for the RC2
            uiCnt1  = 0;
        } else STEP    = FALSE;       //reset the step signal - one pulse generated

        uiWork = (1024 - uiPot2) >> 2;
        if (++uiCnt2 > uiWork)
        {
            STEP2    = TRUE ;     //Generate pulse for the RC0
            uiCnt2  = 0;
        } else STEP2   = FALSE;        //reset the step signal - one pulse generated

        TMR1IE  = TRUE;         //Enable the timer 1 interrupt again
    }
}//of main interrupt service routine

Автор:  Cekins [ Чет Яну 22, 2015 8:18 am ]
Заглавие:  Re: Играчка закачка с PIC16F887

Точно така се получава. Скоро правих абсолютно същата постановтка. Просто си сметнах една табличка в ексел с 1024 стойности и чета от нея периода. По късно ще дам подробности, че сега пиша от телефона.


уф... чак сега успях да седна на нормална клавиатура...

Значи примерно ей това : 13000000/(200+{adc_input}) дава от около 76 до 470 херца напълно линейно (колкото е възможно при 10 бита де). Аз го направих единия таймер (8 битов) изключва изхода, прелоудва друг 16 битов таймер с някоя от стойностите и го пуска. 16 битовия таймер като изтече включва малкия таймер и съответния изход. На практика малкия таймер, който генерира пулса вкарва лееека нелинейност в честотата. В моя случай се управляват драйвери на стъпкови мотори и мога да си позволя пулса да е много кратък.

В ексела като се поиграе малко с числата могат да се докарат всякакви честоти (е ествествено в рамките на възможностите на таймера), после се вкарват в една таблица и няма никакъв овърхед от постоянна аритметика.

А за още по-лесно едни от най-новите 16-ки имат NCO - какво повече му трябва на човек :)

Автор:  rikotech [ Нед Яну 25, 2015 2:17 pm ]
Заглавие:  Re: Играчка закачка с PIC16F887

Много сложно ми се вижда решението на толкова проста задача.
Така няма ли да стане.
Всеки път като влизаме в ISR то превключваме състоянието на изхода. Като задаваме стойност на таймера (вътре в ISRто) според прочетената стойност на ADCто променяме периода му на прекъсване. Колкото по висока стойност задаваме на регистрите на таймера толкова по скоро ще настъпи следващото прекъсване респективно ще расте и честотата на изхода.

Код:
void TimerIsr(void)
{
   TMR1IF  = FALSE;
   output_pin ^= 1;                                     // toggle състоянието на изхода
   TMR1L = (adc_value*64) & 0xFF;              //*64 преобразува 10-битова стойност на adc в 16-битова за таймера.
   TMR1H = ((adc_value*64)>>8) & 0xFF;   
}

Автор:  dgeorgiev92 [ Чет Яну 29, 2015 12:00 pm ]
Заглавие:  Re: Играчка закачка с PIC16F887

Точно това правя rikotech но когато започна да увеличавам таимера с потенциометъра изменението на честотата става логаритмично и как да компенсирам това изменение и да се движи линейно честотата

Автор:  Ники [ Чет Яну 29, 2015 12:11 pm ]
Заглавие:  Re: Играчка закачка с PIC16F887

най-лесно ми се вижда с таблица, от която при дадена стойност на ацп, взимаш нужната стойност за таймера.

Автор:  rikotech [ Съб Яну 31, 2015 9:56 pm ]
Заглавие:  Re: Играчка закачка с PIC16F887

Прочети за това:

NUMERICALLY CONTROLLED
OSCILLATOR (NCO) MODULE

можеш да намериш повече инфо тук: http://www.microchip.com/pagehandler/en-us/family/8bit/peripherals/coreindependent/nco-prdpge.html

Автор:  dgeorgiev92 [ Пон Мар 23, 2015 3:15 pm ]
Заглавие:  Re: Играчка закачка с PIC16F887

В крайна сметка го направих с масив от променливи и стана доста гладко.
Но сега имам нова задача да чета един сензор по I2C и успах но когато тръгна да дебъгвам и рестартрам програмата не иска да стартира I2C шината и трябва да спирам захранването. от какво може да е този проблем.

Страница 1 от 1 Часовете са според зоната UTC + 2 часа [ DST ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/