Stm32 kesme sorunu

Başlatan robikod, 23 Ağustos 2017, 16:49:51

robikod

Merhaba,
Pyserial slider ile servo motora derece bilgisi gonderiyorum stm32 tarafinda bu bilgi kesme olarak aliniyor. Ancak ard arda slideri kaydirdigimda servo hareket etmemeye basliyor maksimimum 2 3 hareket gorebiliyorum bu sorunu nasil cozebilirim?
#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;
static unsigned int 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();
        Delay(500);
    }
}
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

        // USART_angle2=(unsigned int)USART_REceiveData(USART1);                                                       // if (USART_Temp_Data == '1')

        //
        //     // while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET)
        //     //{
        //     //}
        // }

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

        //     Led_state = 2;
        // }

        USART_PutString("duty\n");

        // 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;
    angle_convert_dutycyle();
    TIM2->CCR1 = dc;
}
void angle_convert_dutycyle(void)
{
    char buf[40];
    float tmp1 = ((float)USART_angle / 180.0);
    dc = ((tmp1 + 1.0) * 1000.0);

    sprintf(buf, "1. Servo Angle is: %d , DC: %7.2f\r\n", USART_angle, ((tmp1 + 10.0) * 100.0));
    USART_PutString(buf);
}
/*
void servo_controller(uint16_t  srv1,uint16_t srv2,uint16_t srv3,uint16_t srv4){

angle_convert_dutycycle(srv1);
TIM2->CCR1=dc;
angle_convert_dutycycle(srv2);
TIM2->CCR2=dc;
angle_convert_dutycycle(srv3);
TIM2->CCR3=dc;
angle_convert_dutycycle(srv4);
TIM2->CCR4=dc;
}*/
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);
}

yldzelektronik

kaynak kod eklemenizde yarar var. isr rutinlerine bakmak bakmak gerek. kesme içinde eğer flag silmiyorsanız sürekli kesmede kalıyor olabilir.
bir de nasıl gönderiyorsunuz? uart ile mi?
Kişinin başına gelen hayır Allah'tandır. Kişinin başına gelen şer nefsindendir. Nefislerimizle kendimize zulüm ediyoruz.

robikod

Alıntı yapılan: yldzelektronik - 23 Ağustos 2017, 17:02:16
kaynak kod eklemenizde yarar var. isr rutinlerine bakmak bakmak gerek. kesme içinde eğer flag silmiyorsanız sürekli kesmede kalıyor olabilir.
bir de nasıl gönderiyorsunuz? uart ile mi?
Kodları ekledim. Evet Uart ile

yldzelektronik

Çok detaylı bakmadım.Ama gözüme çarpanlar;

       
  • Float olan bir sayıyı f ile belirtin.Aksi halde bildiğim kadarıyla derleyici bunu double olarak ele alacak. 10.23f float olmasını garantiler.
  • angle_convert_dutycyle içindeki buf dizisinin boyu yetersiz gibi.Eşikte dolaşıyor. Biraz büyütün bence. memory leak oluşturabilir.
Bunların sorunun kaynağı olduğunu söylemiyorum. Ama dizi boyutu faktör olabilir.
Debug yapıp denediniz mi?
Kişinin başına gelen hayır Allah'tandır. Kişinin başına gelen şer nefsindendir. Nefislerimizle kendimize zulüm ediyoruz.

robikod

Alıntı yapılan: yldzelektronik - 23 Ağustos 2017, 17:33:13
Çok detaylı bakmadım.Ama gözüme çarpanlar;

       
  • Float olan bir sayıyı f ile belirtin.Aksi halde bildiğim kadarıyla derleyici bunu double olarak ele alacak. 10.23f float olmasını garantiler.
  • angle_convert_dutycyle içindeki buf dizisinin boyu yetersiz gibi.Eşikte dolaşıyor. Biraz büyütün bence. memory leak oluşturabilir.
Bunların sorunun kaynağı olduğunu söylemiyorum. Ama dizi boyutu faktör olabilir.
Debug yapıp denediniz mi?
Soylediginiz kisimlari duzelttim. Sorun cozulmedi ama en azindan baska bir yanlisim duzeldi. Kesme kisminda nasil bir sey yapmaliyim?

Klein

Kesme içerisinde döngü ile string göndermeye çalışıyorsunuz.
9 kusurlu hareketten biri. Mümkünse yapmayın. illa kesme içerisinde yapmak istiyorsanız DMA kullanmayı deneyin. 
Muhtemelen "Override Error (ORE)" bayrağı çekiliyor.  Kontrol edin.

robikod

Alıntı yapılan: Klein - 23 Ağustos 2017, 18:12:29
Kesme içerisinde döngü ile string göndermeye çalışıyorsunuz.
9 kusurlu hareketten biri. Mümkünse yapmayın. illa kesme içerisinde yapmak istiyorsanız DMA kullanmayı deneyin. 
Muhtemelen "Override Error (ORE)" bayrağı çekiliyor.  Kontrol edin.
Peki nasıl yapmalıyım ? Yeni başladığım için konuya pek hakim değilim yardımcı olursanız sevinirim

Klein

