Picproje Elektronik Sitesi

PICPROJE PROGRAMLAMA DERSLERİ => STM32 Örnekleri => Konuyu başlatan: seyityildirim - 20 Aralık 2016, 15:40:50

Başlık: Android Üzerinden Dc Motor Hız ve Yön Kontrolü (STM32F4 Discovery)
Gönderen: seyityildirim - 20 Aralık 2016, 15:40:50
Kullanılan malzemeler

Stm32f4 Discovery kartı
HC-05 Bluetooth modül
L298N motor sürücü
12 V'luk batarya
Android destekli bir telefon
Bağlantı kabloları


Bağlantılar

Bluetooth            Discovery

Rx                           Tx  (PB6)

Tx                           Rx  (PB7)

GND                      GND

VCC                       3.3 V

L298N                 Discovery

IN1                        PD12

IN2                       PD13



L298N OUT1 uçlarına DC motor takılır. 12V luk bataryanın uçları da L298N in 12V ve GND uçlarına takılır. Aynı GND ucu Discovery GND si ile birleştirilmelidir.

Keil'de yazılan kodlar aşağıdadır. Anlamadığınız yerler olursa cevaplamaya çalışırım.



#include "stm32f4xx.h" // Device header
#include "stm32f4xx_conf.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>


#define peryod 8399
#define MAX_STRLEN 12 // this is the maximum string length of our string in characters

char received_string[MAX_STRLEN+1]; // this will hold the recieved string
int veri;

uint16_t PWM_Duty = 0;
uint16_t PWM_Freq = 10000;

// Funtion Prototypes

void PWM_SetDutyCycle(TIM_TypeDef* TIMx, uint8_t Duty, uint8_t OCx);
void init_USART1(uint32_t baudrate);
void USART_puts(USART_TypeDef* USARTx, volatile char *s);
void USART1_IRQHandler(void);
void PWM_Config(void);

int main()
{
// Enable HSE clock
RCC_HSEConfig(RCC_HSE_ON);
// Wait for clock to stabilize
while (!RCC_WaitForHSEStartUp());

init_USART1(9600); // initialize USART1 @ 38400 baud
PWM_Config();
while(1);
}

void init_USART1(uint32_t baudrate)
{

GPIO_InitTypeDef GPIO_InitStruct; // TX ve RX olarak kullanacagimiz GPIO pinleri için
USART_InitTypeDef USART_InitStruct; // USART1 için
NVIC_InitTypeDef NVIC_InitStructure; // Kesmeleri ayarlamak için

/* USART1 için APB2 clock u aktif edilir
* sadece USART1 ve USART6 APB2 ye baglidir.
* diger USART lar APB1 clock hattina baglidir
*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

/* USART1 tarafindan TX için PB6 pini, RX için PB7 pini kullanilacak
* Bu pinlerin bulundugu GPIO hattinin clock u aktif edilir.
*/
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);

/* This sequence sets up the TX and RX pins
* so they work correctly with the USART1 peripheral
*/
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; // Pin 6 (TX) ve Pin7 (RX) olarak kullanilacak
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; // Bu pinler alternetif fonksiyon olarak tanimlandi ki USART buraya ulasabilsin
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; // IO nin hizini belirler ve baud rate ile alakasi yoktur
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; // Çikis Push-pull olarak ayarlandi
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; // Pull-up direnci aktif edildi.
GPIO_Init(GPIOB, &GPIO_InitStruct);

/* RX ve TX pimleri simdi AF'ye baglidir, böylece USART1 pinlerin kontrolünü devralabilir
*/
GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_USART1); //
GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_USART1);

/* USART_InitStruct USART1'in özelliklerini tanimlamak için kullanilacak
*/
USART_InitStruct.USART_BaudRate = baudrate;
USART_InitStruct.USART_WordLength = USART_WordLength_8b;
USART_InitStruct.USART_StopBits = USART_StopBits_1;
USART_InitStruct.USART_Parity = USART_Parity_No;
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
USART_Init(USART1, &USART_InitStruct);


/* Here the USART1 receive interrupt is enabled
* and the interrupt controller is configured
* to jump to the USART1_IRQHandler() function
* if the USART1 receive interrupt occurs
*/
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); // USART1 gelen veri kesmesi aktif edilir

NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; // USART1 kesmesi ayarlancak.
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;//
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // the USART1 interrupts are globally enabled
NVIC_Init(&NVIC_InitStructure);

USART_Cmd(USART1, ENABLE); // sonuç olarak USART1 donanimi aktif edildi
}

