STM32藍牙控制循跡避障小車源代碼——1.電機驅動,變速
注意-所需模塊:
主控:STM32F103C8T6(F1系列板子均可以)

驅動芯片:L298N(1個)

接線:L298N:
A6–IN1
A7–IN2
B0–IN3
B1–IN4
ENA:5V
ENB:5V
代碼
所有的代碼都是直接從工程里面復制的,實測是沒有問題的,
1.電機控制:moter.c
參考文章: 基于STM32F103C8T6的循跡避障小車完整制作程序
這篇文章詳細講解了PWM調速原理以及定時器通道的選擇
-
我這里再簡單總結一下:
IN1,IN2控制電機原理:
首先我們將OUT1和OUT2分別接電機的兩極,這時我們控制單片機使輸入端IN1接入高電平,則相應的OUT1端也就變為高電平;將IN2接入低電平后相應的OUT2也就變為低電平,OUT1和OUT2間有了電位差,這樣電機就能轉起來了, -
PWM輸出到IN1~IN4四個端子,來實作調速,
開啟定時器3的4個通道
定時器3的通道1-4分別對應PA6, PA7, PB0, PB1,將這四個引腳分別接到 IN1-IN4,實作調速, -
呼叫函式:TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare1);
這個函式中的數字1代表的是TIMx的通道1,TIMx中的x可以取1-17但除了6,7,兩個引數 TIMx , Compare1,
Compare1是用于與TIMx比較的數,相當于TIMx的一個周期時間減去Compare1,
差值越小(Compare1值越大),輸出PWM的高電平時間越短,轉速越低,
#include "moter.h"
//注意:宣告不能出現在塊中的可執行陳述句之后!
//在main函式里直接呼叫TIM3_PWM_Init()這個函式就完成了引腳和定時器的初始化
//然后在后面直接用控制運動函式
//IN1-IN4分別接PA6,PA7,PB0,PB1
void TIM3_PWM_Init(void)
{
TIM_OCInitTypeDef TIM_OCInitStruct;
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
GPIO_InitTypeDef GPIO_InitStruct;
//使能定時器3時鐘,使能IO口時鐘GPIOA,GPIOB,開啟AFIO
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO,ENABLE);
//定時器3初始化
TIM_TimeBaseInitStruct.TIM_ClockDivision=0;
TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;
TIM_TimeBaseInitStruct.TIM_Period=899;
TIM_TimeBaseInitStruct.TIM_Prescaler=0;
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStruct);
//初始化埠復用的A6 A7 B0 B1
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_6|GPIO_Pin_7;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStruct);
//初始化并配置定時器3的4個通道
//通道1
TIM_OCInitStruct.TIM_OCMode=TIM_OCMode_PWM2;
TIM_OCInitStruct.TIM_OutputState=ENABLE;
TIM_OCInitStruct.TIM_OCPolarity=TIM_OCPolarity_High;
TIM_OCInitStruct.TIM_Pulse=900;
TIM_OC1Init(TIM3,&TIM_OCInitStruct);//初始化通道1
TIM_OC1PreloadConfig(TIM3,TIM_OCPreload_Enable);
//通道2
TIM_OCInitStruct.TIM_OCMode=TIM_OCMode_PWM2;
TIM_OCInitStruct.TIM_OutputState=ENABLE;
TIM_OCInitStruct.TIM_OCPolarity=TIM_OCPolarity_High;
TIM_OCInitStruct.TIM_Pulse=900;
TIM_OC2Init(TIM3,&TIM_OCInitStruct);//初始化通道2
TIM_OC2PreloadConfig(TIM3,TIM_OCPreload_Enable);
//通道3
TIM_OCInitStruct.TIM_OCMode=TIM_OCMode_PWM2;
TIM_OCInitStruct.TIM_OutputState=ENABLE;
TIM_OCInitStruct.TIM_OCPolarity=TIM_OCPolarity_High;
TIM_OCInitStruct.TIM_Pulse=900;
TIM_OC3Init(TIM3,&TIM_OCInitStruct);//初始化通道3
TIM_OC3PreloadConfig(TIM3,TIM_OCPreload_Enable);
//通道4
TIM_OCInitStruct.TIM_OCMode=TIM_OCMode_PWM2;
TIM_OCInitStruct.TIM_OutputState=ENABLE;
TIM_OCInitStruct.TIM_OCPolarity=TIM_OCPolarity_High;
TIM_OCInitStruct.TIM_Pulse=900;
TIM_OC4Init(TIM3,&TIM_OCInitStruct);//初始化通道4
TIM_OC4PreloadConfig(TIM3,TIM_OCPreload_Enable);
//使能定時器3
TIM_Cmd(TIM3,ENABLE);
}
//Compare1是用于與TIMx比較的數,相當于TIMx的一個周期時間減去Compare1,
//差值越小(Compare值越大),輸出PWM的高電平時間越短,轉速越低,
void Forward(int a)
{
TIM_SetCompare1(TIM3,a);//差值越大,速度越慢
TIM_SetCompare2(TIM3,900);
TIM_SetCompare3(TIM3,a);
TIM_SetCompare4(TIM3,900);
}
void Backward(int a)
{
TIM_SetCompare1(TIM3,900);
TIM_SetCompare2(TIM3,a);
TIM_SetCompare3(TIM3,900);
TIM_SetCompare4(TIM3,a);
}
void STOP()
{
TIM_SetCompare1(TIM3,900);
TIM_SetCompare2(TIM3,900);
TIM_SetCompare3(TIM3,900);
TIM_SetCompare4(TIM3,900);
}
void Turn_left(int a)
{
TIM_SetCompare1(TIM3,900);
TIM_SetCompare2(TIM3,a);
TIM_SetCompare3(TIM3,a);
TIM_SetCompare4(TIM3,900);
}
void Turn_right(int a)
{
TIM_SetCompare1(TIM3,a);
TIM_SetCompare2(TIM3,900);
TIM_SetCompare3(TIM3,900);
TIM_SetCompare4(TIM3,a);
}
void Big_Turn_left(int a)
{
TIM_SetCompare1(TIM3,900);
TIM_SetCompare2(TIM3,a);
TIM_SetCompare3(TIM3,a);
TIM_SetCompare4(TIM3,900);
}
void Big_Turn_right(int a)
{
TIM_SetCompare1(TIM3,a);
TIM_SetCompare2(TIM3,900);
TIM_SetCompare3(TIM3,900);
TIM_SetCompare4(TIM3,a);
}
- 在moter.c代碼中,我定義了小車的7種運動方式,引數a用來可用來調控速度,a取值在[0,900],我一般取[200,600],且a的值越大,電機轉動速度越慢(注意當a的值過大時,可能會驅動不了),
moter.h:
#ifndef __MOTER_H
#define __MOTER_H
#include "stm32f10x.h"
void TIM3_PWM_Init(void);
void Forward(int a);
void Backward(int a);
void Turn_left(int a);
void Turn_right(int a);
void Big_Turn_left(int a);
void Big_Turn_right(int a);
void STOP(void);
#endif
- 初始化函式
測驗
將上面兩個代碼寫進工程里,如果想要測驗代碼是否正確,電機接線是否接反了,可以在主函式里寫進以下代碼,
#include "stm32f10x.h"
#include "moter.h"
#include "delay.h"
int main(void)
{
delay_init(); //延時初始化
TIM3_PWM_Init(); //電機pwm TIM3
while(1)
{
Forward(500);//前進,也可以換成其他運動,如Turn_left(400);
//引數越大,電機轉速越慢
}
}
工程下載
https://download.csdn.net/download/www_haha__/64043160
下一節我會寫循跡模塊
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/382110.html
標籤:其他
上一篇:怎么做出可以賣的電路板