Rx kesmesi geldiğinde  okuduğunuz değeri bir yere kaydedip çıkacaksınız.
Main döngüsü içerisinde o değerin gelip gelmediğini kontrol edip geldiyse, ona göre işlem yapacaksınız.

örnek:
char Buf[];
int Count;

void RxKesmesi()
{
    Buf[count] = PortOku();
    Count++;
}

int main(void)
{
while(1){

   if(Count)
  {
       elinizdeki veri ile ne yapacaksanız buraya yazın.
       count = 0; 
  }
}
}


robikod

Alıntı yapılan: Klein - 24 Ağustos 2017, 10:06:16
Rx kesmesi geldiğinde  okuduğunuz değeri bir yere kaydedip çıkacaksınız.
Main döngüsü içerisinde o değerin gelip gelmediğini kontrol edip geldiyse, ona göre işlem yapacaksınız.

örnek:
char Buf[];
int Count;

void RxKesmesi()
{
    Buf[count] = PortOku();
    Count++;
}

int main(void)
{
while(1){

   if(Count)
  {
       elinizdeki veri ile ne yapacaksanız buraya yazın.
       count = 0; 
  }
}
}


Bufferdan gelen veriyi kullanacağım, ama sorum şu ki count değerini sürekli artırdığımızda gelen verinin dizisinn eleman sayısını artır mıyor muyz ?

Klein

Artırıyoruz.
Dğer türlü , siz gönderme işlemi yaparken peş peşe iki veri gelirse,  sadece son geleni bilirsiniz.
Bu şekilde Count değerine göre kaç veri geldiğini bilip, ona göre  aldığınız tüm değerleri işleyebilirsiniz.


robikod

if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
    {
        static uint8_t cnt = 0;
        char rx_data = USART_ReceiveData(USART1);
        if ((rx_data != '\n') && (cnt < MAX_STRLEN))
        { //rx_data boş karakter değil ve maximum karakter sayısı aşılması ise
            data[cnt] = rx_data;
            cnt++;
        }
        else
        { // boş karakter gelmemiş ve maksimum karakter kullanılmışsa
            cnt = 0;
        }

        // USART_ClearITPendingBit(USART1, USART_IT_RXNE);
    }
}


Kesme olan kısmı bu şekilde değiştirdim şimdi.
Burada gelen veriyi bir diziye atıyorum, ama aşağıda gelen bu dizi yani mesela 180 sayısı bir dizi olarak alınıyor işlem yapmak için inte çevirmem lazım nasıl yapabilirim bunu peki ?

Klein

#include "string.h"

int a = atoi(Str);

robikod

atoi'yi denedim olmadı bende şu şekilde yapmayı denedim  seri portan bir geri dönüş yok
#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;
static unsigned int dc;
#define MAX_STRLEN 3
volatile char data[MAX_STRLEN + 1];
char Usart_data;

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();
        //Delay(500);
    }
}
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
    //    char data = USART_ReceiveData(USART1); //receive a char
    //                                            // char data = USART_ReceiveData(USART1); //receive a char
    //     if (data == '\r' || data == '\n')
    //     {
    //         if (rx_index != 0)
    //         {
    //             memcpy((void *)line_buffer, rx_buffer, rx_index);
    //             line_buffer[rx_index] = 0;
    //             line_valid = 1;
    //             data = (unsigned int)USART_angle;
    //             rx_index = 0;
    //             USART_PutString("data geldi");
    //         }
    //     }
    //     else
    //     {
    //         if (rx_index == LINEMAX)
    //             rx_index = 0;

    //         rx_buffer[rx_index++] = data;
    //     }

    /*
*/
    if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
    {
        static uint8_t cnt = 0;
        char rx_data = USART_ReceiveData(USART1);
        if ((rx_data != '\n') && (cnt < MAX_STRLEN))
        { //rx_data boş karakter değil ve maximum karakter sayısı aşılması ise
            data[cnt] = rx_data;
            cnt++;
        }
        else
        { // boş karakter gelmemiş ve maksimum karakter kullanılmışsa
            Usart_data = data[cnt];
            USART_PutString(Usart_data);
            cnt = 0;
        }

        // 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;
    angle_convert_dutycyle();
    TIM2->CCR1 = dc;
}
void angle_convert_dutycyle(void)

{

    Usart_data = (unsigned int)USART_angle;
    char buf[100];
    float tmp1 = ((float)USART_angle / 180.0f);
    dc = ((tmp1 + 1.0f) * 1000.0f);

    sprintf(buf, "1. Servo Angle is: %d , DC: %7.2f\r\n", USART_angle, ((tmp1 + 10.0f) * 100.0f));
    USART_PutString(buf);
}
/*
void servo_controller(uint16_t  srv1,uint16_t srv2,uint16_t srv3,uint16_t srv4){

angle_convert_dutycycle(srv1);
TIM2->CCR1=dc;
angle_convert_dutycycle(srv2);
TIM2->CCR2=dc;
angle_convert_dutycycle(srv3);
TIM2->CCR3=dc;
angle_convert_dutycycle(srv4);
TIM2->CCR4=dc;
}*/
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);
}