Jump to content

    

Управление серводвигателем под FreeRTOS

Всем привет!

Совсем недавно перешел на FreeRTOS до этого немного работал с С под AVR микроконтроллеры. Сейчас стоит задача подключить 3 серводвигателя к ATmega32 из под FreeRTOS. У меня имеется код который работает без ОС, но при внедрении его в ОС ничего не пашет, точнее ШИМ вроде генерируется но не по параметрам. Я подключил выход к осциллографу и на выходе если я все правильно понимаю у меня через каждую миллисекунду появляется высокий уровень....хотя я задавал период как бы в 20 мс. Короче непонятки какие то...пожалуйста, если у кого либо есть какая либо информация,мысли или наработки поделитесь плз!!!))) и к Курницу не посылать...он мне не отвечает... Если что надо выложить, коды или фотки с осцилла то говорите.

Заранее большое спасибо)

Share this post


Link to post
Share on other sites

Такие вещи решаются с помощью протеусовского симулятора в течение часа.

Share this post


Link to post
Share on other sites
Совсем недавно перешел на FreeRTOS до этого немного работал с С под AVR микроконтроллеры. Сейчас стоит задача подключить 3 серводвигателя к ATmega32 из под FreeRTOS.

Скорости хватит?

 

У меня имеется код который работает без ОС, но при внедрении его в ОС ничего не пашет, точнее ШИМ вроде генерируется но не по параметрам.

 

Попробуйте теперь по другому:

Вариант 1. Перенести ШИМ на другой таймер.

Вариант 2. Отключить запуск Оси.

 

у меня через каждую миллисекунду появляется высокий уровень....хотя я задавал период как бы в 20 мс.

Такой период наводит на мысль, что Ось использует тот же таймер что и ваш ШИМ.

Либо настройте системный таймер Оси на другой таймер, или поменяйте период системного таймера Оси (в каком-то config-е)

 

Если что надо выложить, коды или фотки с осцилла то говорите.

Проект выкладывайте, иначе можно долго гадать.

 

Такие вещи решаются с помощью протеусовского симулятора в течение часа.

Или в AVRStudio за 5 минут.

А если кто раньше с FreeRtos работал, то можно и без симуляторов по исходнику за те же минуты.

Share this post


Link to post
Share on other sites

скорости пардон чего?)если что у меня кварц на 16 МГц и в Configе стоит период Тика 1000 Гц

я заранее извиняюсь я не профи, а любитель)

как я могу перенести ШИМ на другой таймер если использую аппаратный ШИМ с помощью Timer1...а аппаратный Timer0 для ШИМ мне так и не удалось запустить...

я тоже сразу подумал что этот таймер используется для тиков ОС....но он мне нужен....получается нужно создавать программный...а каким образом???понятия не имею....если есть у кого возможность скиньте пожалуйста конкретный пример полного кода с созданиями всех тасков который генерирует ШИМ на определенной ноге МК с периодом 20 мс и высоким уровнем промежутком от 600мкс до 2400мкс.....буду оооочень благодарен....мне так проще в коде разобраться будет)

вот код самой программы а потом за ним конфигурационный файл.....вот это то что я пока что пробовал)

 

 

 

 

 

 

 

 

#include "FreeRTOS.h"

#include "task.h"

#include <avr/io.h>

///////////////////////////////////////////////////////////////////////////////////////

void vServo( void *pvParameters )

