Специальные цены   новые товары
+ Ответить в теме
Страница 43 из 165 ПерваяПервая ... 33 41 42 43 44 45 53 ... ПоследняяПоследняя
Показано с 1,681 по 1,720 из 6569

Создание собственной системы стабилизации

Тема раздела Квадрокоптеры. Общие вопросы в категории Квадрокоптеры и мультироторы; Сообщение от Razek Полет по точкам имеет смысл с железобетонным удержанием высоты, такая фича только у комрада Маховика есть, а ...

  1. #1681

    Регистрация
    13.03.2011
    Адрес
    Montreal, Canada
    Возраст
    38
    Сообщений
    2,291
    Записей в дневнике
    19
    Цитата Сообщение от Razek Посмотреть сообщение
    Полет по точкам имеет смысл с железобетонным удержанием высоты, такая фича только у комрада Маховика есть, а в оригинальном вие вроде она не так хорошо работает
    в 2.2 сейчас одна из моих первый версий (баро+аксель), но для авто режимов вполне справляется со своей задачей... а вот толковой регулировки высоты в альтхолде в мануале, там (в 2.2) нет...
    Цитата Сообщение от DVE Посмотреть сообщение
    А разве Wii уже поддерживает полет по точкам?
    уже есть... точка задается через андроид Ezio (EZ-GUI) прогу, посредством пальцо тыка, см. видео ниже...
    Цитата Сообщение от SergDoc Посмотреть сообщение
    Вот только думаю, для хобби, полёт по точкам -архинужная вещь, вышел в чисто поле - отпустил коптер погулять и сиди медитируй, позагоать можно, а он выгулялся и назад прилелел - романтика
    тогда уж лучше функцию follow me:
    - first implementation of MSP_SET_WP
    with the help of Ezio app (EZ-GUI), we can now control the multi with a smartphone: set a new position on a map / follow me / follow heading
    see Multiwii EZ-GUI specific topic: http://www.multiwii.com/forum/viewtopic.php?f=8&t=2034
    some video about this functionality:



  2.  
  3. #1682

    Регистрация
    01.11.2010
    Адрес
    Belarus Slonim
    Возраст
    36
    Сообщений
    4,462
    Записей в дневнике
    8
    Война с ШИМ часть вторая:
    так как у меня всё через ж... , ну в общем с ног на голову поставлено
    Код:
    static void pwmGPIOConfig(GPIO_TypeDef *gpio, uint32_t pin, uint8_t input)
    {
        GPIO_InitTypeDef GPIO_InitStructure;
    
        GPIO_StructInit(&GPIO_InitStructure);
        GPIO_InitStructure.GPIO_Pin = pin;
        if (input)
            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
        else{
            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
            GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
        }
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
        GPIO_Init(gpio, &GPIO_InitStructure);
    }
    всем скопом каналы шимов настраиваются, тактирование разрешено отдельно.
    похоже на правду?

  4. #1683

    Регистрация
    13.03.2011
    Адрес
    Montreal, Canada
    Возраст
    38
    Сообщений
    2,291
    Записей в дневнике
    19
    Цитата Сообщение от SergDoc Посмотреть сообщение
    Кому интересно я уже давал ссылку AfroFlight32 - FunFly Controller "Naze 32"
    уже облетал?
    калман одномерный там? чет не верю я в это чудо чудное, что прям так сразу лучше полетит, чем более простые ИМУ-шки...
    с калманом, уже не по наслышке, подбор коэф-в еще тот секаС...

  5. #1684

    Регистрация
    01.11.2010
    Адрес
    Belarus Slonim
    Возраст
    36
    Сообщений
    4,462
    Записей в дневнике
    8
    Цитата Сообщение от mahowik Посмотреть сообщение
    уже облетал?
    калман одномерный там? чет не верю я в это чудо чудное, что прям так сразу лучше полетит, чем более простые ИМУ-шки...
    с калманом, уже не по наслышке, подбор коэф-в еще тот секаС...
    мелкоплата на нём у меня, правда у неё секас с акселем, но летает.... кальман да одномерный...

    есть там один секрет комплиментарный фильтр никто не отменял цикл жрёт в два раза больше (4000), но на много лучше себя ведёт чем Таймкопа (~2000)...

  6.  
  7. #1685

    Регистрация
    13.03.2011
    Адрес
    Montreal, Canada
    Возраст
    38
    Сообщений
    2,291
    Записей в дневнике
    19
    Цитата Сообщение от SergDoc Посмотреть сообщение
    кальман да одномерный...
    а что характеризует n-мерность калмана? кол-во сенсоров на входе? тогда что он фильтрует 1D?

    Пытаюсь вот вникнуть понемногу, но пока туговато заходит:
    http://habrahabr.ru/post/166693/
    http://habrahabr.ru/post/140274/

  8. #1686

    Регистрация
    01.11.2010
    Адрес
    Belarus Slonim
    Возраст
    36
    Сообщений
    4,462
    Записей в дневнике
    8
    ось - одноосевой, каждая ось отдельно

  9. #1687

    Регистрация
    13.03.2011
    Адрес
    Montreal, Canada
    Возраст
    38
    Сообщений
    2,291
    Записей в дневнике
    19
    тогда уж лучшА уже привычные нам вращалки

  10.  
  11. #1688

    Регистрация
    01.11.2010
    Адрес
    Belarus Slonim
    Возраст
    36
    Сообщений
    4,462
    Записей в дневнике
    8
    Допилил ШИМ вроде, но за мной как всегда проверять надо:
    Код:
    #include "board.h"
    
    #define PULSE_1MS       (1000) // 1ms pulse width
    
    typedef void pwmCallbackPtr(uint8_t port, uint16_t capture);
    
    static pwmHardware_t timerHardware[] = {
        { TIM2, GPIOA, GPIO_Pin_15,TIM_Channel_1, TIM2_IRQn, 0, },          	// PWM1
        { TIM2, GPIOB, GPIO_Pin_3, TIM_Channel_2, TIM2_IRQn, 0, },          	// PWM2
        { TIM3, GPIOB, GPIO_Pin_4, TIM_Channel_1, TIM3_IRQn, 0, },          	// PWM3
        { TIM3, GPIOB, GPIO_Pin_5, TIM_Channel_2, TIM3_IRQn, 0, },          	// PWM4
        { TIM4, GPIOB, GPIO_Pin_6, TIM_Channel_1, TIM4_IRQn, 0, },          	// PWM5
        { TIM4, GPIOB, GPIO_Pin_7, TIM_Channel_2, TIM4_IRQn, 0, },          	// PWM6
        { TIM4, GPIOB, GPIO_Pin_8, TIM_Channel_3, TIM4_IRQn, 0, },  			// PWM7
        { TIM4, GPIOB, GPIO_Pin_9, TIM_Channel_4, TIM4_IRQn, 0, },				// PWM8
        { TIM1, GPIOE, GPIO_Pin_14,TIM_Channel_4, TIM1_CC_IRQn, 1, },           // PWM9
        { TIM1, GPIOE, GPIO_Pin_13,TIM_Channel_3, TIM1_CC_IRQn, 1, },       	// PWM10
        { TIM1, GPIOE, GPIO_Pin_11,TIM_Channel_2, TIM1_CC_IRQn, 1, },      		// PWM11
        { TIM1, GPIOE, GPIO_Pin_9, TIM_Channel_1, TIM1_CC_IRQn, 1, },           // PWM12
        { TIM5, GPIOA, GPIO_Pin_3, TIM_Channel_4, TIM5_IRQn, 0, },          	// PWM13
        { TIM5, GPIOA, GPIO_Pin_2, TIM_Channel_3, TIM5_IRQn, 0, },          	// PWM14
        { TIM5, GPIOA, GPIO_Pin_1, TIM_Channel_2, TIM5_IRQn, 0, },          	// PWM15
        { TIM5, GPIOA, GPIO_Pin_0, TIM_Channel_1, TIM5_IRQn, 0, },       		// PWM16
        { TIM8, GPIOC, GPIO_Pin_6, TIM_Channel_1, TIM8_CC_IRQn, 1, },           // PWM17
        { TIM8, GPIOC, GPIO_Pin_7, TIM_Channel_2, TIM8_CC_IRQn, 1, },           // PWM18
        { TIM8, GPIOC, GPIO_Pin_8, TIM_Channel_3, TIM8_CC_IRQn, 1, },           // PWM19
        { TIM8, GPIOC, GPIO_Pin_9, TIM_Channel_4, TIM8_CC_IRQn, 1, },           // PWM20
    };
    
    typedef struct {
        pwmCallbackPtr *callback;
        volatile uint16_t *ccr;
        uint16_t period;
    
        // for input only
        uint8_t channel;
        uint8_t state;
        uint16_t rise;
        uint16_t fall;
        uint16_t capture;
    } pwmPortData_t;
    
    enum {
        TYPE_IP = 0x10,
        TYPE_IW = 0x20,
        TYPE_M = 0x40,
        TYPE_S = 0x80
    };
    
    static pwmPortData_t pwmPorts[MAX_PORTS];
    static uint16_t captures[MAX_INPUTS];
    static pwmPortData_t *motors[MAX_MOTORS];
    static pwmPortData_t *servos[MAX_SERVOS];
    static uint8_t numMotors = 0;
    static uint8_t numServos = 0;
    static uint8_t  numInputs = 0;
    // external vars (ugh)
    extern int16_t failsafeCnt;
    
    static const uint8_t multiPPM[] = {
        PWM6  | TYPE_IP,     // PPM input
        PWM9  | TYPE_M,
        PWM10 | TYPE_M,
        PWM11 | TYPE_M,
        PWM12 | TYPE_M,
        PWM13 | TYPE_M,
        PWM14 | TYPE_M,
        PWM15 | TYPE_M,
        PWM16 | TYPE_M,
        PWM17 | TYPE_S,
        PWM18 | TYPE_S,
        PWM19 | TYPE_S,
        PWM20 | TYPE_S,
        0xFF
    };
    
    static const uint8_t multiPWM[] = {
        PWM1 | TYPE_IW,     // input #1
        PWM2 | TYPE_IW,
        PWM3 | TYPE_IW,
        PWM4 | TYPE_IW,
        PWM5 | TYPE_IW,
        PWM6 | TYPE_IW,
        PWM7 | TYPE_IW,
        PWM8 | TYPE_IW,     // input #8
        PWM9 | TYPE_M,
        PWM10 | TYPE_M,
        PWM11 | TYPE_M,
        PWM12 | TYPE_M,
        PWM13 | TYPE_M,
        PWM14 | TYPE_M,
        PWM15 | TYPE_M,
        PWM16 | TYPE_M,
        PWM17 | TYPE_S,
        PWM18 | TYPE_S,
        PWM19 | TYPE_S,
        PWM20 | TYPE_S,
        0xFF
    };
    
    static const uint8_t airPPM[] = {
        PWM6 | TYPE_IP,     // PPM input
        PWM9 | TYPE_M,      // motor #1
        PWM10 | TYPE_M,     // motor #2
        PWM11 | TYPE_M,      
        PWM12 | TYPE_M,
        PWM13 | TYPE_S,     // servo #1
        PWM14 | TYPE_S,
        PWM15 | TYPE_S,
        PWM16 | TYPE_S,
        PWM17 | TYPE_S,
        PWM18 | TYPE_S,
        PWM19 | TYPE_S,
        PWM20 | TYPE_S,
        0xFF
    };
    
    static const uint8_t airPWM[] = {
        PWM1 | TYPE_IW,     // input #1
        PWM2 | TYPE_IW,
        PWM3 | TYPE_IW,
        PWM4 | TYPE_IW,
        PWM5 | TYPE_IW,
        PWM6 | TYPE_IW,
        PWM7 | TYPE_IW,
        PWM8 | TYPE_IW,     // input #8
        PWM9 | TYPE_M,      // motor #1
        PWM10 | TYPE_M,     // motor #2
        PWM11 | TYPE_M,     
        PWM12 | TYPE_M,
        PWM13 | TYPE_S,     // servo #1
        PWM14 | TYPE_S,
        PWM15 | TYPE_S,
        PWM16 | TYPE_S,     
        PWM17 | TYPE_S,     
        PWM18 | TYPE_S,
        PWM19 | TYPE_S,
        PWM20 | TYPE_S,
        0xFF
    };
    
    static const uint8_t *hardwareMaps[] = {
        multiPWM,
        multiPPM,
        airPWM,
        airPPM,
    };
    
    static void pwmTimeBase(TIM_TypeDef *tim, uint32_t period)
    {
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    
        TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
        TIM_TimeBaseStructure.TIM_Period = period - 1;
        TIM_TimeBaseStructure.TIM_Prescaler = (SystemCoreClock / 1000000) - 1; // all timers run at 1MHz
        TIM_TimeBaseStructure.TIM_ClockDivision = 0;
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
        TIM_TimeBaseInit(tim, &TIM_TimeBaseStructure);
    }
    
    static void pwmNVICConfig(uint8_t irq)
    {
        NVIC_InitTypeDef NVIC_InitStructure;
    
        NVIC_InitStructure.NVIC_IRQChannel = irq;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);
    }
    
    static void pwmOCConfig(TIM_TypeDef *tim, uint8_t channel, uint16_t value)
    {
        TIM_OCInitTypeDef  TIM_OCInitStructure;
    
        TIM_OCStructInit(&TIM_OCInitStructure);
        TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
        TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
        TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;
        TIM_OCInitStructure.TIM_Pulse = value;
        TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
        TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
    
        switch (channel) {
            case TIM_Channel_1:
                TIM_OC1Init(tim, &TIM_OCInitStructure);
                TIM_OC1PreloadConfig(tim, TIM_OCPreload_Enable);
                break;
            case TIM_Channel_2:
                TIM_OC2Init(tim, &TIM_OCInitStructure);
                TIM_OC2PreloadConfig(tim, TIM_OCPreload_Enable);
                break;
            case TIM_Channel_3:
                TIM_OC3Init(tim, &TIM_OCInitStructure);
                TIM_OC3PreloadConfig(tim, TIM_OCPreload_Enable);
                break;
            case TIM_Channel_4:
                TIM_OC4Init(tim, &TIM_OCInitStructure);
                TIM_OC4PreloadConfig(tim, TIM_OCPreload_Enable);
                break;
        }
    }
    
    static void pwmICConfig(TIM_TypeDef *tim, uint8_t channel, uint16_t polarity)
    {
        TIM_ICInitTypeDef  TIM_ICInitStructure;
    
        TIM_ICStructInit(&TIM_ICInitStructure);
        TIM_ICInitStructure.TIM_Channel = channel;
        TIM_ICInitStructure.TIM_ICPolarity = polarity;
        TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
        TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
        TIM_ICInitStructure.TIM_ICFilter = 0x0;
    
        TIM_ICInit(tim, &TIM_ICInitStructure);
    }
    
    static void pwmGPIOConfig(GPIO_TypeDef *gpio, uint32_t pin, uint8_t input)
    {
        GPIO_InitTypeDef GPIO_InitStructure;
    
        GPIO_StructInit(&GPIO_InitStructure);
        GPIO_InitStructure.GPIO_Pin = pin;
        if (input)
            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
        else{
            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
            GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
        }
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
        GPIO_Init(gpio, &GPIO_InitStructure);
    }
    
    static pwmPortData_t *pwmOutConfig(uint8_t port, uint16_t period, uint16_t value)
    {
        pwmPortData_t *p = &pwmPorts[port];
        pwmTimeBase(timerHardware[port].tim, period);
        pwmGPIOConfig(timerHardware[port].gpio, timerHardware[port].pin, 0);
        pwmOCConfig(timerHardware[port].tim, timerHardware[port].channel, value);
        // Needed  TIM1 & TIM8
        if (timerHardware[port].outputEnable)
            TIM_CtrlPWMOutputs(timerHardware[port].tim, ENABLE);
        TIM_Cmd(timerHardware[port].tim, ENABLE);
    
        switch (timerHardware[port].channel) {
            case TIM_Channel_1:
                p->ccr = &timerHardware[port].tim->CCR1;
                break;
            case TIM_Channel_2:
                p->ccr = &timerHardware[port].tim->CCR2;
                break;
            case TIM_Channel_3:
                p->ccr = &timerHardware[port].tim->CCR3;
                break;
            case TIM_Channel_4:
                p->ccr = &timerHardware[port].tim->CCR4;
                break;
        }
        return p;
    }
    
    static pwmPortData_t *pwmInConfig(uint8_t port, pwmCallbackPtr callback, uint8_t channel)
    {
        pwmPortData_t *p = &pwmPorts[port];
        pwmTimeBase(timerHardware[port].tim, 0xFFFF);
        pwmGPIOConfig(timerHardware[port].gpio, timerHardware[port].pin, 1);
        pwmICConfig(timerHardware[port].tim, timerHardware[port].channel, TIM_ICPolarity_Rising);
        TIM_Cmd(timerHardware[port].tim, ENABLE);
        pwmNVICConfig(timerHardware[port].irq);
        // set callback before configuring interrupts
        p->callback = callback;
        p->channel = channel;
    
        switch (timerHardware[port].channel) {
            case TIM_Channel_1:
                TIM_ITConfig(timerHardware[port].tim, TIM_IT_CC1, ENABLE);
                break;
            case TIM_Channel_2:
                TIM_ITConfig(timerHardware[port].tim, TIM_IT_CC2, ENABLE);
                break;
            case TIM_Channel_3:
                TIM_ITConfig(timerHardware[port].tim, TIM_IT_CC3, ENABLE);
                break;
            case TIM_Channel_4:
                TIM_ITConfig(timerHardware[port].tim, TIM_IT_CC4, ENABLE);
                break;
        }
        return p;
    }
    
    void TIM1_CC_IRQHandler(void)		//TIM1
    {
        uint8_t port;
    
        if (TIM_GetITStatus(TIM1, TIM_IT_CC1) == SET) {
            port = PWM12;
            TIM_ClearITPendingBit(TIM1, TIM_IT_CC1);
            pwmPorts[port].callback(port, TIM_GetCapture1(TIM1));
        } else if (TIM_GetITStatus(TIM1, TIM_IT_CC2) == SET) {
            port = PWM11;
            TIM_ClearITPendingBit(TIM1, TIM_IT_CC2);
            pwmPorts[port].callback(port, TIM_GetCapture4(TIM1));
        } else if (TIM_GetITStatus(TIM1, TIM_IT_CC3) == SET) {
            port = PWM10;
            TIM_ClearITPendingBit(TIM1, TIM_IT_CC3);
            pwmPorts[port].callback(port, TIM_GetCapture4(TIM1));
        } else if (TIM_GetITStatus(TIM1, TIM_IT_CC4) == SET) {
            port = PWM9;
            TIM_ClearITPendingBit(TIM1, TIM_IT_CC4);
            pwmPorts[port].callback(port, TIM_GetCapture4(TIM1));
        }
    }
    void TIM8_CC_IRQHandler(void)		//TIM8
    {
        uint8_t port;
    
        if (TIM_GetITStatus(TIM8, TIM_IT_CC1) == SET) {
            port = PWM17;
            TIM_ClearITPendingBit(TIM8, TIM_IT_CC1);
            pwmPorts[port].callback(port, TIM_GetCapture1(TIM8));
        } else if (TIM_GetITStatus(TIM8, TIM_IT_CC2) == SET) {
            port = PWM18;
            TIM_ClearITPendingBit(TIM8, TIM_IT_CC2);
            pwmPorts[port].callback(port, TIM_GetCapture4(TIM8));
        } else if (TIM_GetITStatus(TIM8, TIM_IT_CC3) == SET) {
            port = PWM19;
            TIM_ClearITPendingBit(TIM8, TIM_IT_CC3);
            pwmPorts[port].callback(port, TIM_GetCapture4(TIM8));
        } else if (TIM_GetITStatus(TIM8, TIM_IT_CC4) == SET) {
            port = PWM20;
            TIM_ClearITPendingBit(TIM8, TIM_IT_CC4);
            pwmPorts[port].callback(port, TIM_GetCapture4(TIM8));
        }
    }
    
     void TIM2_IRQHandler(void)		//TIM2
    {
        int8_t port;
        
    
        if (TIM_GetITStatus(TIM2, TIM_IT_CC1) == SET) {
            port = PWM1;
            TIM_ClearITPendingBit(TIM2, TIM_IT_CC1);
            pwmPorts[port].callback(port, TIM_GetCapture1(TIM2));
        } else if (TIM_GetITStatus(TIM2, TIM_IT_CC2) == SET) {
            port = PWM2;
            TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);
            pwmPorts[port].callback(port, TIM_GetCapture2(TIM2));
        }
    }
    
    
     void TIM3_IRQHandler(void)		//TIM3
    {
        int8_t port;
    
    
        if (TIM_GetITStatus(TIM3, TIM_IT_CC1) == SET) {
            port = PWM3;
            TIM_ClearITPendingBit(TIM3, TIM_IT_CC1);
            pwmPorts[port].callback(port, TIM_GetCapture1(TIM3));
        } else if (TIM_GetITStatus(TIM3, TIM_IT_CC2) == SET) {
            port = PWM4;
            TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);
            pwmPorts[port].callback(port, TIM_GetCapture2(TIM3));
        }
    }
     void TIM4_IRQHandler(void)		//TIM4
    {
        int8_t port;
    
    
        if (TIM_GetITStatus(TIM4, TIM_IT_CC1) == SET) {
            port = PWM5;
            TIM_ClearITPendingBit(TIM4, TIM_IT_CC1);
            pwmPorts[port].callback(port, TIM_GetCapture1(TIM4));
        } else if (TIM_GetITStatus(TIM4, TIM_IT_CC2) == SET) {
            port = PWM6;
            TIM_ClearITPendingBit(TIM4, TIM_IT_CC2);
            pwmPorts[port].callback(port, TIM_GetCapture2(TIM4));
        } else if (TIM_GetITStatus(TIM4, TIM_IT_CC3) == SET) {
            port = PWM7;
            TIM_ClearITPendingBit(TIM4, TIM_IT_CC3);
            pwmPorts[port].callback(port, TIM_GetCapture3(TIM4));
        } else if (TIM_GetITStatus(TIM4, TIM_IT_CC4) == SET) {
            port = PWM8;
            TIM_ClearITPendingBit(TIM4, TIM_IT_CC4);
            pwmPorts[port].callback(port, TIM_GetCapture4(TIM4));
        }
    }
    
     void TIM5_IRQHandler(void)		//TIM5
    {
        int8_t port;
    
    
        if (TIM_GetITStatus(TIM5, TIM_IT_CC1) == SET) {
            port = PWM16;
            TIM_ClearITPendingBit(TIM5, TIM_IT_CC1);
            pwmPorts[port].callback(port, TIM_GetCapture1(TIM5));
        } else if (TIM_GetITStatus(TIM5, TIM_IT_CC2) == SET) {
            port = PWM15;
            TIM_ClearITPendingBit(TIM5, TIM_IT_CC2);
            pwmPorts[port].callback(port, TIM_GetCapture2(TIM5));
        } else if (TIM_GetITStatus(TIM5, TIM_IT_CC3) == SET) {
            port = PWM14;
            TIM_ClearITPendingBit(TIM5, TIM_IT_CC3);
            pwmPorts[port].callback(port, TIM_GetCapture3(TIM5));
        } else if (TIM_GetITStatus(TIM5, TIM_IT_CC4) == SET) {
            port = PWM13;
            TIM_ClearITPendingBit(TIM5, TIM_IT_CC4);
            pwmPorts[port].callback(port, TIM_GetCapture4(TIM5));
        }
    }
    static void ppmCallback(uint8_t port, uint16_t capture)
    {
        uint16_t diff;
        static uint16_t now;
        static uint16_t last = 0;
        static uint8_t chan = 0;
    
        last = now;
        now = capture;
        diff = now - last;
    
        if (diff > 2700) { // Per http://www.rcgroups.com/forums/showpost.php?p=21996147&postcount=3960 "So, if you use 2.5ms or higher as being the reset for the PPM stream start, you will be fine. I use 2.7ms just to be safe."
            chan = 0;
        } else {
            if (diff > 750 && diff < 2250 && chan < 8) {   // 750 to 2250 ms is our 'valid' channel range
                captures[chan] = diff;
            }
            chan++;
            failsafeCnt = 0;
        }
    }
    
    static void pwmCallback(uint8_t port, uint16_t capture)
    {
        if (pwmPorts[port].state == 0) {
            pwmPorts[port].rise = capture;
            pwmPorts[port].state = 1;
            pwmICConfig(timerHardware[port].tim, timerHardware[port].channel, TIM_ICPolarity_Falling);
        } else {
            pwmPorts[port].fall = capture;
            // compute capture
            pwmPorts[port].capture = pwmPorts[port].fall - pwmPorts[port].rise;
            captures[pwmPorts[port].channel] = pwmPorts[port].capture;
            // switch state
            pwmPorts[port].state = 0;
            pwmICConfig(timerHardware[port].tim, timerHardware[port].channel, TIM_ICPolarity_Rising);
            // reset failsafe
            failsafeCnt = 0;
        }
    }
    
    bool pwmInit(drv_pwm_config_t *init)
    {
        int i = 0;
        const uint8_t *setup;
    
        // this is pretty hacky shit, but it will do for now. array of 4 config maps, [ multiPWM multiPPM airPWM airPPM ]
        if (init->airplane)
            i = 2; // switch to air hardware config
        if (init->usePPM)
            i++; // next index is for PPM
    
        setup = hardwareMaps[i];
    
        for (i = 0; i < MAX_PORTS; i++) {
            uint8_t port = setup[i] & 0x0F;
            uint8_t mask = setup[i] & 0xF0;
    
            if (setup[i] == 0xFF) // terminator
                break;
            if (mask & TYPE_IP) {
                pwmInConfig(port, ppmCallback, 0);
                numInputs = 8;
            } else if (mask & TYPE_IW) {
                pwmInConfig(port, pwmCallback, numInputs);
                numInputs++;
            } else if (mask & TYPE_M) {
                motors[numMotors++] = pwmOutConfig(port, 1000000 / init->motorPwmRate, PULSE_1MS);
            } else if (mask & TYPE_S) {
                servos[numServos++] = pwmOutConfig(port, 1000000 / init->servoPwmRate, PULSE_1MS);
            }
        }
    
        return false;
    }
    
    void pwmWriteMotor(uint8_t index, uint16_t value)
    {
        if (index < numMotors)
            *motors[index]->ccr = value;
    }
    
    void pwmWriteServo(uint8_t index, uint16_t value)
    {
        if (index < numServos)
            *servos[index]->ccr = value;
    }
    
    uint16_t pwmRead(uint8_t channel)
    {
        return captures[channel];
    }

  12. #1689

    Регистрация
    22.08.2011
    Адрес
    Калининград
    Возраст
    35
    Сообщений
    947
    Записей в дневнике
    2
    Цитата Сообщение от mahowik Посмотреть сообщение
    тогда что он фильтрует 1D?

    Я так сильно не капал калман в афрофлайте, но похоже это вариации на тему Альфа-Бета фильтра. Фильтровать он фильтрует хорошо, но данные не фузионит.
    И основная проблема это как узнать характеристику шума сигнала который нужно фильтровать, для корректной настройки калмана.

    Вот нашел семпл калмана для атмеги http://sites.google.com/site/jordiua...r_by_Jordi.txt

  13. #1690

    Регистрация
    01.11.2010
    Адрес
    Belarus Slonim
    Возраст
    36
    Сообщений
    4,462
    Записей в дневнике
    8
    я когда-то запускал что-то подобное на атмеге в паралель с альфа бета, но опять же по одной оси http://forum.rcdesign.ru/f123/thread224458-3.html#post2656976

  14. #1691

    Регистрация
    22.08.2011
    Адрес
    Калининград
    Возраст
    35
    Сообщений
    947
    Записей в дневнике
    2
    Блин а ветке то уже 2 года и мы это дату прощелкали =))

  15. #1692

    Регистрация
    01.11.2010
    Адрес
    Belarus Slonim
    Возраст
    36
    Сообщений
    4,462
    Записей в дневнике
    8
    Даа, время летит, а сколько битых аппаратов.... наверно можно было купить что-нибудь дорогущее.... но это же не интересно

  16. #1693

    Регистрация
    01.11.2010
    Адрес
    Belarus Slonim
    Возраст
    36
    Сообщений
    4,462
    Записей в дневнике
    8
    И в продолжении темы:
    хвастаюся
    Миниатюры Миниатюры Нажмите на изображение для увеличения
