使用STM32CubeMx搭建平衡小车代码框架.docx
- 文档编号:11932612
- 上传时间:2023-04-16
- 格式:DOCX
- 页数:15
- 大小:431.50KB
使用STM32CubeMx搭建平衡小车代码框架.docx
《使用STM32CubeMx搭建平衡小车代码框架.docx》由会员分享,可在线阅读,更多相关《使用STM32CubeMx搭建平衡小车代码框架.docx(15页珍藏版)》请在冰豆网上搜索。
使用STM32CubeMx搭建平衡小车代码框架
使用STM32CubeMx快速搭建平衡小车代码框架
硬件平台:
STM32CubeMx
HAL代码库:
STM32F1xx
项目平台:
MDK5.17A
1.项目总体框架如下:
MPU6050的数据读取采用软件模拟IIC,可使用MPU的DMP库直接生成角度值,减轻MCU计算负担;(DMP库资源详见,正点原子MPU6050资料)
电机驱动部分采用市面上常见的直流电机驱动,引脚分布如下:
PWMA,PWMB,A0,A1,B0,B1;
其中PWMA、PWMB为电机驱动信号;
A0、A1、B0、B1为电机方向控制信号,其控制电平如下:
A0A1电机
高高制动
高低正转
低高反转
低低停止
其中,制动为电机锁死,而停止为电机停转;
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"
#include"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(&htim3);
}
HAL_TIM_Base_Stop(&htim3);
}
voidDelay_ms(uint32_tms){
Delay_us(1000*ms);
}
代码片段2模拟IIC:
#defineHIGH1
#defineLOW0
#defineSDA_IN(){GPIOB->CRL&=0x0FFFFFFF;GPIOB->CRL|=0x40000000;}
#defineSDA_OUT(){GPIOB->CRL&=0x0FFFFFFF;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();
IIC_SDA(HIGH);
IIC_SCL(HIGH);
Delay_us(4);
IIC_SDA(LOW);
Delay_us(4);
IIC_SCL(LOW);
}
voidIIC_Stop(void)
{
SDA_OUT();
IIC_SCL(LOW);
IIC_SDA(LOW);
Delay_us(4);
IIC_SCL(HIGH);
IIC_SDA(HIGH);
Delay_us(4);
}
uint8_tIIC_Wait_Ack(void)
{
uint8_tucErrTime=0;
SDA_IN();
IIC_SDA(HIGH);Delay_us
(1);
IIC_SCL(HIGH);Delay_us
(1);
while(READ_SDA)
{
ucErrTime++;
if(ucErrTime>250)
{
IIC_Stop();
return1;
}
}
IIC_SCL(LOW);
return0;
}
voidIIC_Ack(void)
{
IIC_SCL(LOW);
SDA_OUT();
IIC_SDA(LOW);
Delay_us
(2);
IIC_SCL(HIGH);
Delay_us
(2);
IIC_SCL(LOW);
}
voidIIC_NAck(void)
{
IIC_SCL(LOW);
SDA_OUT();
IIC_SDA(HIGH);
Delay_us
(2);
IIC_SCL(HIGH);
Delay_us
(2);
IIC_SCL(LOW);
}
voidIIC_Send_Byte(uint8_ttxd)
{
uint8_tt;
SDA_OUT();
IIC_SCL(LOW);
for(t=0;t<8;t++)
{
IIC_SDA((txd&0x80)>>7);
txd<<=1;
Delay_us
(2);
IIC_SCL(HIGH);
Delay_us
(2);
IIC_SCL(LOW);
Delay_us
(2);
}
}
uint8_tIIC_Read_Byte(uint8_tack)
{
uint8_ti,receive=0;
SDA_IN();
for(i=0;i<8;i++)
{
IIC_SCL(LOW);
Delay_us
(2);
IIC_SCL(HIGH);
receive<<=1;
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;
sptr->PrevError=0;
sptr->Proportion=P_DATA;
sptr->Integral=I_DATA;
sptr->Derivative=D_DATA;
sptr->SetPoint=0;
}
intIncPIDCalc(PID*sptr,intnextPoint)
{
intiError,iIncpid;
iError=sptr->SetPoint-nextPoint;
iIncpid=sptr->Proportion*iError-\
sptr->Integral*sptr->LastError+\
sptr->Derivative*sptr->PrevError;
sptr->PrevError=sptr->LastError;
sptr->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);
__HAL_TIM_SetCompare(&htim2,TIM_CHANNEL_2,0);
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2);
注:
更改PWM的占空比使用
HAL_TIM_SetCompare(&htim2,TIM_CHANNEL_1,val)函数即可,其占空比的为用户设定的值除以ARR的值,即val/99+1;即val直接等于占空比;
后记:
关于DMP的代码直接参考正点原子的MPU6050的代码即可;
如有侵权请联系告知删除,感谢你们的配合!
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 使用 STM32CubeMx 搭建 平衡 小车 代码 框架