Страница 1 из 1

Как правильно организовать программу для МК

Добавлено: Чт мар 06, 2014 09:41:55
sergey_mak
Доброе утро. Такой вопрос. В программировании МК в принципе я новичек, хочу послушать советов грамотных людей. У меня есть цель создать прибор для управления коллекторным двигателем. Этот двигатель стоит в старой научной установке. Задача этого прибора измерять и стабилизировать обороты по заданной программе. На валу двигателя есть энкодер оптический в диске энкодера 60 прорезей. По элементной базе думаю использовать ATMega328, FT232RL для связи с компом, пять кнопок, 16x2 LCD дисплей, MOSFET для управления двигателем. Сигнал с энкодера подавать на внешнее прерывание МК. Что хочется получить...Небольшее меню, в котором можно задать несколько пресетов частоты вращения движка, ввести коэффициенты PID регулятора, включать и отключать PID регулятор. Собственно PID регулятор, вывод на индикатор во время работы уставку и реально измеренное значение оборотов, вывод этих же значений в COM порт, получение из СОМ порта пресетов, коэффициентов и сигнала вкл.\выкл.

Собственно вопрос, как лучше организовать программу для такого функционала, использовать флаговый автомат? Может быть какую либо РТОС, либо просто прерывания и бесконечный цикл..Как бы сделали вы? Спасибо всем за ответы.

Re: Как правильно организовать программу для МК

Добавлено: Чт мар 06, 2014 11:01:52
Dr. Alex
На мой взгляд для такой задачи будет достаточно прерывания и цикла)

Re: Как правильно организовать программу для МК

Добавлено: Чт мар 06, 2014 11:15:08
oleg110592
тут посмотреть можно: http://elm-chan.org/works/smc/report_e.html

Re: Как правильно организовать программу для МК

Добавлено: Чт мар 06, 2014 11:16:09
sergey_mak
Понятно что обработку кнопок, индикацию, вывод данных в СОМ порт наверное лучше организовать в основном цикле, а вот как разрулить измерение частоты вращения, ПИД регулятор и управление.....Пока не понимаю.

Re: Как правильно организовать программу для МК

Добавлено: Чт мар 06, 2014 11:17:36
sergey_mak
oleg110592 писал(а):тут посмотреть можно: http://elm-chan.org/works/smc/report_e.html
Спасибо за ссылку, кажется я ее уже видел, изучу.

Re: Как правильно организовать программу для МК

Добавлено: Чт мар 06, 2014 11:20:32
Dr. Alex
Ну про PID регулятор вот ТУТ и ТУТ неплохо написанно

Re: Как правильно организовать программу для МК

Добавлено: Чт мар 06, 2014 11:27:02
sergey_mak
Про ПИД понятно, не понятно как ресурсы МК разделить для ПИД, измерения и управления.

Re: Как правильно организовать программу для МК

Добавлено: Чт мар 06, 2014 11:28:21
Леонид Иванович
Делал очень похожий проект. Тоже научный прибор, двигатель с оптическим прерывателем на валу, стабилизировал частоту с помощью ПИД, управлял от компьютера. Ниже привожу модуль main программы микроконтроллера, там структура программы видна.
Спойлер

Код: Выделить всё

//----------------------------------------------------------------------------

//Проект:         R-7A
//Компилятор:     IAR EWAVR 4.21a
//Мироконтроллер: ATMega8
//E-mail:         wubblick@yahoo.com

//------------------------------ Fuses: -------------------------------------

//SPI Enable
//Full Amplitude
//ExtXTAL, High frequency
//Startup: 64 ms + 16K CK
//BOD enabled, 4.0V

//----------------------------------------------------------------------------

#include "Main.h"
#include "Control.h"
#include "Port.h"
#include "Commands.h"

//----------------- Используемые модулем аппаратные ресурсы: -----------------

//Таймер 2 используется в качестве системного таймера.

//------------------------------ Переменные: ---------------------------------

volatile static bool fTick;        //флаг обновления watchdog-таймера
static bool tick;                  //признак начала нового итервала таймера

