Altium Designer画的二轮自平衡小车电路原理图和PCB图如下:(51hei附件中可下载工程文件)
上层和中层亚克力3D图及CAD图
安卓蓝牙遥控器APK及源码
整体BOM表格
02 - 姿态解算MCU源代码(STM32F103C8T6)
- /* main.c file
- 编写者:lisn3188
- 编译环境:MDK-Lite Version: 4.23
- 测试: 本程序已在第七实验室的mini IMU上完成测试
- 功能:
- 1.初始化各个传感器,
- 2.运行姿态解算和高度测量
- 3.将解算的姿态和各个传感器的输出上传到 MiniIMU AHRS 测试软件
- 4.响应 PC发送的命令
- ------------------------------------*/
- /*----------------------------------------------------------------
- 修改备忘:(2014.08.28 by flotox)
- 1/去掉气压传感器数据接口
- 2/保持帧格式
- 3/数据输出频率调整为20hz
- 4/调整机头方向
- 5/保留陀螺仪标零偏
- 6/去掉UART1数据输出
- 7/只输出姿态数据结算帧
- 8/在数据融合时去掉磁力计的影响
- 9/上电数据即可用,不用等待
- ----------------------------------------------------------------*/
- #include "common.h" //包含所有的驱动 头文件
- //上传数据的状态机
- #define REIMU 0x01 //上传解算的姿态数据
- #define REMOV 0x02 //上传传感器的输出
- #define REHMC 0x03 //上传磁力计的标定值
- #define Upload_Speed 100 //数据上传速度 单位 Hz
- #define upload_time (1000000/Upload_Speed) //计算上传的时间。单位为us
- int16_t ax, ay, az;
- int16_t gx, gy, gz;
- int16_t hx, hy, hz;
- int32_t Temperature = 0, Pressure = 0, Altitude = 0;
- uint32_t system_micrsecond;
- int16_t hmcvalue[3];
- u8 state= REIMU; //发送特定帧 的状态机
- /**************************实现函数********************************************
- *函数原型: int main(void)
- *功 能: 主程序
- *******************************************************************************/
- int main(void)
- {
- int16_t Math_hz=0;
- unsigned char PC_comm; //PC 命令关键字节
- float ypr[3]; // yaw pitch roll
- /* 配置系统时钟为72M 使用外部8M晶体+PLL*/
- //SystemInit();
- delay_init(72); //延时初始化
- Initial_LED_GPIO(); //初始化STM32-SDK板子上的LED接口
- Initial_PWMLED();
- Initial_UART2(115200L);
- load_config(); //从flash中读取配置信息 -->eeprom.c
- IIC_Init(); //初始化I2C接口
- delay_ms(300); //等待器件上电
- //UART1_Put_String("Initialize...\r\n");
- IMU_init(); //初始化IMU和传感器
- system_micrsecond=micros();
- while(1){ //主循环
-
- //delay_ms(1); //延时,不要算那么快。
- IMU_getYawPitchRoll(ypr); //姿态更新
- Math_hz++; //解算次数 ++
- //-------------上位机------------------------------
- //是否到了更新 上位机的时间了?
- if((micros()-system_micrsecond)>upload_time){
- switch(state){
- case REIMU:
- UART2_ReportIMU((int16_t)(ypr[0]*10.0),(int16_t)(ypr[1]*10.0),
- (int16_t)(ypr[2]*10.0),Altitude/10,Temperature,Pressure/10,Math_hz*Upload_Speed);
- Math_hz=0;
- // state = REMOV; //更改状态。
- break;
- case REMOV:
- MPU6050_getlastMotion6(&ax, &ay, &az, &gx, &gy, &gz);
- HMC58X3_getlastValues(&hx,&hy,&hz);
- UART2_ReportMotion(ax,ay,az,gx,gy,gz,hx,hy,hz);
- state = REIMU;
- if(HMC5883_calib)state = REHMC; //需要发送当前磁力计标定值
- break;
- default:
- UART2_ReportHMC(HMC5883_maxx,HMC5883_maxy,HMC5883_maxz,
- HMC5883_minx,HMC5883_miny,HMC5883_minz,0);//发送标定值
- state = REIMU;
- break;
- }//switch(state)
- system_micrsecond=micros(); //取系统时间 单位 us
- LED_Change(); //LED1改变亮度
- }
- //--------------------------------------------------
- //处理PC发送来的命令
- if((PC_comm=UART2_CommandRoute())!=0xff)
- {
- switch(PC_comm){ //检查命令标识
- case Gyro_init: MPU6050_InitGyro_Offset(); break; //读取陀螺仪零偏
- case High_init: break; //气压高度 清零
- case HMC_calib_begin: HMC5883L_Start_Calib(); break; //开始磁力计标定
- case HMC_calib: HMC5883L_Save_Calib(); break; //保存磁力计标定
- }
- }// 处理PC 发送的命令
- }//主循环 while(1) 结束
- } //main
- //------------------End of File----------------------------
复制代码
01 - 运动控制MCU源代码(STM32F103RCT6)
- /**---------------------------------------------------------------
- 项目:两轮自平衡小车(Two-Wheels Auto-Balancing Vechile)
- 版本:v1.0.0
- 文件: Balancing.c
- 功能:自平衡计算
- 作者:flotox@yeah.net
- 日期:2014.9.5
- 更新:2014.9.5
- ----------------------------------------------------------------*/
- #include "stm32f10x.h"
- #include "GlobalVars.h"
- #include "MotorDriver.h"
- // float Temp[200] = {0};
- // uint32_t Temp_i = 0;
- /**
- * @brief 自平衡计算外设初始化
- * @param none
- * @retval none
- */
- void Balancing_Init(void){
-
- GPIO_InitTypeDef GPIO_InitStructure;
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
- NVIC_InitTypeDef NVIC_InitStructure;
-
- /*开启GPIOC外设时钟*/
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
- /*开启TIM4外设时钟*/
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
-
- /*配置PC.15端口为Out_PP模式*/
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_Init(GPIOC, &GPIO_InitStructure);
-
- /*TIM4 NVIC设置*/
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //2 bits for pre-emption priority 2 bits for subpriority
-
- NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //指定抢占式优先级别,可取0~3
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //指定响应式优先级别,可取0~3
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);
-
- TIM_DeInit(TIM4);
-
- /*定时器基本配置*/
- TIM_TimeBaseStructure.TIM_Prescaler = 0; //时钟预分频数0,TIM4的时钟计数频率为72MHz
- TIM_TimeBaseStructure.TIM_Period = 20 - 1; //自动重装载寄存器数20,10ms溢出1次
- TIM_TimeBaseStructure.TIM_ClockDivision = 0; //采样分频
- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数
- TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
-
- TIM_PrescalerConfig(TIM4, 0x8c9f, TIM_PSCReloadMode_Immediate); //时钟分频系数36000,定时器时钟为2KHz
- TIM_ARRPreloadConfig(TIM4, DISABLE); //禁止ARR预装载缓冲器
- TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE); //使能Update中断
-
- TIM_Cmd(TIM4, ENABLE); //开启时钟
- }
- /**
- * @brief 自平衡计算循环子程序(10ms被调用一次)
- * @param none
- * @retval none
- */
- void Balancing_Loop(void){
- uiCount_Led++;
-
- /*Led闪烁*/
- if(uiCount_Led >= 40){
-
- uiCount_Led = 0;
- GPIO_WriteBit(GPIOC,GPIO_Pin_15,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOC,GPIO_Pin_15)));
- }
-
- switch(iMotion_Type){
- case MOTION_TYPE_NONE:
-
- fTarget_Speed = 0;
- fTarget_Turn = 0;
- break;
-
- case MOTION_TYPE_FORWARDS:
-
- fTarget_Speed = -150;
- fTarget_Turn = 0;
- break;
-
- case MOTION_TYPE_BACKWARDS:
-
- fTarget_Speed = 150; //150
- fTarget_Turn = 0;
- break;
-
- case MOTION_TYPE_TURN_LEFT:
-
- fTarget_Speed = 0;
- fTarget_Turn = -210;
- break;
-
- case MOTION_TYPE_TURN_RIGHT:
-
- fTarget_Speed = 0;
- fTarget_Turn = 210;
- break;
-
- case MOTION_TYPE_FORWARDS_TURN_LEFT:
-
- fTarget_Speed = -150;
- fTarget_Turn = -210;
- break;
-
- case MOTION_TYPE_FORWARDS_TURN_RIGHT:
-
- fTarget_Speed = -150;
- fTarget_Turn = 210;
- break;
-
- case MOTION_TYPE_BACKWARDS_TURN_LEFT:
-
- fTarget_Speed = 150;
- fTarget_Turn = -210;
- break;
-
- case MOTION_TYPE_BACKWARDS_TURN_RIGHT:
-
- fTarget_Speed = 150;
- fTarget_Turn = 210;
- break;
- }
-
- /*动作改变时增加中间的过度过程,过度过程为50ms*/
- if((iMotion_Type != iMotion_Type_Last) && (iCount_Motion_Type_Change == 0)){
-
- iCount_Motion_Type_Change = 10;
- iMotion_Type_Last = iMotion_Type;
- }
-
- if(iCount_Motion_Type_Change != 0){
-
- iCount_Motion_Type_Change --;
- fTarget_Speed = 0;
- fTarget_Turn = 0;
- }
-
- /*速度和位移一阶低通滤波*/
- fSpeed_Vechile = (iCount_L + iCount_R) * 0.5;
- fSpeed_Vechile_F = fSpeed_Vechile_F * 0.7 + fSpeed_Vechile * 0.3;
-
- /*累加求位移*/
- fPosition += fSpeed_Vechile_F;
- /*位移调节量*/
- fPosition += fTarget_Speed;
- /*位移限制,上下限待调节*/
- if(fPosition > 5000){ //5000
-
- fPosition = 5000;
- }
- else if(fPosition < -5000){
-
- fPosition = -5000;
- }
-
- /*左轮和右轮光栅脉冲计数器清零*/
- iCount_L = 0;
- iCount_R = 0;
-
- /*角度限制*/
- if( (fPitchAngle < 40.0) && (fPitchAngle > -40.0) ){
-
-
- /*俯仰角速度,单位deg/s,大于0则角速度方向向前,小于0则角速度方向向后*/
- fAngle_Vel = -(fPitchAngle - fPitchAngle_Last);
-
- /*保存此次俯仰角度*/
- fPitchAngle_Last = fPitchAngle;
-
- /*计算PWM输出控制量*/
- fPWM = (-fpid_angle) * fPitchAngle +
- fpid_angle_vel * fAngle_Vel +
- fpid_speed * fSpeed_Vechile_F +
- fPosition * fpid_position;
-
- /*旋转调节量*/
- fPWM_L = fPWM + fTarget_Turn;
- fPWM_R = fPWM - fTarget_Turn;
-
- /*左轮控制*/
- if(fPWM_L > 0){
-
- MotorDriver_L_Turn_Forward();
- }
- else{
-
- MotorDriver_L_Turn_Reverse();
- fPWM_L = -fPWM_L;
- }
-
- /*右轮控制*/
- if(fPWM_R > 0){
-
- MotorDriver_R_Turn_Forward();
- }
- else{
-
- MotorDriver_R_Turn_Reverse();
- fPWM_R = -fPWM_R;
- }
-
- /*加上死区电压*/
- fPWM_L += 40;
- fPWM_R += 10;
-
- /*限制PWM*/
- if(fPWM_L > 1000){
-
- fPWM_L = 1000;
- }
-
- if(fPWM_R > 1000){
-
- fPWM_R = 1000;
- }
-
- /*输出PWM控制量*/
- TIM_SetCompare2(TIM8, (uint16_t)fPWM_L); //左轮
- TIM_SetCompare2(TIM1, (uint16_t)fPWM_R); //右轮
- }
- /*倾角过大时的姿态数据不参与计算*/
- else{
-
- TIM_SetCompare2(TIM8, 0); //左轮
- TIM_SetCompare2(TIM1, 0); //右轮
- }
-
- }
复制代码
全部资料51hei下载地址:
二轮自平衡小车.rar
(14.78 MB, 下载次数: 59)
|