Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem TCP & FAT




Loading

Servo controling with ATmega32 and FreeRTOS

Posted by robototechnik on January 25, 2013
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=)

RE: Servo controling with ATmega32 and FreeRTOS

Posted by Richard on January 25, 2013
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.

RE: Servo controling with ATmega32 and FreeRTOS

Posted by robototechnik on January 25, 2013
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
///////////////////////////////////////////////////////////////////////////////////////
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<TCCR1B|=(1<
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
#include

#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 ("pushr0\n\t"\
"inr0, __SREG__\n\t"\
"cli\n\t"\
"pushr0\n\t"\
"pushr1\n\t"\
"clrr1\n\t"\
"pushr2\n\t"\
"pushr3\n\t"\
"pushr4\n\t"\
"pushr5\n\t"\
"pushr6\n\t"\
"pushr7\n\t"\
"pushr8\n\t"\
"pushr9\n\t"\
"pushr10\n\t"\
"pushr11\n\t"\
"pushr12\n\t"\
"pushr13\n\t"\
"pushr14\n\t"\
"pushr15\n\t"\
"pushr16\n\t"\
"pushr17\n\t"\
"pushr18\n\t"\
"pushr19\n\t"\
"pushr20\n\t"\
"pushr21\n\t"\
"pushr22\n\t"\
"pushr23\n\t"\
"pushr24\n\t"\
"pushr25\n\t"\
"pushr26\n\t"\
"pushr27\n\t"\
"pushr28\n\t"\
"pushr29\n\t"\
"pushr30\n\t"\
"pushr31\n\t"\
"ldsr26, pxCurrentTCB\n\t"\
"ldsr27, pxCurrentTCB + 1\n\t"\
"inr0, 0x3d\n\t"\
"stx+, r0\n\t"\
"inr0, 0x3e\n\t"\
"stx+, r0\n\t"\
);



#define portRESTORE_CONTEXT()\
asm volatile ("ldsr26, pxCurrentTCB\n\t"\
"ldsr27, pxCurrentTCB + 1\n\t"\
"ldr28, x+\n\t"\
"out__SP_L__, r28\n\t"\
"ldr29, x+\n\t"\
"out__SP_H__, r29\n\t"\
"popr31\n\t"\
"popr30\n\t"\
"popr29\n\t"\
"popr28\n\t"\
"popr27\n\t"\
"popr26\n\t"\
"popr25\n\t"\
"popr24\n\t"\
"popr23\n\t"\
"popr22\n\t"\
"popr21\n\t"\
"popr20\n\t"\
"popr19\n\t"\
"popr18\n\t"\
"popr17\n\t"\
"popr16\n\t"\
"popr15\n\t"\
"popr14\n\t"\
"popr13\n\t"\
"popr12\n\t"\
"popr11\n\t"\
"popr10\n\t"\
"popr9\n\t"\
"popr8\n\t"\
"popr7\n\t"\
"popr6\n\t"\
"popr5\n\t"\
"popr4\n\t"\
"popr3\n\t"\
"popr2\n\t"\
"popr1\n\t"\
"popr0\n\t"\
"out__SREG__, r0\n\t"\
"popr0\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<TIMSK |= 1<TCCR0 = ps_value | (1<}

#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=)

RE: Servo controling with ATmega32 and FreeRTOS

Posted by Richard on January 25, 2013
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.

RE: Servo controling with ATmega32 and FreeRTOS

Posted by robototechnik on January 25, 2013
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=)

RE: Servo controling with ATmega32 and FreeRTOS

Posted by MEdwards on January 25, 2013
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.

RE: Servo controling with ATmega32 and FreeRTOS

Posted by robototechnik on January 25, 2013
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...???

RE: Servo controling with ATmega32 and FreeRTOS

Posted by robototechnik on January 25, 2013
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

RE: Servo controling with ATmega32 and FreeRTOS

Posted by robototechnik on January 27, 2013
is anybody here?=)

RE: Servo controling with ATmega32 and FreeRTOS

Posted by Richard on January 27, 2013
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.

RE: Servo controling with ATmega32 and FreeRTOS

Posted by robototechnik on January 27, 2013
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

RE: Servo controling with ATmega32 and FreeRTOS

Posted by robototechnik on January 28, 2013
tell me please if i spending my time...=(


[ Back to the top ]    [ About FreeRTOS ]    [ Sitemap ]    [ ]




Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.

Latest News

FreeRTOS kernel V10 is available for immediate download. Now MIT licensed.


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

OpenRTOS and SafeRTOS