Learn how easy it is to sync an existing GitHub or Google Code repo to a SourceForge project! See Demo

Close

Servo controling with ATmega32 and FreeRTOS

2013-01-25
2013-09-16
  • robototechnik
    robototechnik
    2013-01-25

    Hi !
    I have a problem with controling two servos with ATmega32 using FreeRTOS. The servos are connected to the Timer1 PWM outputs…at the beginning there was ticking process on the Timer1, now it should tick on the Timer0, but it doesnt((( the PWM generates only a frequency of the first variable and the main programm never riches the second variable((
    i cannot find the problem(
    here is the link to the project that i compiled in AVRStudio=)
    can anybode help me, please???
    thanks for everybody who will answer=)

     
  • Richard
    Richard
    2013-01-25

    The link to the project files has been deleted from your post for two reasons:

    1) It asked me for an email address to download the files.
    2) Clicking on the link caused me to be redirected to inappropriate adult material.

    From your email it sounds like you updated the port layer to use timer 0 in place of timer 1 because your servo motor needs timer 1, but timer 0 is not generating the tick.

    Is timer 0 generating an interrupt at all?  Try creating a basic program that does nothing but configure timer 0 to generate a periodic interrupt.  When that is working add in the the FreeRTOS code and FreeRTOS interrupt handlers are installed for timer 0 instead of timer 1.

    Regards.

     
  • robototechnik
    robototechnik
    2013-01-25

    oh sorry, i didnt want, i found simply the file hoster…i thought it will be okay=)
    actually i dont know, im only a beginner…ill tell again what was already done:
    here ist the code which im trying to run

    #include "FreeRTOS.h"
    #include "task.h"
    #include <avr/io.h>
    ///////////////////////////////////////////////////////////////////////////////////////
    void vServo( void *pvParameters )
    {
    for (;;)
    {
            OCR1A=200;                                           //800ìñ/4ìñ
            OCR1B=200;
            vTaskDelay(500 / portTICK_RATE_MS); 
            OCR1A=375;                                           //1500ìñ/4ìñ
            OCR1B=375;
            vTaskDelay(500 / portTICK_RATE_MS);
            OCR1A=550;                                           //2200ìñ/4ìñ
            OCR1B=550;
            vTaskDelay(500 / portTICK_RATE_MS);
    
    }
    }
    /////////////////////////////////////////////////////////////////////////////////////////////
    int main( void )
    {
    
    TCCR1A|=(1<<COM1A1)|(1<<COM1B1)|(1<<WGM11);      
    TCCR1B|=(1<<WGM13)|(1<<WGM12)|(1<<CS11)|(1<<CS10);
    
    ICR1=4999;
    
    DDRD = 0b00110000;
    
     xTaskCreate( vServo, 
                 (signed char * ) "Servo", 
                 configMINIMAL_STACK_SIZE, 
                 NULL, 
                 1, 
                 NULL );
    
     vTaskStartScheduler();
     return 0;
    }
    

    when the FreeRTOS using Timer1 the PWM for servo will not working, because of the 1000 Hz TICK RATE, the period will be 1 ms.
    one man helped me, he changed the file called PORT.c(the one for ATmega 323) and now it look so

    #include <stdlib.h>
    #include <avr/interrupt.h>
    #include "FreeRTOS.h"
    #include "task.h"
    #define portFLAGS_INT_ENABLED                   ( ( portSTACK_TYPE ) 0x80 )
    #define portCLEAR_COUNTER_ON_MATCH              ( ( unsigned char ) 0x08 )
    #define portPRESCALE_64                         ( ( unsigned char ) 0x03 )
    #define portCLOCK_PRESCALER                     ( ( unsigned long ) 64 )
    #define portCOMPARE_MATCH_A_INTERRUPT_ENABLE    ( ( unsigned char ) 0x10 )
    typedef void tskTCB;
    extern volatile tskTCB * volatile pxCurrentTCB;
    #define portSAVE_CONTEXT()                                  \
        asm volatile (  "push   r0                      \n\t"   \
                        "in     r0, __SREG__            \n\t"   \
                        "cli                            \n\t"   \
                        "push   r0                      \n\t"   \
                        "push   r1                      \n\t"   \
                        "clr    r1                      \n\t"   \
                        "push   r2                      \n\t"   \
                        "push   r3                      \n\t"   \
                        "push   r4                      \n\t"   \
                        "push   r5                      \n\t"   \
                        "push   r6                      \n\t"   \
                        "push   r7                      \n\t"   \
                        "push   r8                      \n\t"   \
                        "push   r9                      \n\t"   \
                        "push   r10                     \n\t"   \
                        "push   r11                     \n\t"   \
                        "push   r12                     \n\t"   \
                        "push   r13                     \n\t"   \
                        "push   r14                     \n\t"   \
                        "push   r15                     \n\t"   \
                        "push   r16                     \n\t"   \
                        "push   r17                     \n\t"   \
                        "push   r18                     \n\t"   \
                        "push   r19                     \n\t"   \
                        "push   r20                     \n\t"   \
                        "push   r21                     \n\t"   \
                        "push   r22                     \n\t"   \
                        "push   r23                     \n\t"   \
                        "push   r24                     \n\t"   \
                        "push   r25                     \n\t"   \
                        "push   r26                     \n\t"   \
                        "push   r27                     \n\t"   \
                        "push   r28                     \n\t"   \
                        "push   r29                     \n\t"   \
                        "push   r30                     \n\t"   \
                        "push   r31                     \n\t"   \
                        "lds    r26, pxCurrentTCB       \n\t"   \
                        "lds    r27, pxCurrentTCB + 1   \n\t"   \
                        "in     r0, 0x3d                \n\t"   \
                        "st     x+, r0                  \n\t"   \
                        "in     r0, 0x3e                \n\t"   \
                        "st     x+, r0                  \n\t"   \
                    );
    #define portRESTORE_CONTEXT()                               \
        asm volatile (  "lds    r26, pxCurrentTCB       \n\t"   \
                        "lds    r27, pxCurrentTCB + 1   \n\t"   \
                        "ld     r28, x+                 \n\t"   \
                        "out    __SP_L__, r28           \n\t"   \
                        "ld     r29, x+                 \n\t"   \
                        "out    __SP_H__, r29           \n\t"   \
                        "pop    r31                     \n\t"   \
                        "pop    r30                     \n\t"   \
                        "pop    r29                     \n\t"   \
                        "pop    r28                     \n\t"   \
                        "pop    r27                     \n\t"   \
                        "pop    r26                     \n\t"   \
                        "pop    r25                     \n\t"   \
                        "pop    r24                     \n\t"   \
                        "pop    r23                     \n\t"   \
                        "pop    r22                     \n\t"   \
                        "pop    r21                     \n\t"   \
                        "pop    r20                     \n\t"   \
                        "pop    r19                     \n\t"   \
                        "pop    r18                     \n\t"   \
                        "pop    r17                     \n\t"   \
                        "pop    r16                     \n\t"   \
                        "pop    r15                     \n\t"   \
                        "pop    r14                     \n\t"   \
                        "pop    r13                     \n\t"   \
                        "pop    r12                     \n\t"   \
                        "pop    r11                     \n\t"   \
                        "pop    r10                     \n\t"   \
                        "pop    r9                      \n\t"   \
                        "pop    r8                      \n\t"   \
                        "pop    r7                      \n\t"   \
                        "pop    r6                      \n\t"   \
                        "pop    r5                      \n\t"   \
                        "pop    r4                      \n\t"   \
                        "pop    r3                      \n\t"   \
                        "pop    r2                      \n\t"   \
                        "pop    r1                      \n\t"   \
                        "pop    r0                      \n\t"   \
                        "out    __SREG__, r0            \n\t"   \
                        "pop    r0                      \n\t"   \
                    );
    static void prvSetupTimerInterrupt( void );
    portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
    {
    unsigned short usAddress;
        *pxTopOfStack = 0x11;
        pxTopOfStack--;
        *pxTopOfStack = 0x22;
        pxTopOfStack--;
        *pxTopOfStack = 0x33;
        pxTopOfStack--;
        usAddress = ( unsigned short ) pxCode;
        *pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned short ) 0x00ff );
        pxTopOfStack--;
        usAddress >>= 8;
        *pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned short ) 0x00ff );
        pxTopOfStack--;
        *pxTopOfStack = ( portSTACK_TYPE ) 0x00;    
        pxTopOfStack--;
        *pxTopOfStack = portFLAGS_INT_ENABLED;
        pxTopOfStack--;
        *pxTopOfStack = ( portSTACK_TYPE ) 0x00;    /* R1 */
        pxTopOfStack--;
        *pxTopOfStack = ( portSTACK_TYPE ) 0x02;    /* R2 */
        pxTopOfStack--;
        *pxTopOfStack = ( portSTACK_TYPE ) 0x03;    /* R3 */
        pxTopOfStack--;
        *pxTopOfStack = ( portSTACK_TYPE ) 0x04;    /* R4 */
        pxTopOfStack--;
        *pxTopOfStack = ( portSTACK_TYPE ) 0x05;    /* R5 */
        pxTopOfStack--;
        *pxTopOfStack = ( portSTACK_TYPE ) 0x06;    /* R6 */
        pxTopOfStack--;
        *pxTopOfStack = ( portSTACK_TYPE ) 0x07;    /* R7 */
        pxTopOfStack--;
        *pxTopOfStack = ( portSTACK_TYPE ) 0x08;    /* R8 */
        pxTopOfStack--;
        *pxTopOfStack = ( portSTACK_TYPE ) 0x09;    /* R9 */
        pxTopOfStack--;
        *pxTopOfStack = ( portSTACK_TYPE ) 0x10;    /* R10 */
        pxTopOfStack--;
        *pxTopOfStack = ( portSTACK_TYPE ) 0x11;    /* R11 */
        pxTopOfStack--;
        *pxTopOfStack = ( portSTACK_TYPE ) 0x12;    /* R12 */
        pxTopOfStack--;
        *pxTopOfStack = ( portSTACK_TYPE ) 0x13;    /* R13 */
        pxTopOfStack--;
        *pxTopOfStack = ( portSTACK_TYPE ) 0x14;    /* R14 */
        pxTopOfStack--;
        *pxTopOfStack = ( portSTACK_TYPE ) 0x15;    /* R15 */
        pxTopOfStack--;
        *pxTopOfStack = ( portSTACK_TYPE ) 0x16;    /* R16 */
        pxTopOfStack--;
        *pxTopOfStack = ( portSTACK_TYPE ) 0x17;    /* R17 */
        pxTopOfStack--;
        *pxTopOfStack = ( portSTACK_TYPE ) 0x18;    /* R18 */
        pxTopOfStack--;
        *pxTopOfStack = ( portSTACK_TYPE ) 0x19;    /* R19 */
        pxTopOfStack--;
        *pxTopOfStack = ( portSTACK_TYPE ) 0x20;    /* R20 */
        pxTopOfStack--;
        *pxTopOfStack = ( portSTACK_TYPE ) 0x21;    /* R21 */
        pxTopOfStack--;
        *pxTopOfStack = ( portSTACK_TYPE ) 0x22;    /* R22 */
        pxTopOfStack--;
        *pxTopOfStack = ( portSTACK_TYPE ) 0x23;    /* R23 */
        pxTopOfStack--;
        usAddress = ( unsigned short ) pvParameters;
        *pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned short ) 0x00ff );
        pxTopOfStack--;
        usAddress >>= 8;
        *pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned short ) 0x00ff );
        pxTopOfStack--;
        *pxTopOfStack = ( portSTACK_TYPE ) 0x26;    /* R26 X */
        pxTopOfStack--;
        *pxTopOfStack = ( portSTACK_TYPE ) 0x27;    /* R27 */
        pxTopOfStack--;
        *pxTopOfStack = ( portSTACK_TYPE ) 0x28;    /* R28 Y */
        pxTopOfStack--;
        *pxTopOfStack = ( portSTACK_TYPE ) 0x29;    /* R29 */
        pxTopOfStack--;
        *pxTopOfStack = ( portSTACK_TYPE ) 0x30;    /* R30 Z */
        pxTopOfStack--;
        *pxTopOfStack = ( portSTACK_TYPE ) 0x031;   /* R31 */
        pxTopOfStack--;
    
        return pxTopOfStack;
    }
    portBASE_TYPE xPortStartScheduler( void )
    {
    
        prvSetupTimerInterrupt();
        portRESTORE_CONTEXT();
    
        asm volatile ( "ret" );
        return pdTRUE;
    }
    void vPortEndScheduler( void )
    {
    
    }
    void vPortYield( void ) __attribute__ ( ( naked ) );
    void vPortYield( void )
    {
        portSAVE_CONTEXT();
        vTaskSwitchContext();
        portRESTORE_CONTEXT();
        asm volatile ( "ret" );
    }
    /*-----------------------------------------------------------*/
    void vPortYieldFromTick( void ) __attribute__ ( ( naked ) );
    void vPortYieldFromTick( void )
    {
        portSAVE_CONTEXT();
        vTaskIncrementTick();
        vTaskSwitchContext();
        portRESTORE_CONTEXT();
        asm volatile ( "ret" );
    }
    /*-----------------------------------------------------------*/
    static void prvSetupTimerInterrupt( void )
    {
    unsigned long ocr_value=configCPU_CLOCK_HZ / configTICK_RATE_HZ; 
    unsigned long temp;
    unsigned char ps_value=1;
    
        TCCR0=0; TCNT0 = 0; 
        if(ocr_value > 255) {ocr_value /= 8; ps_value = 2;}
        if(ocr_value > 255) {ocr_value /= 8; ps_value = 3;}
        if(ocr_value > 255) {ocr_value /= 4; ps_value = 4;}
        if(ocr_value > 255) {ocr_value /= 4; ps_value = 5;}
        if(ocr_value > 255) return;
    
        OCR0 = (unsigned char) ocr_value;
        TIFR = 1<<TOV0;
        TIMSK |= 1<<TOIE0;
        TCCR0 = ps_value | (1<<WGM01); 
    }
    #if configUSE_PREEMPTION == 1
        void SIG_OVERFLOW0( void ) __attribute__ ( ( signal, naked ) );
        void SIG_OVERFLOW0( void )
        {
            vPortYieldFromTick();
            asm volatile ( "reti" );
        }
    #else
        void SIG_OVERFLOW0( void ) __attribute__ ( ( signal ) );
        void SIG_OVERFLOW0( void )
        {
            vTaskIncrementTick();
        }
    #endif
    

    now it looks like the FreeRTOS doesnt TICKs…i mean the PWM frequency is noe okay, with the period of 20ms, but the programm doesnt work, it stops at
    OCR1A=200; //800ìñ/4ìñ
    OCR1B=200;
    vTaskDelay(500 / portTICK_RATE_MS);
    and generates PWM in loop(
    and i dont know the reason=(
    help me please=)

     
  • Richard
    Richard
    2013-01-25

    As per my previous post, is the interrupt executing at all?  Are you able to successfully use the timer to generate periodic interrupts in a basic "hello world" type program without FreeRTOS?  I can't help with the specifics of setting up a timer on an AVR, so you need to ensure the peripheral timer is executing as you want it to before you try using it with FreeRTOS.

    Regards.

     
  • robototechnik
    robototechnik
    2013-01-25

    i have just tried to make another one code, and it also doesnt work….i mean it starts…a little part of the code is done and then something like sleep=)
    the same situation as in the code with servos=(
    can you please explain once again and siplified what should i do?=) thank you=)

     
  • MEdwards
    MEdwards
    2013-01-25

    So the interrupt is not working in a simple program without FreeRTOS? If so then you will have to get it working, but I don't think anybody here can tell you that because it is specific to the hardware. You could loon on www.avrfreaks.net to see if you can find code for that timer.

     
  • robototechnik
    robototechnik
    2013-01-25

    no everything is working fine without FreeRTOS, but when i put this simple code into the FreeRTOS Ive found this problem with period of PWM signal and the Timer1. One man helped me to solve this problem with putting the source tick to the Timer0 to free Timer1 for servos….and it doesnt work=/
    and we dont know the reason….i thought somebody from this forum can help me…???

     
  • robototechnik
    robototechnik
    2013-01-25

    the main C code and the file which we changed for putting ticking source to Timer0 from Timer1 are in the third message.
    the main code shold work without problems but PORT.C…i dont know how it works at all=(
    i can put also here the original PORT.C if needed

     
  • robototechnik
    robototechnik
    2013-01-27

    is anybody here?=)

     
  • Richard
    Richard
    2013-01-27

    What is it you are waiting for?  I don't understand the problem you are describing.

    As far as I can see from this thread:

    - FreeRTOS works ok if you don't change the timer used to generate the tick.
    - You have to change the timer because your application code needs the timer that was originally used to generate the tick.
    - After you have made the modification the tick interrupt is not working.
    - It has been suggested that you get the timer interrupt working by itself, in a stand alone application, so you can be sure that your code to setup the timer and handle the timer interrupt is functioning.

    Have you tried setting up the timer in a stand alone application to see if the timer peripheral is being configured correctly and that the timer interrupt is being handled correctly?  If so, I don't understand your last couple of posts.

    Regards.

     
  • robototechnik
    robototechnik
    2013-01-27

    i hope that somebody will answer and help me…
    but i didnt understand the last post…what should i do?
    i know that the problem is in the PORT.C file but i really dont know how to solve it=(
    could anybody help me please?its a little bit difficult to see into such a difficult code for pupil…this is the reason why i am writing here
    thanks

     
  • robototechnik
    robototechnik
    2013-01-28

    tell me please if i spending my time…=(