{

for (;;)

{

OCR1A=180;

OCR1B=180;

vTaskDelay( 5000 / portTICK_RATE_MS);

 

OCR1A=262;

OCR1B=262;

vTaskDelay( 5000 / portTICK_RATE_MS);

 

OCR1A=375;

OCR1B=375;

vTaskDelay( 5000 / portTICK_RATE_MS);

 

OCR1A=487;

OCR1B=487;

vTaskDelay( 5000 / portTICK_RATE_MS);

 

OCR1A=570;

OCR1B=570;

vTaskDelay( 5000 / 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;

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

#ifndef FREERTOS_CONFIG_H

#define FREERTOS_CONFIG_H

 

#include <avr/io.h>

 

/*-----------------------------------------------------------

* Application specific definitions.

*

* These definitions should be adjusted for your particular hardware and

* application requirements.

*

* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE

* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.

*

* See http://www.freertos.org/a00110.html.

*----------------------------------------------------------*/

 

#define configUSE_PREEMPTION 1

#define configUSE_IDLE_HOOK 0

#define configUSE_TICK_HOOK 0

#define configCPU_CLOCK_HZ ( ( unsigned long ) 16000000 )

#define configTICK_RATE_HZ ( ( portTickType ) 1000 )

#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 4 )

#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 500 )

#define configTOTAL_HEAP_SIZE ( (size_t ) ( 1500 ) )

#define configMAX_TASK_NAME_LEN ( 10 )

#define configUSE_TRACE_FACILITY 0

#define configUSE_16_BIT_TICKS 1

#define configIDLE_SHOULD_YIELD 1

#define configQUEUE_REGISTRY_SIZE 1

 

/* Co-routine definitions. */

#define configUSE_CO_ROUTINES 1

#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )

 

/* Set the following definitions to 1 to include the API function, or zero

to exclude the API function. */

 

#define INCLUDE_vTaskPrioritySet 1

#define INCLUDE_uxTaskPriorityGet 1

#define INCLUDE_vTaskDelete 1

#define INCLUDE_vTaskCleanUpResources 1

#define INCLUDE_vTaskSuspend 1

#define INCLUDE_vTaskDelayUntil 1

#define INCLUDE_vTaskDelay 1

 

 

#endif /* FREERTOS_CONFIG_H */

 

 

Share this post


Link to post
Share on other sites
скорости пардон чего?)

 

Скорости света надо полагать...

 

 

если что у меня кварц на 16 МГц и в Configе стоит период Тика 1000 Гц

 

Не так уж много...

 

 

 

как я могу перенести ШИМ на другой таймер если использую аппаратный ШИМ с помощью Timer1...а аппаратный Timer0 для ШИМ мне так и не удалось запустить...

 

Перенесите Шим на T2 или перенесите системный таймер Оси на T0 и задайте другой период (1 миллисекунда не выйдет)

 

я тоже сразу подумал что этот таймер используется для тиков ОС

 

Как бы они 1мс получили на другом таймере...

 

....но он мне нужен....получается нужно создавать программный...а каким образом???

 

перенесите прерывание системного таймера на другой вектор. Ессли возможно. Или вам строго 1 мс нужна от системного таймера? Затраты на Ось при этом будут высьма немалыми.

 

вот код самой программы а потом за ним конфигурационный файл.....вот это то что я пока что пробовал)

 

Проект целиком лучше заархивируйте

Share this post


Link to post
Share on other sites

Артём, я могу вас попросить мне разжевать все что я должен сделать пожалуйста...я не понимаю что именно не так...(

 

Share this post


Link to post
Share on other sites

1. Лезете в port.c для авровского порта, находите там

void SIG_OUTPUT_COMPARE1A( void ) __attribute__ ( ( signal, naked ) );

И переназначаете его на что-нить другое.

 

2. Не забываем про инициализацию

это находится в static void prvSetupTimerInterrupt( void )

 

Share this post


Link to post
Share on other sites

окай я нашел эту строку...но как переназначить?

инициализацию чего и где вообще?)

я извиняюсь еще раз)сильно не бейте)

Share this post


Link to post
Share on other sites
1. Лезете в port.c для авровского порта, находите там

void SIG_OUTPUT_COMPARE1A( void ) __attribute__ ( ( signal, naked ) );

И переназначаете его на что-нить другое.

 

2. Не забываем про инициализацию

это находится в static void prvSetupTimerInterrupt( void )

Тип того.

а 1000 Hz при том как? (проекта под авр под рукой у меня нет).

Share this post


Link to post
Share on other sites
Артем я вас не понимаю(

что тип того?и при чем 1000Гц?

 

Вам какfя частота системного таймера нужна(она будет определять точность с которой выполняются задержки в частности)?

Share this post


Link to post
Share on other sites

я точно не знаю...знаю что мне нужна неплохая точность угла поворота серводвигателя...а так же хорошее быстродействие системы для одновременного опроса сенсоров....вот)

Share this post


Link to post
Share on other sites
окай я нашел эту строку...но как переназначить?

инициализацию чего и где вообще?)

я извиняюсь еще раз)сильно не бейте)

Ежели Вы уже писали под АВРки, то, надо полагать, в потрохах оных Вы уже разбираетесь? Тама три строчки в шесть рядов :) Не морочьте людям голову на ночь :)

Что у Вас свободно? Timer0? Отлично, на него и вешайте прерывание, даже output compare можно не использовать из любви к искусству, типа такого

#include <avr/interrupt.h>
void SIG_OUTPUT_COMPARE0( void ) __attribute__ ( ( signal,naked ) );
    void SIG_OUTPUT_COMPARE0( void )
    {
        vTaskIncrementTick();
                asm volatile("reti");
    }

 

static void prvSetupTimerInterrupt( void ) - тут устанавливаете все что касается срабатывания таймера 0 с 1мс тиком

Я сейчас не пишу под авры, лазать по макабукам - долго. Уж будьте любезны - сами.

Если заметили, там функция целиком посвящена именно настройке таймера, и больше ничего. можно смело написать своё, как угодно криво/прямо, лишь бы у Вас пошли прерывания на OCR0 1мс, и отразить это в configTICK_RATE_HZ

 

ЗЫ там подправил чуток, у Вас же preemption будет?

Edited by _Pasha

Share this post


Link to post
Share on other sites

не то что бы много писал....так попробовал но думал что хоть немного разбираюсь(

забыл уточнить мне 15 лет)так что...пардон иногда недоезжаю)

теперь более менее понятно...то есть если я перекину тики на таймер0 то таймер1 освободится и смогу рулить сервами с моим кодом?верно?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this