使用STM32CubeMx搭建平衡小车代码框架.docx

上传人:b****2 文档编号:2904511 上传时间:2023-05-05 格式:DOCX 页数:15 大小:431.50KB
下载 相关 举报
使用STM32CubeMx搭建平衡小车代码框架.docx_第1页
第1页 / 共15页
使用STM32CubeMx搭建平衡小车代码框架.docx_第2页
第2页 / 共15页
使用STM32CubeMx搭建平衡小车代码框架.docx_第3页
第3页 / 共15页
使用STM32CubeMx搭建平衡小车代码框架.docx_第4页
第4页 / 共15页
使用STM32CubeMx搭建平衡小车代码框架.docx_第5页
第5页 / 共15页
使用STM32CubeMx搭建平衡小车代码框架.docx_第6页
第6页 / 共15页
使用STM32CubeMx搭建平衡小车代码框架.docx_第7页
第7页 / 共15页
使用STM32CubeMx搭建平衡小车代码框架.docx_第8页
第8页 / 共15页
使用STM32CubeMx搭建平衡小车代码框架.docx_第9页
第9页 / 共15页
使用STM32CubeMx搭建平衡小车代码框架.docx_第10页
第10页 / 共15页
使用STM32CubeMx搭建平衡小车代码框架.docx_第11页
第11页 / 共15页
使用STM32CubeMx搭建平衡小车代码框架.docx_第12页
第12页 / 共15页
使用STM32CubeMx搭建平衡小车代码框架.docx_第13页
第13页 / 共15页
使用STM32CubeMx搭建平衡小车代码框架.docx_第14页
第14页 / 共15页
使用STM32CubeMx搭建平衡小车代码框架.docx_第15页
第15页 / 共15页
亲,该文档总共15页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

使用STM32CubeMx搭建平衡小车代码框架.docx

《使用STM32CubeMx搭建平衡小车代码框架.docx》由会员分享,可在线阅读,更多相关《使用STM32CubeMx搭建平衡小车代码框架.docx(15页珍藏版)》请在冰点文库上搜索。

使用STM32CubeMx搭建平衡小车代码框架.docx

使用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的代码即可;

如有侵权请联系告知删除,感谢你们的配合!

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 初中教育 > 语文

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2