Название: DSCN0351.jpg‎
Просмотров: 82
Размер:	80.9 Кб
ID:	771994  

  17. #1694

    Регистрация
    19.04.2010
    Адрес
    Ханты
    Возраст
    40
    Сообщений
    1,471
    Цитата Сообщение от SergDoc Посмотреть сообщение
    хвастаюся
    Красиво! ждемс испытаний

  18. #1695

    Регистрация
    01.11.2010
    Адрес
    Belarus Slonim
    Возраст
    36
    Сообщений
    4,462
    Записей в дневнике
    8
    Время, его то как раз нет, мне ещё код допиливать, ну одну плату думаю после выходных соберу, когда тестить буду ещё не знаю, т.к. мои в апреле поедут в деревню, мне, пока детей дома не будет, надо ремонт на кухне сделать...
    вопрос, что на нижней плате запаять в переходные разъёмы - мамы или папы? я склоняюсь к папам, т.к. нижняя плата, в принципе, законченое устройство и папы легче...

  19. #1696

    Регистрация
    06.04.2012
    Адрес
    Moscow
    Возраст
    34
    Сообщений
    202
    Цитата Сообщение от SergDoc Посмотреть сообщение
    Дошли руки до ШИМов, начало:
    Код:
    static pwmHardware_t timerHardware[] = {
        { TIM2, GPIOA, GPIO_Pin_15,TIM_Channel_1, TIM2_IRQn, 0, },          	// PWM1
        { TIM2, GPIOB, GPIO_Pin_3, TIM_Channel_2, TIM2_IRQn, 0, },          	// PWM2
        { TIM3, GPIOB, GPIO_Pin_4, TIM_Channel_1, TIM3_IRQn, 0, },          	// PWM3
        { TIM3, GPIOB, GPIO_Pin_5, TIM_Channel_2, TIM3_IRQn, 0, },          	// PWM4
        { TIM4, GPIOB, GPIO_Pin_6, TIM_Channel_1, TIM4_IRQn, 0, },          	// PWM5
        { TIM4, GPIOB, GPIO_Pin_7, TIM_Channel_2, TIM4_IRQn, 0, },          	// PWM6
        { TIM4, GPIOB, GPIO_Pin_8, TIM_Channel_3, TIM4_IRQn, 0, },  	              // PWM7
        { TIM4, GPIOB, GPIO_Pin_9, TIM_Channel_4, TIM4_IRQn, 0, },		// PWM8
        { TIM1, GPIOE, GPIO_Pin_14,TIM_Channel_4, TIM1_CC_IRQn, 1, },                // PWM9
        { TIM1, GPIOE, GPIO_Pin_13,TIM_Channel_3, TIM1_CC_IRQn, 1, },       	// PWM10
        { TIM1, GPIOE, GPIO_Pin_11,TIM_Channel_2, TIM1_CC_IRQn, 1, },      	// PWM11
        { TIM1, GPIOE, GPIO_Pin_9, TIM_Channel_1, TIM1_CC_IRQn, 1, },                 // PWM12
        { TIM5, GPIOA, GPIO_Pin_3, TIM_Channel_4, TIM5_IRQn, 0, },          	// PWM13
        { TIM5, GPIOA, GPIO_Pin_2, TIM_Channel_3, TIM5_IRQn, 0, },          	// PWM14
        { TIM5, GPIOA, GPIO_Pin_1, TIM_Channel_2, TIM5_IRQn, 0, },          	// PWM15
        { TIM5, GPIOA, GPIO_Pin_0, TIM_Channel_1, TIM5_IRQn, 0, },       		// PWM16     		
        { TIM8, GPIOC, GPIO_Pin_6, TIM_Channel_1, TIM8_CC_IRQn, 1, },                 // PWM17
        { TIM8, GPIOC, GPIO_Pin_7, TIM_Channel_2, TIM8_CC_IRQn, 1, },                 // PWM18
        { TIM8, GPIOC, GPIO_Pin_8, TIM_Channel_3, TIM8_CC_IRQn, 1, },                 // PWM19
        { TIM8, GPIOC, GPIO_Pin_9, TIM_Channel_4, TIM8_CC_IRQn, 1, },                 // PWM20
    };
    Это откуда код, Сергей? Вы так кусками из разных проектов обычно выдержки показываете, что трудно следить за мыслью. Если это кусок какого-то проекта, то хоть ссылайтесь на него - какой проект, какой файл.

    Цитата Сообщение от Razek Посмотреть сообщение
    Я так сильно не капал калман в афрофлайте, но похоже это вариации на тему Альфа-Бета фильтра. Фильтровать он фильтрует хорошо, но данные не фузионит.
    И основная проблема это как узнать характеристику шума сигнала который нужно фильтровать, для корректной настройки калмана.

    Вот нашел семпл калмана для атмеги http://sites.google.com/site/jordiua...r_by_Jordi.txt
    А есть нормальное описание, понятное для программера, а не математика как осуществлять sensor fusion для обычных доступных датчиков? Например ITG3200, ADXL345, HMC5883. Ну или что-то аналогичное. Ведь задача то всегда одна и та же - имея несовершенные датчики взаимно корректировать их для получения инерциальных данных и положения аппарата в пространстве.
    Логику-то я более-менее понимаю, но от логики до реализации даже не десяток шагов.

  20. #1697

    Регистрация
    01.11.2010
    Адрес
    Belarus Slonim
    Возраст
    36
    Сообщений
    4,462
    Записей в дневнике
    8
    Цитата Сообщение от RaJa Посмотреть сообщение
    Это откуда код, Сергей?
    тут весь же драйвер выложил.... а на чём основано, на том же на чём и мелкоплата была, на afrodevices

    Цитата Сообщение от SergDoc Посмотреть сообщение
    была
    ой почему была - есть, правда сейчас лишится барометра

  21. #1698

    Регистрация
    06.04.2012
    Адрес
    Moscow
    Возраст
    34
    Сообщений
    202
    Цитата Сообщение от SergDoc Посмотреть сообщение
    тут весь же драйвер выложил.... а на чём основано, на том же на чём и мелкоплата была, на afrodevices
    Сорри, видимо, я пропустил этот момент.

  22. #1699

    Регистрация
    01.11.2010
    Адрес
    Belarus Slonim
    Возраст
    36
    Сообщений
    4,462
    Записей в дневнике
    8
    Сегодня произошла беда, сломал mpu6000 - соскачила с пинцета и этим же пинцетом выгрызло 13-ю лапу причём глубоко, даже зацепится не за что , а так почти собрал плату , дальнейшая сборка откладывается на неопределённое время, ибо надо заказывать новую микруху хорошо хоть мелкоплату не разобрал, а то уже собирался барометр выковырять. Вот такой вот я безрукий. Ладно есть время код допилить....

  23. #1700

    Регистрация
    13.03.2011
    Адрес
    Montreal, Canada
    Возраст
    38
    Сообщений
    2,291
    Записей в дневнике
    19
    Сергей, тут с чипом уже терять нечего. Попробуй иголкой проколупать корпус около потерянной ноги... я в детстве так транзисторы спасал иногда...

  24. #1701

    Регистрация
    01.11.2010
    Адрес
    Belarus Slonim
    Возраст
    36
    Сообщений
    4,462
    Записей в дневнике
    8
    я уже думал об этом, завтра на работе попробую прорезать, но там блин рядом с лапой корпус металлический горизонтальные по краям, боюсь не подпаяюсь....

  25. #1702

    Регистрация
    02.03.2011
    Адрес
    Санкт-Петербург, Оренбург,
    Возраст
    49
    Сообщений
    2,566
    Цитата Сообщение от SergDoc Посмотреть сообщение
    боюсь не подпаяюсь..
    Прямо с торца встык и паять. Когда то в детстве точно подобное получалось, каждая мелкосхема тогда была на счету, главное не шевелить все это безобразие после пайки.

  26. #1703

    Регистрация
    01.11.2010
    Адрес
    Belarus Slonim
    Возраст
    36
    Сообщений
    4,462
    Записей в дневнике
    8
    Цитата Сообщение от Probelzaelo Посмотреть сообщение
    главное не шевелить все это безобразие после пайки.
    ага особенно на коптере а вы размер себе представляете 4Х4мм по шесть лап с каждой стороны, там всё к чему припаятся это 0.05 мм хвостик и то если достану...

  27. #1704

    Регистрация
    02.03.2011
    Адрес
    Санкт-Петербург, Оренбург,
    Возраст
    49
    Сообщений
    2,566
    Цитата Сообщение от SergDoc Посмотреть сообщение
    ага особенно на коптере
    ну если петля из провода наружу торчать не будет то подержится.
    Цитата Сообщение от SergDoc Посмотреть сообщение
    всё к чему припаятся это 0.05 мм хвостик и то если достану...
    Придется "выточить шильце" из проводка 0.1, либо оставить затею, чем все возможно и закончится. ))))
    на самом деле из реальных вариантов как выше было сказано расковырять корпус, но лучше не иголкой, а гравером с тонким камнем мелким "напылением" слегка подточить корпус, если он не керамический, если керамический, то нужно будет совсем альмас, однако, чтоб Гюльчитай личико приоткыло. может что и получится. если не получится - все равно выбрасывать ))

    Цитата Сообщение от SergDoc Посмотреть сообщение
    пинцетом выгрызло 13-ю лапу
    Какое число не счастливое - 13 , а оно туда ест!

    кстати а соседние 14,15,16 если они ни куда не включены(как сказано в даташите) и просто висят, то это очень удобная "держалка" для проводничка, правда у держалки длина 0.4мм, корпус нужно пилить вдоль этих нескольких ног сразу до появления "металла" и класть на них поперек жилку из провода, чтоб она и 13 захватила, лишнее срезать нафиг, а как и куда потом объединять площадки 13,14,15 уже решать проще. сильно надеюсь они там не на земле...
    Последний раз редактировалось Probelzaelo; 29.03.2013 в 02:12.

  28. #1705

    Регистрация
    01.11.2010
    Адрес
    Belarus Slonim
    Возраст
    36
    Сообщений
    4,462
    Записей в дневнике
    8
    Мир не без добрых людей, сегодня закажу новую
    Пока есть чем заняться, ещё не разобрался с Uart+DMA, SPI - драйвер вроде осилил, да ещё драйвер самой MPU надо делать, придумывать как его присобачить, потом USB, работы ещё уйма, чем занять два лишних светодиода? а ещё SPI Flash и i2c eeprom, думаю пока датчик приедет ещё ПО готово не будет, есть сомнения по i2c....

  29. #1706

    Регистрация
    01.11.2010
    Адрес
    Belarus Slonim
    Возраст
    36
    Сообщений
    4,462
    Записей в дневнике
    8
    Плату-то можно сделать будет и намного меньше, при том, что китайцы научились 4-х слойки делать, чувствую тема никогда не кончится предлагаю, пока естественно чисто теоретически, новый проект, но уже на "крутых" датчиках, кто что предложит? (аналоговые через АЦП-SPI) Настроение у меня сегодня хорошее

  30. #1707

    Регистрация
    17.06.2011
    Адрес
    Минск
    Возраст
    39
    Сообщений
    1,941
    Поделитесь плиз секретом, где затариваться детальками для мелкосерийного производства? Ну там 50 штучек того, 50 того... На ebay в принципе есть поставщики, но мало ли где то есть еще дешевле.

    Сергей, ты заказывал в РБ, ну скажем 50 микрух, были ли проблемы с таможней?

  31. #1708

    Регистрация
    01.11.2010
    Адрес
    Belarus Slonim
    Возраст
    36
    Сообщений
    4,462
    Записей в дневнике
    8
    Цитата Сообщение от Sir Alex Посмотреть сообщение
    ну скажем 50 микрух, были ли проблемы с таможней?
    не я так много не беру, одну две, а вот платок 10 и ничего.... пропы тоже пачками, три четыре упаковки по 6 шт.

  32. #1709

    Регистрация
    13.03.2011
    Адрес
    Montreal, Canada
    Возраст
    38
    Сообщений
    2,291
    Записей в дневнике
    19
    Цитата Сообщение от Sir Alex Посмотреть сообщение
    Поделитесь плиз секретом, где затариваться детальками для мелкосерийного производства? Ну там 50 штучек того, 50 того...
    http://www.digikey.com/ рулит... дистрибьюторы по всему миру... даж РБ вроде http://www.digikey.by/
    ценник пожалуй самый низкий, а ассортимент товара огромный... есть если не все, то почти все... не знаю только что с доставкой в РБ... в канаду 7$...

    как пример http://www.digikey.com/scripts/dksea...=STM32F407VGT6
    http://www.digikey.com/scripts/DkSea...COVERY&cur=USD

  33. #1710

    Регистрация
    01.11.2010
    Адрес
    Belarus Slonim
    Возраст
    36
    Сообщений
    4,462
    Записей в дневнике
    8
    В РБ нифига не пошлют, ибо ню-ню... мы вне закона доставка от 44 а потом скажут - мы не можем выслать данный товар, потому что бла, бла, бла... да потом ещё месяц спрашивать каждый день будут, а зачем вы хотели купить это?

  34. #1711

    Регистрация
    13.03.2011
    Адрес
    Montreal, Canada
    Возраст
    38
    Сообщений
    2,291
    Записей в дневнике
    19
    херова ((
    могу STM32F4DISCOVERY по себестоимости передать с кем (с налогами и доставкой чета около 23$), если кто будет ехать из знакомых... не пользованая по сути... себе по надобности новую закажу...

  35. #1712

    Регистрация
    01.11.2010
    Адрес
    Belarus Slonim
    Возраст
    36
    Сообщений
    4,462
    Записей в дневнике
    8
    есть дырка, но к сожалению, уже в долги залез, так что накоплю - куплю себе проц нормальный.....

  36. #1713

    Регистрация
    15.06.2011
    Адрес
    Ростов-на-Дону
    Возраст
    45
    Сообщений
    870
    ИМХО , если не использовать DMP , то закладывать в разработку MPU-6000 было несовсем правильное решение ибо недешево и вечные проблемы с доставабельностью ... может есть смысл сделать еще один вариант верхней платы на чемнибуди более даставабельном ??? LSM330 или L3g4200 + bma180 ???

    PS: интересно что быстрее станет доступно LSM333 или MPU-9250 ...
    PPS: посылку собрал ...

  37. #1714

    Регистрация
    01.11.2010
    Адрес
    Belarus Slonim
    Возраст
    36
    Сообщений
    4,462
    Записей в дневнике
    8
    чёт не догоняю я этот uart dma, uart1 dma1, а какой Stream ? тфу-ты из AutoQuad-а выдернуть же можно....

    Цитата Сообщение от Gapey Посмотреть сообщение
    LSM330
    чёта я лсм-ки наелся, хотяяя - жду безветрия попробую, должно уже нормально полететь...

    блин уже башка трещит, stream а потом chanel ещё, куда чего писать?
    Последний раз редактировалось SergDoc; 29.03.2013 в 22:05.

  38. #1715

    Регистрация
    17.06.2011
    Адрес
    Минск
    Возраст
    39
    Сообщений
    1,941
    Цитата Сообщение от mahowik Посмотреть сообщение
    http://www.digikey.com/ рулит... дистрибьюторы по всему миру... даж РБ вроде http://www.digikey.by/ ценник пожалуй самый низкий, а ассортимент товара огромный... есть если не все, то почти все... не знаю только что с доставкой в РБ... в канаду 7$...
    Не не, доставка у них от 100$ в Беларусь. А по ценнику, посмотри и биплатно пришлют

  39. #1716

    Регистрация
    01.11.2010
    Адрес
    Belarus Slonim
    Возраст
    36
    Сообщений
    4,462
    Записей в дневнике
    8
    Цитата Сообщение от Sir Alex Посмотреть сообщение
    А по ценнику, посмотри и биплатно пришлют
    только картинка зачётная не vgt а vet а в vet только вий и аероквад лезут, у остальных проектов флеха занята под 400кb и выше....
    Последний раз редактировалось SergDoc; 29.03.2013 в 23:01.

  40. #1717

    Регистрация
    01.11.2010
    Адрес
    Belarus Slonim
    Возраст
    36
    Сообщений
    4,462
    Записей в дневнике
    8
    ну вот, переделанный uart Билла Несбита, под f4 ихний почему-то не нашел, так что переделывал старый, который спёр Таймкоп
    Код:
    #include "board.h"
    
    /*
        DMA UART routines idea lifted from AutoQuad
        Copyright © 2011  Bill Nesbitt
    */
    #define UART_BUFFER_SIZE    256
    
    // Receive buffer, circular DMA
    volatile uint8_t rxBuffer[UART_BUFFER_SIZE];
    uint32_t rxDMAPos = 0;
    volatile uint8_t txBuffer[UART_BUFFER_SIZE];
    uint32_t txBufferTail = 0;
    uint32_t txBufferHead = 0;
    
    static void uartTxDMA(void)
    {
    	DMA1_Stream4->M0AR = (uint32_t)&txBuffer[txBufferTail];
        if (txBufferHead > txBufferTail) {
        	DMA1_Stream4->NDTR = txBufferHead - txBufferTail;
            txBufferTail = txBufferHead;
        } else {
        	DMA1_Stream4->NDTR = UART_BUFFER_SIZE - txBufferTail;
            txBufferTail = 0;
        }
    
        DMA_Cmd(DMA1_Stream4, ENABLE);
    }
    
    void DMA1_Channel4_IRQHandler(void)
    {
        DMA_ClearITPendingBit(DMA1_Stream4, DMA_IT_TCIF4);
        DMA_Cmd(DMA1_Stream4, DISABLE);
    
        if (txBufferHead != txBufferTail)
            uartTxDMA();
    }
    
    void uartInit(uint32_t speed)
    {
        GPIO_InitTypeDef GPIO_InitStructure;
        USART_InitTypeDef USART_InitStructure;
        DMA_InitTypeDef DMA_InitStructure;
        NVIC_InitTypeDef NVIC_InitStructure;
    
        // USART1_TX    PA9
        // USART1_RX    PA10
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
        GPIO_Init(GPIOA, &GPIO_InitStructure);
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
        GPIO_Init(GPIOA, &GPIO_InitStructure);
    
        // DMA TX Interrupt
        NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream4_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);
    
        USART_InitStructure.USART_BaudRate = speed;
        USART_InitStructure.USART_WordLength = USART_WordLength_8b;
        USART_InitStructure.USART_StopBits = USART_StopBits_1;
        USART_InitStructure.USART_Parity = USART_Parity_No;
        USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
        USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
        USART_Init(USART1, &USART_InitStructure);
    
        // Receive DMA into a circular buffer
        DMA_DeInit(DMA1_Stream5);
        DMA_InitStructure.DMA_Channel = DMA_Channel_5;
        DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
        DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
        DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART1->DR;
        DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)rxBuffer;
        DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
        DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
        DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
        DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
        DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
        DMA_InitStructure.DMA_BufferSize = UART_BUFFER_SIZE;
        DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
        DMA_Init(DMA1_Stream5, &DMA_InitStructure);
    
        DMA_Cmd(DMA1_Stream5, ENABLE);
        USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE);
        rxDMAPos = DMA_GetCurrDataCounter(DMA1_Stream5);
    
        // Transmit DMA
        DMA_DeInit(DMA1_Stream5);
        DMA_InitStructure.DMA_Channel = DMA_Channel_5;
        DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART1->DR;
        DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
        DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
        DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
        DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
        DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
        DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
        DMA_Init(DMA1_Stream5, &DMA_InitStructure);
        DMA_ITConfig(DMA1_Stream5, DMA_IT_TC, ENABLE);
        DMA1_Stream5->NDTR = 0;
        USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
    
        USART_Cmd(USART1, ENABLE);
    }
    
    uint16_t uartAvailable(void)
    {
        return (DMA_GetCurrDataCounter(DMA1_Stream5) != rxDMAPos) ? true : false;
    }
    
    bool uartTransmitEmpty(void)
    {
        return (txBufferTail == txBufferHead);
    }
    
    uint8_t uartRead(void)
    {
        uint8_t ch;
    
        ch = rxBuffer[UART_BUFFER_SIZE - rxDMAPos];
        // go back around the buffer
        if (--rxDMAPos == 0)
            rxDMAPos = UART_BUFFER_SIZE;
    
        return ch;
    }
    
    uint8_t uartReadPoll(void)
    {
        while (!uartAvailable()); // wait for some bytes
        return uartRead();
    }
    
    void uartWrite(uint8_t ch)
    {
        txBuffer[txBufferHead] = ch;
        txBufferHead = (txBufferHead + 1) % UART_BUFFER_SIZE;
    
        // if DMA wasn't enabled, fire it up
        if (!(DMA1_Stream4->CR & 1))
            uartTxDMA();
    }
    
    void uartPrint(char *str)
    {
        while (*str)
            uartWrite(*(str++));
    }
    
    /* -------------------------- UART2  ----------------------------- */
    uartReceiveCallbackPtr uart2Callback = NULL;
    #define UART2_BUFFER_SIZE    128
    
    volatile uint8_t tx2Buffer[UART2_BUFFER_SIZE];
    uint32_t tx2BufferTail = 0;
    uint32_t tx2BufferHead = 0;
    bool uart2RxOnly = false;
    
    static void uart2Open(uint32_t speed)
    {
        USART_InitTypeDef USART_InitStructure;
    
        USART_StructInit(&USART_InitStructure);
        USART_InitStructure.USART_BaudRate = speed;
        USART_InitStructure.USART_WordLength = USART_WordLength_8b;
        USART_InitStructure.USART_StopBits = USART_StopBits_1;
        USART_InitStructure.USART_Parity = USART_Parity_No;
        USART_InitStructure.USART_Mode = USART_Mode_Rx | (uart2RxOnly ? 0 : USART_Mode_Tx);
        USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
        USART_Init(USART2, &USART_InitStructure);
        USART_Cmd(USART2, ENABLE);
    }
    
    void uart2Init(uint32_t speed, uartReceiveCallbackPtr func, bool rxOnly)
    {
        NVIC_InitTypeDef NVIC_InitStructure;
        GPIO_InitTypeDef GPIO_InitStructure;
    
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
    
        uart2RxOnly = rxOnly;
    
        NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);
    
        // USART2_TX    PD5
        // USART2_RX    PD6
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
        if (!rxOnly)
            GPIO_Init(GPIOD, &GPIO_InitStructure);
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
        GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_DOWN;
        GPIO_Init(GPIOD, &GPIO_InitStructure);
    
        uart2Open(speed);
        USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
        if (!rxOnly)
            USART_ITConfig(USART2, USART_IT_TXE, ENABLE);
        uart2Callback = func;
    }
    
    void uart2ChangeBaud(uint32_t speed)
    {
        uart2Open(speed);
    }
    
    void uart2Write(uint8_t ch)
    {
        if (uart2RxOnly)
            return;
    
        tx2Buffer[tx2BufferHead] = ch;
        tx2BufferHead = (tx2BufferHead + 1) % UART2_BUFFER_SIZE;
    
        USART_ITConfig(USART2, USART_IT_TXE, ENABLE);
    }
    
    bool uart2TransmitEmpty(void)
    {
        return tx2BufferTail == tx2BufferHead;
    }
    
    void USART2_IRQHandler(void)
    {
        uint16_t SR = USART2->SR;
    
        if (SR & USART_IT_RXNE) {
            if (uart2Callback)
                uart2Callback(USART_ReceiveData(USART2));
        }
        if (SR & USART_FLAG_TXE) {
            if (tx2BufferTail != tx2BufferHead) {
                USART2->DR = tx2Buffer[tx2BufferTail];
                tx2BufferTail = (tx2BufferTail + 1) % UART2_BUFFER_SIZE;
            } else {
                USART_ITConfig(USART2, USART_IT_TXE, DISABLE);
            }
        }
    }
    
    /* -------------------------- UART3  ----------------------------- */
    uartReceiveCallbackPtr uart3Callback = NULL;
    #define UART3_BUFFER_SIZE    128
    
    volatile uint8_t tx3Buffer[UART3_BUFFER_SIZE];
    uint32_t tx3BufferTail = 0;
    uint32_t tx3BufferHead = 0;
    bool uart3RxOnly = false;
    
    static void uart3Open(uint32_t speed)
    {
        USART_InitTypeDef USART_InitStructure;
    
        USART_StructInit(&USART_InitStructure);
        USART_InitStructure.USART_BaudRate = speed;
        USART_InitStructure.USART_WordLength = USART_WordLength_8b;
        USART_InitStructure.USART_StopBits = USART_StopBits_1;
        USART_InitStructure.USART_Parity = USART_Parity_No;
        USART_InitStructure.USART_Mode = USART_Mode_Rx | (uart3RxOnly ? 0 : USART_Mode_Tx);
        USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
        USART_Init(USART3, &USART_InitStructure);
        USART_Cmd(USART3, ENABLE);
    }
    
    void uart3Init(uint32_t speed, uartReceiveCallbackPtr func, bool rxOnly)
    {
        NVIC_InitTypeDef NVIC_InitStructure;
        GPIO_InitTypeDef GPIO_InitStructure;
    
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
    
        uart3RxOnly = rxOnly;
    
        NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);
    
        // USART2_TX    PD8
        // USART2_RX    PD9
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
        if (!rxOnly)
            GPIO_Init(GPIOD, &GPIO_InitStructure);
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
        GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_DOWN;
        GPIO_Init(GPIOD, &GPIO_InitStructure);
    
        uart3Open(speed);
        USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
        if (!rxOnly)
            USART_ITConfig(USART3, USART_IT_TXE, ENABLE);
        uart3Callback = func;
    }
    
    void uart3ChangeBaud(uint32_t speed)
    {
        uart3Open(speed);
    }
    
    void uart3Write(uint8_t ch)
    {
        if (uart3RxOnly)
            return;
    
        tx3Buffer[tx3BufferHead] = ch;
        tx3BufferHead = (tx3BufferHead + 1) % UART3_BUFFER_SIZE;
    
        USART_ITConfig(USART3, USART_IT_TXE, ENABLE);
    }
    
    bool uart3TransmitEmpty(void)
    {
        return tx3BufferTail == tx3BufferHead;
    }
    
    void USART3_IRQHandler(void)
    {
        uint16_t SR = USART3->SR;
    
        if (SR & USART_IT_RXNE) {
            if (uart3Callback)
                uart3Callback(USART_ReceiveData(USART3));
        }
        if (SR & USART_FLAG_TXE) {
            if (tx3BufferTail != tx3BufferHead) {
                USART3->DR = tx3Buffer[tx3BufferTail];
                tx3BufferTail = (tx3BufferTail + 1) % UART3_BUFFER_SIZE;
            } else {
                USART_ITConfig(USART3, USART_IT_TXE, DISABLE);
            }
        }
    }
    проект компилится, но далеко не факт что я что-то не намудрил
    только вот под телеметрию, тоже с DMA надо? если да то - ну его нафиг

  41. #1718
    DVE
    DVE вне форума

    Регистрация
    16.06.2008
    Адрес
    EU
    Возраст
    37
    Сообщений
    4,386
    Вышел новый Кролик
    http://www.aliexpress.com/item/Rabbi...820519824.html
    Параметры они не пишут но примерно наверно можно прикинуть что там
    - 32 digits 72 MHZ CPU
    - Gyroscope: +-2000dps,16 digits resolution ratio, responding time:1000HZ
    - Accelerometer: -8G,14 digits resolution ratio, responding time:800Hz
    - Digital Compass:+- 1 deg

    Мне что-то думается что туда с минимальными переделками зальется версия от timecop, или я ошибаюсь?
    Даже подумалось не купить ли одного кролика на опыты...

  42. #1719

    Регистрация
    19.04.2010
    Адрес
    Ханты
    Возраст
    40
    Сообщений
    1,471
    Цитата Сообщение от DVE Посмотреть сообщение
    Параметры они не пишут но примерно наверно можно прикинуть что там - 32 digits 72 MHZ CPU - Gyroscope: +-2000dps,16 digits resolution ratio, responding time:1000HZ - Accelerometer: -8G,14 digits resolution ratio, responding time:800Hz - Digital Compass:+- 1 deg
    "Кролики это не только ценный мех..." Что там за проц? Какая шина к датчикам? В целом схематехнику не плохо бы было посмотреть... Если там СТМ то можно залить что угодно, вопрос только в количестве памяти и функционале ШИМ-входов\выходов.


    Цитата Сообщение от SergDoc Посмотреть сообщение
    только вот под телеметрию, тоже с DMA надо? если да то - ну его нафиг
    ПДП по уарт не использовал, но в самом деле нет никого волшебства, должно работать. Главное правильно распределить каналы, чтоб не получилось что 2 разных устройства используют один канал.

    Вот у меня так :
    Код:
    /*******************************************************************************
    * Function Name  :  USART_Config_Default.
    * Description    :  configure the USART1 with default values.
    * Input          :  None.
    * Return         :  None.
    *******************************************************************************/
    void USART1_Config(uint32_t rate)
    {
      GPIO_InitTypeDef GPIO_InitStructure;
     USART_InitTypeDef USART_InitStructure;
     /* подадим такт на порт */
      RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
      /* настройка выводов порта */
      GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_4|GPIO_Pin_5;  
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
      GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
      GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
      GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
      GPIO_Init(GPIOC, &GPIO_InitStructure);
      
      /* Соединим выводы портов с AF7 */
     GPIO_PinAFConfig(GPIOC, GPIO_PinSource5, GPIO_AF_7);
     GPIO_PinAFConfig(GPIOC, GPIO_PinSource4, GPIO_AF_7);
      
      /* обнуляем указатели буферов */  
      USART1_TX_src_ptr = USART1_TX_dst_ptr = 0;
      USART1_RX_src_ptr = USART1_RX_dst_ptr = 0;
      /* настройка УПСИ */
      RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
      USART_InitStructure.USART_BaudRate = rate;
      USART_InitStructure.USART_WordLength = USART_WordLength_8b;
      USART_InitStructure.USART_StopBits = USART_StopBits_1;
      USART_InitStructure.USART_Parity = USART_Parity_No;
      USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
      USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
      USART_Init(USART1, &USART_InitStructure);
      /* Enable the USART Receive interrupt */
      USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
      USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
      USART_Cmd(USART1, ENABLE); 
      NVIC_EnableIRQ(USART1_IRQn);
      NVIC_SetPriority(USART1_IRQn, 15);   
    }
    /*************** передача байта в УСПСИ *************************/
    uint8_t USART1_TX_buff[256]; /* буфер для передачи УСПИСИ */
    uint8_t USART1_TX_src_ptr; /* указатель на буфер для передачи УСПИСИ */
    uint8_t USART1_TX_dst_ptr; /* указатель на буфер для передачи УСПИСИ */
    void USART1_Transmite(uint8_t data)
    {
     USART1_TX_buff[USART1_TX_src_ptr++] = data;
     USART_ITConfig(USART1, USART_IT_TXE, ENABLE); 
    }
    /**************** приём байта из УСПСИ ****************************/
    uint8_t USART1_RX_buff[256]; /* буфер для приема УСПИСИ */
    uint8_t USART1_RX_src_ptr; /* указатель на буфер для приема УСПИСИ */
    uint8_t USART1_RX_dst_ptr; /* указатель на буфер для приема УСПИСИ */
    uint8_t USART1_Recieve()
    {
     if(USART1_RX_dst_ptr == USART1_RX_src_ptr) 
      return 0; 
     else 
      return USART1_RX_buff[USART1_RX_dst_ptr++]; 
    }
    /**************** получение кол-ва принятых байт УСПСИ ****************************/
    uint8_t USART1_Available(void)
    {
      return (USART1_RX_dst_ptr != USART1_RX_src_ptr) ; 
    }
    обработчик
    Код:
    /*******************************************************************************
    * Function Name  : EVAL_COM1_IRQHandler
    * Description    : This function handles EVAL_COM1 global interrupt request.
    * Input          : None
    * Output         : None
    * Return         : None
    *******************************************************************************/
    void USART1_IRQHandler(void)
    {
      /* ïðè¸ì */
      if (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == SET) 
      {
        USART1_RX_buff[USART1_RX_src_ptr++] = USART_ReceiveData(USART1);   
      }
      /* ïåðåäà÷à */
      if (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == SET) 
      {
       if (USART1_TX_dst_ptr == USART1_TX_src_ptr)
      USART_ITConfig(USART1, USART_IT_TXE, DISABLE);
     else  USART_SendData(USART1, USART1_TX_buff[USART1_TX_dst_ptr++]);
      }
      if (USART_GetFlagStatus(USART1, USART_FLAG_TC) == SET) 
        USART_ClearFlag(USART1, USART_FLAG_TC);
      /* If overrun condition occurs, clear the ORE flag and recover communication */
      if (USART_GetFlagStatus(USART1, USART_FLAG_ORE) != RESET)
     {
        (void)USART_ReceiveData(USART1);
      USART_ClearFlag(USART1, USART_FLAG_ORE);
     }
      
    }
    обложки
    Код:
    extern void USART_Transmite(uint8_t data);
    extern uint8_t  USART_Recieve(void);
    uint8_t USART_Available(void);
          
    struct __FILE { int handle; /* Add whatever you need here */ };
    FILE __stdout;
    FILE __stdin;
    int  fputc(int ch, FILE* f) 
    { 
     //ITM_SendChar(ch);
     USB_PutChar(ch);
     USART1_Transmite(ch); 
     return ch;
    }
    
    int fgetc(FILE *f) 
    {
    //  if (ITM_CheckChar()){
    //   return ITM_ReceiveChar();
    //  }
     
     if (USB_Available()) {  
      return USB_GetChar(); 
     } 
     if (USART1_Available()){
      return USART1_Recieve();   
     }
     return EOF; 
    }
    то что про УСБ закомметируй
    Последний раз редактировалось rual; 31.03.2013 в 13:19.

  43. #1720

    Регистрация
    26.11.2012
    Адрес
    Tambov
    Возраст
    46
    Сообщений
    777
    Вот что у меня осталось от DiscoveryF3 после небольшой работы с ЛУТом:
    Миниатюры Миниатюры Нажмите на изображение для увеличения