void USART1_IRQHandler(void)
{
// check if the USART1 receive interrupt flag was set
if( USART_GetITStatus(USART1, USART_IT_RXNE) )
{
static uint8_t cnt = 0; // this counter is used to determine the string length
char t = USART1->DR; // the character from the USART1 data register is saved in t

/* check if the received character is not the LF character (used to determine end of string)
* or the if the maximum string length has been been reached
*/
if( (t != '\n') && (cnt < MAX_STRLEN) ){
received_string[cnt] = t;
cnt++;
}

else{ // otherwise reset the character counter and print the received string
cnt = 0;

}
cnt=0;
///////////////////////////////////////////////////////////////////////
veri=received_string[0];
if (veri=='a')
{
PWM_SetDutyCycle(TIM4,0,1);
PWM_SetDutyCycle(TIM4,0,2);
}
else if (veri=='b')
{
PWM_SetDutyCycle(TIM4,25,1);
PWM_SetDutyCycle(TIM4,0,2);
}
else if (veri=='c')
{
PWM_SetDutyCycle(TIM4,50,1);
PWM_SetDutyCycle(TIM4,0,2);
}
else if (veri=='d')
{
PWM_SetDutyCycle(TIM4,75,1);
PWM_SetDutyCycle(TIM4,0,2);
}
else if (veri=='e')
{
PWM_SetDutyCycle(TIM4,100,1);
PWM_SetDutyCycle(TIM4,0,2);
}
else if (veri=='f')
{
PWM_SetDutyCycle(TIM4,0,1);
PWM_SetDutyCycle(TIM4,0,2);
}
else if (veri=='g')
{
PWM_SetDutyCycle(TIM4,0,1);
PWM_SetDutyCycle(TIM4,25,2);
}
else if (veri=='h')
{
PWM_SetDutyCycle(TIM4,0,1);
PWM_SetDutyCycle(TIM4,50,2);
}
else if (veri=='k')
{
PWM_SetDutyCycle(TIM4,0,1);
PWM_SetDutyCycle(TIM4,75,2);
}
else if (veri=='l')
{
PWM_SetDutyCycle(TIM4,0,1);
PWM_SetDutyCycle(TIM4,100,2);
}

}
USART_ClearITPendingBit(USART1, USART_IT_RXNE);
}
void PWM_SetDutyCycle(TIM_TypeDef* TIMx, uint8_t Duty, uint8_t OCx)
{
switch(OCx)
{
case 1: TIMx->CCR1 = (Duty * peryod) / 100; break;
case 2: TIMx->CCR2 = (Duty * peryod) / 100; break;
case 3: TIMx->CCR3 = (Duty * peryod) / 100; break;
case 4: TIMx->CCR4 = (Duty * peryod) / 100; break;
}
}

void PWM_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_BaseStruct;
TIM_OCInitTypeDef TIM_OCStruct;


/* Clock for GPIOD */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
/* Enable clock for TIM4 */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);

/* Alternating functions for pins */
GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_TIM4);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource13, GPIO_AF_TIM4);

TIM_BaseStruct.TIM_Prescaler = 0;
TIM_BaseStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_BaseStruct.TIM_Period = peryod; /* 10kHz PWM */
TIM_BaseStruct.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_BaseStruct.TIM_RepetitionCounter = 0;

TIM_TimeBaseInit(TIM4, &TIM_BaseStruct);
/* Start count on TIM4 */
TIM_Cmd(TIM4, ENABLE);

TIM_OCStruct.TIM_OCMode = TIM_OCMode_PWM2;
TIM_OCStruct.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCStruct.TIM_OCPolarity = TIM_OCPolarity_Low;
TIM_OCStruct.TIM_Pulse = 0;

TIM_OC1Init(TIM4, &TIM_OCStruct);
TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable);

TIM_OCStruct.TIM_Pulse =0;
TIM_OC2Init(TIM4, &TIM_OCStruct);
TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable);
}
A



App inventor programında oluşturulan Android arayüz için kod blokları ve videosu için

https://artibesvolt.wordpress.com/2016/12/20/android-uzerinden-dc-motor-hiz-ve-yon-kontrolu-stm32f4-discovery/

Başlık: Ynt: Android Üzerinden Dc Motor Hız ve Yön Kontrolü (STM32F4 Discovery)
Gönderen: Zoroaster - 20 Aralık 2016, 16:22:25
Hoş olmuş.

Kafamdaki pek çok soruya da cevap geldi.
Başlık: Ynt: Android Üzerinden Dc Motor Hız ve Yön Kontrolü (STM32F4 Discovery)
Gönderen: muhendisbey - 20 Aralık 2016, 20:20:31
Burada motordan geri besleme göremedim. RPM değeri motorun satıcısından alınmış gibi geldi. Hall effect ve mini mıknatıs iş görebilir. Yada yarıklı metal disk (örneğin gazoz kapağı)+indüktif sensör. Onun dışında birçok arkadaşın işine yarayacak, android-Bluetooth UART-stm32f4-pwm çözümü olmuş. Tebrikler.
Başlık: Ynt: Android Üzerinden Dc Motor Hız ve Yön Kontrolü (STM32F4 Discovery)
Gönderen: seyityildirim - 20 Aralık 2016, 21:09:28
Alıntı yapılan: muhendisbey - 20 Aralık 2016, 20:20:31
Burada motordan geri besleme göremedim. RPM değeri motorun satıcısından alınmış gibi geldi. Hall effect ve mini mıknatıs iş görebilir. Yada yarıklı metal disk (örneğin gazoz kapağı)+indüktif sensör. Onun dışında birçok arkadaşın işine yarayacak, android-Bluetooth UART-stm32f4-pwm çözümü olmuş. Tebrikler.

Belirtmeyi unutmuşum hocam kullanılan motor 2500 rpm. Geri besleme kullanılmadan yapıldı dediğiniz gibi.