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);
}
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?
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
Ç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?
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?
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.
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
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;
}
}
}
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 ?
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.
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 ?
#include "string.h"
int a = atoi(Str);
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);
}