Название: pic0003.jpg‎
Просмотров: 74
Размер:	38.2 Кб
ID:	773821  
    Последний раз редактировалось oleg70; 31.03.2013 в 17:27.

+ Ответить в теме

Похожие темы

  1. Система стабилизации гиро+акселерометр
    от Фантомас в разделе Полеты по камере, телеметрия
    Ответов: 32
    Последнее сообщение: 25.01.2011, 14:47
  2. Продам Продам Клона Trex 450SEV2 + Аппаратура + Запчасти+ система стабилизации RTF
    от omegapraim в разделе Барахолка. Вертолеты
    Ответов: 1
    Последнее сообщение: 12.01.2011, 18:16
  3. Продам Трёхосевую систему стабилизации Turnigy V-Bar 600
    от avi@tor в разделе Барахолка. Аппаратура
    Ответов: 1
    Последнее сообщение: 08.11.2010, 13:02
  4. Продам Gaui система стабилизации GU365, дёшево.
    от avi@tor в разделе Барахолка. Вертолеты
    Ответов: 3
    Последнее сообщение: 03.08.2010, 11:13
  5. Системы стабилизации
    от max815 в разделе Фото и видеосъемка, системы стабилизации
    Ответов: 16
    Последнее сообщение: 11.03.2010, 03:14

Метки этой темы

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения