Stm32'de Servo Motora Açı Gönderme Sorunu

Başlatan robikod, 21 Ağustos 2017, 09:15:40

robikod

Merhaba,
Servo motora TIM2->CCR1=1000 gibi ms değerleri göndererek sürebiliyordum şimdi ise 30-60-90 gibi açı değerlerini seri porttan göndererek sürmek istiyorum.
Bunun için şöyle bi algoritma yazdım. Değerleri sağlıyor.
void angle_convert_dutycyle(void)
{
    dc = (((USART_angle / 18) + 10)) * 100;
}


tek bir servo motor sürüyorum usb üzerinden şimdilik. Acaba Stringi tam olarak int e mi çeviremiyorum. Ya da float olarak 2 haneyi almadığım için mi sorun var Yardımcı olursanız sevinirim. Diğer kodlarımı da atayım:
#include "main.h"
#include "common.h"
#include "io_periph_defs.h"
#include "conf.h"
// Kanal 2 de 4 tane Chanel var CH1-CH2-CH3-CH4 4 servo kullanacağımızdan kullanımı kolay olacak
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
void USART1_Init(void);
void led_toggle(void);
static unsigned int USART_angle;
static unsigned int Led_state = 0;
float dc;

int main()
{
    Usart1_init();

    SysTick_Config(SystemCoreClock / 1000);
    //init_pin(DEBUG_LED_PORT, DEBUG_LED_PIN, GPIO_Mode_OUT, GPIO_Speed_50MHz, GPIO_OType_PP, GPIO_PuPd_NOPULL);
    //GPIO_SetBits(DEBUG_LED_PORT, DEBUG_LED_PIN); // basılmadığı durumda reset durumundadır.
    //Delay(1000);
    //Bekleme();
    SERVO_GPIO_Init();

    SERVO_PWM_Init();

    init_pin(DEBUG_LED_PORT, DEBUG_LED_PIN, GPIO_Mode_OUT, GPIO_Speed_50MHz, GPIO_OType_PP, GPIO_PuPd_UP); //led bilgileri tanımlandı.
                                                                                                           // USART1_IRQHandler();

    while (1)
    {

        ust_servo_calistir();
    }
}
void SERVO_GPIO_Init(void) // Servo pin ayarları
{
    GPIO_InitTypeDef GPIO_InitStructure;
    //TIM2-PA0
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //TIM2'de CH_1 pini PA0 olduğu için ilk servo ona göre ayarlandı
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    GPIO_PinAFConfig(GPIOA, GPIO_PinSource0, GPIO_AF_1); // PA0'ın AF_1 kısmında TIM2 ve CH_1 aktif

    //TIM2-PA1
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; //TIM2 CH_2 PA1'de tanımlı
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_1); // TIM2 ve CH2 bu kısımda tanımlı
    //TIM2-PA2
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //TIM2 CH_3 PA3'de tanımlı
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_1); // TIM2 ve CH3 bu kısımda tanımlı
    //TIM2-PA3

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; //TIM2 CH_2 PA3'de tanımlı
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_1); // TIM2 ve CH2 bu kısımda tanımlı
}

void SERVO_PWM_Init(void) //servo pwm-timer ayarları
{
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

    TIM_TimeBaseStructure.TIM_Period = 19999; //arr degeri
    TIM_TimeBaseStructure.TIM_Prescaler = 84; //PrescalerValue; 84
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;

    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse = 1;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    // Kanal Ayarlarını yaptığımız kısım
    //CH1 için
    TIM_OC1Init(TIM2, &TIM_OCInitStructure);
    TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable);

    TIM_ARRPreloadConfig(TIM2, ENABLE);

    // TIM2 de Chanel 2 ayarlarını aktif ediyoruz

    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse = 2; //CCR_Val;

    TIM_OC2Init(TIM2, &TIM_OCInitStructure);

    TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable);

    TIM_Cmd(TIM2, ENABLE);
    //CH3
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse = 3; //CCR_Val;
    TIM_OC3Init(TIM2, &TIM_OCInitStructure);

    TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable);

    TIM_Cmd(TIM2, ENABLE);
    //CH4
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse = 4; //CCR_Val;
    TIM_OC4Init(TIM2, &TIM_OCInitStructure);

    TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Enable);

    TIM_Cmd(TIM2, ENABLE);
}

// void led_toggle()
// {
//     GPIO_SetBits(DEBUG_LED_PORT, DEBUG_LED_PIN);
// }
// void led_off()
// {

//     GPIO_ResetBits(DEBUG_LED_PORT, DEBUG_LED_PIN);
// }
void Usart1_init(void)
{
    // Usart ayarlarını yaptığımız kısım
    GPIO_InitTypeDef GPIO_InitStructure;   // Tx ve Rx ayarları için oluşturduğumuz struct
    USART_InitTypeDef USART_InitStrutcure; // Usart ayarları için oluşturduğumuz struct
    NVIC_InitTypeDef NVIC_InitStructure;   //nvic ayarları için oluşturulan struct
    // USART için Clock ayarlarını yapıyoruz
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

    // Datasheet bilgilerine baktığımızda A9-> TX, A10->RX pinleri olarak kullanılıyor.
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; // 9 ve 10. pinleri belirttik
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure); // A portu olduğunu belirttik

    GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_7); // datasheetinde USART1 için AF değeri 7 olarak verilmiş
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_7);
    // USART Ayarlamaları
    USART_InitStrutcure.USART_BaudRate = 9600;                  //iletişim hızı
    USART_InitStrutcure.USART_WordLength = USART_WordLength_8b; // kaç bitlik veri gönderileceği bilgisi
    USART_InitStrutcure.USART_Parity = USART_Parity_No;
    USART_InitStrutcure.USART_StopBits = USART_StopBits_1;
    USART_InitStrutcure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStrutcure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;

    USART_Init(USART1, &USART_InitStrutcure);
    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
    USART_Cmd(USART1, ENABLE); // Usart Aktif
    //                                                   //Bir kesme oluşturacağımız için kesme ayarlarını yapmamız gerekiyor
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //USART1 in kesmesi olduğunu belirttik
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_Init(&NVIC_InitStructure);
}

void USART1_IRQHandler(void)
{

    if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //enter interrupt when STM32 receice data.
    {
        USART_ClearITPendingBit(USART1, USART_IT_RXNE);

        USART_angle = (unsigned int)USART_ReceiveData(USART1); //receive a char
                                                               // if (USART_Temp_Data == '1')
                                                               // {
                                                               //     angle_ = 1;
                                                               //     // while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET)
                                                               //     //{
                                                               //     //}
                                                               // }

        // if (USART_Temp_Data == '2')
        // {

        //     Led_state = 2;
        // }
        angle_convert_dutycyle();
        USART_ClearITPendingBit(USART1, USART_IT_RXNE);
    }
}

void ust_servo_calistir()
{
    //  if (USART_angle > 45 && USART_angle <= 135) // açılması için
    // {

    //     angle_new = 1500 + (USART_angle - 45) * 12;
    //     TIM2->CCR1 = angle_new;
    //     USART_PutString("aciliyor\n");
    //     Delay(800);
    // }

    // else if (USART_angle > 0 && USART_angle <= 45) //kapanması için gereken aralık
    // {

    //     angle_new = 1000 + (USART_angle * 12);
    //     TIM2->CCR1 = angle_new;
    //     USART_PutString("kapaniyor\n");
    //     Delay(800);
    // }
    // USART_angle = 0;
    // angle_new = 0;

    TIM2->CCR1 = dc;
    Delay(800);
    USART_angle = 0;
    dc = 0;
    Delay(100);
}
void angle_convert_dutycyle(void)
{
    dc = (((USART_angle / 18) + 10)) * 100;
}

// void servo_calistir()
// {
//     TIM2->CCR2 = 500;
//     TIM2->CCR1 = 300;
//     TIM2->CCR2 = 500;
// }
static void USART_SendString(USART_TypeDef *USARTx, char *s)
{
    while (*s)
    {
        while (!USART_GetFlagStatus(USARTx, USART_FLAG_TC))
            ;
        USART_SendData(USARTx, *s);
        s++;
    }
}

void USART_PutString(char *s)
{
    // Send a string
    while (*s)
    {
        USART_PutChar(*s++);
    }
}
void USART_PutChar(char c)
{
    // Wait until transmit data register is empty
    while (!USART_GetFlagStatus(USART1, USART_FLAG_TXE))
        ;
    // Send a char using USART1
    USART_SendData(USART1, c);
}

robikod