使用STM32CubeMx搭建平衡小车代码框架Word文档下载推荐.docx
《使用STM32CubeMx搭建平衡小车代码框架Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《使用STM32CubeMx搭建平衡小车代码框架Word文档下载推荐.docx(15页珍藏版)》请在冰豆网上搜索。
其中,制动为电机锁死,而停止为电机停转;
2.项目搭建:
Step1.打开STM32CubeMX,单击“NewProject”,选择芯片型号,STM32F103C8Tx。
Step2.配置Debug,根据实际选择
Step3.配置外部时钟信号
Step4.配置TIM2(PWM发生器)
Step5.配置模拟IIC引脚
Step6.配置电机控制引脚
Step7.配置TIM3(用作微妙延时时钟),CubeMx生成的代码中不包含微妙延时,此部分用于实现模拟IIC的微妙延时
Step8.配置USART1(用于串口调试)
Step9.时钟配置
注:
关于输入时钟一定要按实际晶振频率填写,否则会造成时序混乱;
Step10.TIM2参数配置(10KHz)
Step11.配置TIM3(微妙延时定时器)
定时器时钟频率的计算:
定时器时钟频率:
72MHz
72MHz/(PSC+1)/ARR=72/(71+1)/1=1Mhz=1us;
Step12.配置GPIO口
Step13.生成项目配置
至此,关于平衡小车的软件框架配置已全部完成,点击项目生成,进入MDK编写代码:
代码片段1:
微妙函数的实现
#include"
delay.h"
tim.h"
voidDelay_us(uint32_tus){
uint16_tcounter=us&
0xffff;
HAL_TIM_Base_Start(&
htim3);
__HAL_TIM_SetCounter(&
htim3,counter);
while(counter>
1){
counter=__HAL_TIM_GetCounter(&
}
HAL_TIM_Base_Stop(&
}
voidDelay_ms(uint32_tms){
Delay_us(1000*ms);
代码片段2模拟IIC:
#defineHIGH1
#defineLOW0
#defineSDA_IN(){GPIOB->
CRL&
=0x0FFFFFFF;
GPIOB->
CRL|=0x40000000;
#defineSDA_OUT(){GPIOB->
CRL|=0x10000000;
}
#defineIIC_SCL(n)(n?
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_SET):
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_RESET))//SCL
#defineIIC_SDA(n)(n?
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_SET):
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_RESET))//SDA
#defineREAD_SDAHAL_GPIO_ReadPin(GPIOB,GPIO_PIN_7)
voidIIC_Init(void)
{
IIC_SDA(HIGH);
IIC_SCL(HIGH);
voidIIC_Start(void)
SDA_OUT();
Delay_us(4);
IIC_SDA(LOW);
IIC_SCL(LOW);
}
voidIIC_Stop(void)
IIC_SDA(LOW);
Delay_us(4);
uint8_tIIC_Wait_Ack(void)
uint8_tucErrTime=0;
SDA_IN();
Delay_us
(1);
while(READ_SDA)
{
ucErrTime++;
if(ucErrTime>
250)
{
IIC_Stop();
return1;
}
return0;
voidIIC_Ack(void)
Delay_us
(2);
voidIIC_NAck(void)
}
voidIIC_Send_Byte(uint8_ttxd)
{
uint8_tt;
for(t=0;
t<
8;
t++)
{
IIC_SDA((txd&
0x80)>
>
7);
txd<
<
=1;
Delay_us
(2);
IIC_SCL(HIGH);
IIC_SCL(LOW);
}
uint8_tIIC_Read_Byte(uint8_tack)
uint8_ti,receive=0;
for(i=0;
i<
i++)
IIC_SCL(LOW);
Delay_us
(2);
IIC_SCL(HIGH);
receive<
if(READ_SDA)receive++;
Delay_us
(1);
}
if(!
ack)IIC_NAck();
elseIIC_Ack();
returnreceive;
代码片段3PID控制器
//50
#defineP_DATA70.0
//25.5
#defineI_DATA46.7
//1.25
#defineD_DATA0
//以上三值需根据实际调整参数
typedefstructPID{
intSetPoint;
doubleProportion;
doubleIntegral;
doubleDerivative;
intLastError;
intPrevError;
}PID;
voidIncPIDInit(PID*sptr)
sptr->
LastError=0;
PrevError=0;
Proportion=P_DATA;
Integral=I_DATA;
Derivative=D_DATA;
SetPoint=0;
intIncPIDCalc(PID*sptr,intnextPoint)
intiError,iIncpid;
iError=sptr->
SetPoint-nextPoint;
iIncpid=sptr->
Proportion*iError-\
sptr->
Integral*sptr->
LastError+\
Derivative*sptr->
PrevError;
PrevError=sptr->
LastError;
LastError=iError;
returniIncpid;
代码片段4PWM发生器
HAL_GPIO_WritePin(Left_Dir0_GPIO_Port,Left_Dir0_Pin,GPIO_PIN_SET);
HAL_GPIO_WritePin(Left_Dir1_GPIO_Port,Left_Dir1_Pin,GPIO_PIN_RESET);
HAL_GPIO_WritePin(Right_Dir0_GPIO_Port,Right_Dir0_Pin,GPIO_PIN_SET);
HAL_GPIO_WritePin(Right_Dir1_GPIO_Port,Right_Dir1_Pin,GPIO_PIN_RESET);
__HAL_TIM_SetCompare(&
htim2,TIM_CHANNEL_1,0);
htim2,TIM_CHANNEL_2,0);
HAL_TIM_PWM_Start(&
htim2,TIM_CHANNEL_1);
htim2,TIM_CHANNEL_2);
更改PWM的占空比使用
HAL_TIM_SetCompare(&
htim2,TIM_CHANNEL_1,val)函数即可,其占空比的为用户设定的值除以ARR的值,即val/99+1;
即val直接等于占空比;
后记:
关于DMP的代码直接参考正点原子的MPU6050的代码即可;