//-------------------------- Прототипы функций: ------------------------------

void main(void);                   //основная программа
void Main_Wdt_Init(void);          //инициализация watchdog-таймера
void Main_Rst_Wdt(bool t);         //рестарт watchdog-таймера
void Main_Ports_Init(void);        //инициализация портов
void Main_Timer_Init(void);        //инициализация системного таймера
#pragma vector = TIMER2_COMP_vect
__interrupt void Sys_Timer(void);  //прерывание системного таймера
__monitor bool Main_GetTick(void); //проверка системного таймера

//----------------------------------------------------------------------------
//------------------------- Основная программа: ------------------------------
//----------------------------------------------------------------------------

void main(void)
{
  Main_Wdt_Init();          //инициализация watchdog-таймера
  Main_Ports_Init();        //инициализация портов
  Main_Timer_Init();        //инициализация системного таймера
  Control_Init();           //инициализация модуля управления
  Port_Init();              //инициализация порта
  __enable_interrupt();     //разрешение прерываний

  while(1)                  //основной цикл
  {
    tick = Main_GetTick();  //проверка системного таймера
    Commands_Exe();         //выполнение команд компьютера
    Control_Exe(tick);      //управление двигателем
    Main_Rst_Wdt(tick);     //рестарт watchdog-таймера
  }
}

//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------

//------------------- Инициализация watchdog-таймера: ------------------------

void Main_Wdt_Init(void)
{
  __watchdog_reset();
  WDTCR = (1<<WDCE) | (1<<WDE);
  WDTCR = (1<<WDE) | (1<<WDP2) | (1<<WDP0); //watchdog time-out 520 ms
}

//------------------------ Рестарт watchdog-таймера: -------------------------

void Main_Rst_Wdt(bool t)
{
  if(t)                 //если есть флаг обновления, то
    __watchdog_reset(); //рестарт watchdog-таймера
}

//------------------------ Инициализация портов: -----------------------------

void Main_Ports_Init(void)
{
  DDRB  = I_DDRB;
  PORTB = I_PORTB;
  DDRC  = I_DDRC;
  PORTC = I_PORTC;
  DDRD  = I_DDRD;
  PORTD = I_PORTD;
}

//------------------ Инициализация системного таймера ------------------------

#define T2VAL (int)((F_CLK * T_SYS / 64.0) + 0.5) //предделитель таймера CK/64

void Main_Timer_Init(void)
{
  TCCR2 = (1<<WGM21) | (1<<CS22); //режим таймера 2: CTC, CK/64
  OCR2 = T2VAL - 1;     //загрузка регистра сравнения
  TIFR = (1 << OCIE2);  //сброс отложенных прерываний
  TIMSK = (1 << OCIE2); //разрешение прерывания по совпадению
  fTick = 1;            //принудительная установка флага обновления
}

//-------------------- Проверка системного таймера: --------------------------

bool Main_GetTick(void)
{
  if(!fTick) return(0);
  fTick = 0;
  return(1);
}

//------------------- Прерывание системного таймера: -------------------------

#pragma vector = TIMER2_COMP_vect
__interrupt void Sys_Timer(void)
{
  fTick = 1;   //установка флага начала нового интервала
  Sound_Gen(); //генерация звука
}

//----------------------------------------------------------------------------
Для связи с компьютером применял протокол Wake, управляющий софт выглядит так:

Изображение

Re: Как правильно организовать программу для МК

Добавлено: Чт мар 06, 2014 11:39:25
sergey_mak
Спасибо большое!

Re: Как правильно организовать программу для МК

Добавлено: Чт мар 06, 2014 11:55:05
Леонид Иванович
Если есть интерес, пишите на почту wubblick@yahoo.com. Могу предоставить любую информацию по этому проекту.

Re: Как правильно организовать программу для МК

Добавлено: Чт мар 06, 2014 12:16:24
sergey_mak
Конечно напишу, тем более давно хотел пообщаться с Вами :)) Еще раз спасибо!