找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4279|回复: 3
收起左侧

stm32F1+mpu6050平衡车源代码

[复制链接]
ID:472829 发表于 2019-1-25 14:31 | 显示全部楼层 |阅读模式
stm32F1 平衡车源代码,采用亚博智能小车拓展板,采用MPU6050  INT脚中断,本代码只有直立环,后续代码稍后上传

单片机源程序如下:
  1. #include "mpu6050.h"
  2. #include "sys.h"
  3. #include "delay.h"
  4. #include "usart.h"   

  5. //初始化MPU6050
  6. //返回值:0,成功
  7. //    其他,错误代码
  8. u8 MPU_Init(void)
  9. {
  10.         u8 res;
  11.   GPIO_InitTypeDef  GPIO_InitStructure;
  12.         
  13.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//使能AFIO时钟
  14.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//先使能外设IO PORTA时钟
  15.         
  16.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;         // 端口配置
  17.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;        //推挽输出
  18.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                 //IO口速度为50MHz
  19.   GPIO_Init(GPIOA, &GPIO_InitStructure);                                         //根据设定参数初始化GPIOA

  20.         GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);//禁止JTAG,从而PA15可以做普通IO使用,否则PA15不能做普通IO!!!
  21.         
  22.         MPU_AD0_CTRL=0;                        //控制MPU6050的AD0脚为低电平,从机地址为:0X68
  23.         
  24.         MPU_IIC_Init(); //初始化IIC总线
  25.         MPU_Write_Byte(MPU_PWR_MGMT1_REG,0X80);        //复位MPU6050
  26.   delay_ms(100);
  27.         MPU_Write_Byte(MPU_PWR_MGMT1_REG,0X00);        //唤醒MPU6050
  28.         MPU_Set_Gyro_Fsr(3);                                        //陀螺仪传感器,±2000dps
  29.         MPU_Set_Accel_Fsr(0);                                        //加速度传感器,±2g
  30.         MPU_Set_Rate(200);                                                //设置采样率50Hz
  31.         MPU_Write_Byte(MPU_INT_EN_REG,0X00);        //关闭所有中断
  32.         MPU_Write_Byte(MPU_USER_CTRL_REG,0X00);        //I2C主模式关闭
  33.         MPU_Write_Byte(MPU_FIFO_EN_REG,0X00);        //关闭FIFO
  34.         MPU_Write_Byte(MPU_INTBP_CFG_REG,0X80);//INT引脚低电平有效
  35.         res=MPU_Read_Byte(MPU_DEVICE_ID_REG);
  36.         if(res==MPU_ADDR)//器件ID正确
  37.         {
  38.                 MPU_Write_Byte(MPU_PWR_MGMT1_REG,0X01);        //设置CLKSEL,PLL X轴为参考
  39.                 MPU_Write_Byte(MPU_PWR_MGMT2_REG,0X00);        //加速度与陀螺仪都工作
  40.                 MPU_Set_Rate(200);                                                //设置采样率为50Hz
  41.          }else return 1;
  42.         return 0;
  43. }
  44. //设置MPU6050陀螺仪传感器满量程范围
  45. //fsr:0,±250dps;1,±500dps;2,±1000dps;3,±2000dps
  46. //返回值:0,设置成功
  47. //    其他,设置失败
  48. u8 MPU_Set_Gyro_Fsr(u8 fsr)
  49. {
  50.         return MPU_Write_Byte(MPU_GYRO_CFG_REG,fsr<<3);//设置陀螺仪满量程范围  
  51. }
  52. //设置MPU6050加速度传感器满量程范围
  53. //fsr:0,±2g;1,±4g;2,±8g;3,±16g
  54. //返回值:0,设置成功
  55. //    其他,设置失败
  56. u8 MPU_Set_Accel_Fsr(u8 fsr)
  57. {
  58.         return MPU_Write_Byte(MPU_ACCEL_CFG_REG,fsr<<3);//设置加速度传感器满量程范围  
  59. }
  60. //设置MPU6050的数字低通滤波器
  61. //lpf:数字低通滤波频率(Hz)
  62. //返回值:0,设置成功
  63. //    其他,设置失败
  64. u8 MPU_Set_LPF(u16 lpf)
  65. {
  66.         u8 data=0;
  67.         if(lpf>=188)data=1;
  68.         else if(lpf>=98)data=2;
  69.         else if(lpf>=42)data=3;
  70.         else if(lpf>=20)data=4;
  71.         else if(lpf>=10)data=5;
  72.         else data=6;
  73.         return MPU_Write_Byte(MPU_CFG_REG,data);//设置数字低通滤波器  
  74. }
  75. //设置MPU6050的采样率(假定Fs=1KHz)
  76. //rate:4~1000(Hz)
  77. //返回值:0,设置成功
  78. //    其他,设置失败
  79. u8 MPU_Set_Rate(u16 rate)
  80. {
  81.         u8 data;
  82.         if(rate>1000)rate=1000;
  83.         if(rate<4)rate=4;
  84.         data=1000/rate-1;
  85.         data=MPU_Write_Byte(MPU_SAMPLE_RATE_REG,data);        //设置数字低通滤波器
  86.          return MPU_Set_LPF(rate/2);        //自动设置LPF为采样率的一半
  87. }

  88. //得到温度值
  89. //返回值:温度值(扩大了100倍)
  90. short MPU_Get_Temperature(void)
  91. {
  92.     u8 buf[2];
  93.     short raw;
  94.         float temp;
  95.         MPU_Read_Len(MPU_ADDR,MPU_TEMP_OUTH_REG,2,buf);
  96.     raw=((u16)buf[0]<<8)|buf[1];  
  97.     temp=36.53+((double)raw)/340;  
  98.     return temp*100;;
  99. }
  100. //得到陀螺仪值(原始值)
  101. //gx,gy,gz:陀螺仪x,y,z轴的原始读数(带符号)
  102. //返回值:0,成功
  103. //    其他,错误代码
  104. u8 MPU_Get_Gyroscope(short *gx,short *gy,short *gz)
  105. {
  106.     u8 buf[6],res;  
  107.         res=MPU_Read_Len(MPU_ADDR,MPU_GYRO_XOUTH_REG,6,buf);
  108.         if(res==0)
  109.         {
  110.                 *gx=((u16)buf[0]<<8)|buf[1];  
  111.                 *gy=((u16)buf[2]<<8)|buf[3];  
  112.                 *gz=((u16)buf[4]<<8)|buf[5];
  113.         }         
  114.     return res;;
  115. }
  116. //得到加速度值(原始值)
  117. //gx,gy,gz:陀螺仪x,y,z轴的原始读数(带符号)
  118. //返回值:0,成功
  119. //    其他,错误代码
  120. u8 MPU_Get_Accelerometer(short *ax,short *ay,short *az)
  121. {
  122.     u8 buf[6],res;  
  123.         res=MPU_Read_Len(MPU_ADDR,MPU_ACCEL_XOUTH_REG,6,buf);
  124.         if(res==0)
  125.         {
  126.                 *ax=((u16)buf[0]<<8)|buf[1];  
  127.                 *ay=((u16)buf[2]<<8)|buf[3];  
  128.                 *az=((u16)buf[4]<<8)|buf[5];
  129.         }         
  130.     return res;;
  131. }
  132. //IIC连续写
  133. //addr:器件地址
  134. //reg:寄存器地址
  135. //len:写入长度
  136. //buf:数据区
  137. //返回值:0,正常
  138. //    其他,错误代码
  139. u8 MPU_Write_Len(u8 addr,u8 reg,u8 len,u8 *buf)
  140. {
  141.         u8 i;
  142.     MPU_IIC_Start();
  143.         MPU_IIC_Send_Byte((addr<<1)|0);//发送器件地址+写命令        
  144.         if(MPU_IIC_Wait_Ack())        //等待应答
  145.         {
  146.                 MPU_IIC_Stop();                 
  147.                 return 1;               
  148.         }
  149.     MPU_IIC_Send_Byte(reg);        //写寄存器地址
  150.     MPU_IIC_Wait_Ack();                //等待应答
  151.         for(i=0;i<len;i++)
  152.         {
  153.                 MPU_IIC_Send_Byte(buf[i]);        //发送数据
  154.                 if(MPU_IIC_Wait_Ack())                //等待ACK
  155.                 {
  156.                         MPU_IIC_Stop();         
  157.                         return 1;                 
  158.                 }               
  159.         }   
  160.     MPU_IIC_Stop();         
  161.         return 0;        
  162. }
  163. //IIC连续读
  164. //addr:器件地址
  165. //reg:要读取的寄存器地址
  166. //len:要读取的长度
  167. //buf:读取到的数据存储区
  168. //返回值:0,正常
  169. //    其他,错误代码
  170. u8 MPU_Read_Len(u8 addr,u8 reg,u8 len,u8 *buf)
  171. {
  172.          MPU_IIC_Start();
  173.         MPU_IIC_Send_Byte((addr<<1)|0);//发送器件地址+写命令        
  174.         if(MPU_IIC_Wait_Ack())        //等待应答
  175.         {
  176.                 MPU_IIC_Stop();                 
  177.                 return 1;               
  178.         }
  179.     MPU_IIC_Send_Byte(reg);        //写寄存器地址
  180.     MPU_IIC_Wait_Ack();                //等待应答
  181.     MPU_IIC_Start();
  182.         MPU_IIC_Send_Byte((addr<<1)|1);//发送器件地址+读命令        
  183.     MPU_IIC_Wait_Ack();                //等待应答
  184.         while(len)
  185.         {
  186.                 if(len==1)*buf=MPU_IIC_Read_Byte(0);//读数据,发送nACK
  187.                 else *buf=MPU_IIC_Read_Byte(1);                //读数据,发送ACK  
  188.                 len--;
  189.                 buf++;
  190.         }   
  191.     MPU_IIC_Stop();        //产生一个停止条件
  192.         return 0;        
  193. }
  194. //IIC写一个字节
  195. //reg:寄存器地址
  196. //data:数据
  197. //返回值:0,正常
  198. //    其他,错误代码
  199. u8 MPU_Write_Byte(u8 reg,u8 data)                                 
  200. {
  201.     MPU_IIC_Start();
  202.         MPU_IIC_Send_Byte((MPU_ADDR<<1)|0);//发送器件地址+写命令        
  203.         if(MPU_IIC_Wait_Ack())        //等待应答
  204.         {
  205.                 MPU_IIC_Stop();                 
  206.                 return 1;               
  207.         }
  208.     MPU_IIC_Send_Byte(reg);        //写寄存器地址
  209.     MPU_IIC_Wait_Ack();                //等待应答
  210.         MPU_IIC_Send_Byte(data);//发送数据
  211.         if(MPU_IIC_Wait_Ack())        //等待ACK
  212.         {
  213.                 MPU_IIC_Stop();         
  214.                 return 1;                 
  215.         }                 
  216.     MPU_IIC_Stop();         
  217.         return 0;
  218. }
  219. //IIC读一个字节
  220. //reg:寄存器地址
  221. //返回值:读到的数据
  222. u8 MPU_Read_Byte(u8 reg)
  223. {
  224.         u8 res;
  225.     MPU_IIC_Start();
  226.         MPU_IIC_Send_Byte((MPU_ADDR<<1)|0);//发送器件地址+写命令        
  227.         MPU_IIC_Wait_Ack();                //等待应答
  228.     MPU_IIC_Send_Byte(reg);        //写寄存器地址
  229.     MPU_IIC_Wait_Ack();                //等待应答
  230.     MPU_IIC_Start();
  231.         MPU_IIC_Send_Byte((MPU_ADDR<<1)|1);//发送器件地址+读命令        
  232.     MPU_IIC_Wait_Ack();                //等待应答
  233.         res=MPU_IIC_Read_Byte(0);//读取数据,发送nACK
  234.     MPU_IIC_Stop();                        //产生一个停止条件
  235.         return res;               
  236. }
复制代码
  1. #include "sys.h"        
  2. #include "delay.h"        
  3. #include "led.h"
  4. #include "Motor.h"
  5. #include "usart.h"
  6. #include "timer.h"
  7. #include "pid.h"
  8. #include "oled.h"
  9. #include "mpu6050.h"
  10. #include "usmart.h"   
  11. #include "inv_mpu.h"
  12. #include "inv_mpu_dmp_motion_driver.h"

  13. //串口1发送1个字符
  14. //c:要发送的字符
  15. u8 a = 0;
  16. u16 Kms;

  17. float pitch;
  18. float roll,yaw;                 //欧拉角         
  19. short gyrox,gyroy,gyroz;        //陀螺仪原始数据
  20. short aacx,aacy,aacz;                //加速度传感器原始数据

  21. void usart1_send_char(u8 c)
  22. {           
  23.         while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET); //循环发送,直到发送完毕   
  24.         USART_SendData(USART1,c);  
  25. }
  26. //传送数据给匿名四轴上位机软件(V2.6版本)
  27. //fun:功能字. 0XA0~0XAF
  28. //data:数据缓存区,最多28字节!!
  29. //len:data区有效数据个数
  30. void usart1_niming_report(u8 fun,u8*data,u8 len)
  31. {
  32.         u8 send_buf[32];
  33.         u8 i;
  34.         if(len>28)return;        //最多28字节数据
  35.         send_buf[len+3]=0;        //校验数置零
  36.         send_buf[0]=0X88;        //帧头
  37.         send_buf[1]=fun;        //功能字
  38.         send_buf[2]=len;        //数据长度
  39.         for(i=0;i<len;i++)send_buf[3+i]=data[i];                        //复制数据
  40.         for(i=0;i<len+3;i++)send_buf[len+3]+=send_buf[i];        //计算校验和        
  41.         for(i=0;i<len+4;i++)usart1_send_char(send_buf[i]);        //发送数据到串口1
  42. }
  43. //发送加速度传感器数据和陀螺仪数据
  44. //aacx,aacy,aacz:x,y,z三个方向上面的加速度值
  45. //gyrox,gyroy,gyroz:x,y,z三个方向上面的陀螺仪值
  46. void mpu6050_send_data(short aacx,short aacy,short aacz,short gyrox,short gyroy,short gyroz)
  47. {
  48.         u8 tbuf[12];
  49.         tbuf[0]=(aacx>>8)&0XFF;
  50.         tbuf[1]=aacx&0XFF;
  51.         tbuf[2]=(aacy>>8)&0XFF;
  52.         tbuf[3]=aacy&0XFF;
  53.         tbuf[4]=(aacz>>8)&0XFF;
  54.         tbuf[5]=aacz&0XFF;
  55.         tbuf[6]=(gyrox>>8)&0XFF;
  56.         tbuf[7]=gyrox&0XFF;
  57.         tbuf[8]=(gyroy>>8)&0XFF;
  58.         tbuf[9]=gyroy&0XFF;
  59.         tbuf[10]=(gyroz>>8)&0XFF;
  60.         tbuf[11]=gyroz&0XFF;
  61.         usart1_niming_report(0XA1,tbuf,12);//自定义帧,0XA1
  62. }        
  63. //通过串口1上报结算后的姿态数据给电脑
  64. //aacx,aacy,aacz:x,y,z三个方向上面的加速度值
  65. //gyrox,gyroy,gyroz:x,y,z三个方向上面的陀螺仪值
  66. //roll:横滚角.单位0.01度。 -18000 -> 18000 对应 -180.00  ->  180.00度
  67. //pitch:俯仰角.单位 0.01度。-9000 - 9000 对应 -90.00 -> 90.00 度
  68. //yaw:航向角.单位为0.1度 0 -> 3600  对应 0 -> 360.0度
  69. void usart1_report_imu(short aacx,short aacy,short aacz,short gyrox,short gyroy,short gyroz,short roll,short pitch,short yaw)
  70. {
  71.         u8 tbuf[28];
  72.         u8 i;
  73.         for(i=0;i<28;i++)tbuf[i]=0;//清0
  74.         tbuf[0]=(aacx>>8)&0XFF;
  75.         tbuf[1]=aacx&0XFF;
  76.         tbuf[2]=(aacy>>8)&0XFF;
  77.         tbuf[3]=aacy&0XFF;
  78.         tbuf[4]=(aacz>>8)&0XFF;
  79.         tbuf[5]=aacz&0XFF;
  80.         tbuf[6]=(gyrox>>8)&0XFF;
  81.         tbuf[7]=gyrox&0XFF;
  82.         tbuf[8]=(gyroy>>8)&0XFF;
  83.         tbuf[9]=gyroy&0XFF;
  84.         tbuf[10]=(gyroz>>8)&0XFF;
  85.         tbuf[11]=gyroz&0XFF;        
  86.         tbuf[18]=(roll>>8)&0XFF;
  87.         tbuf[19]=roll&0XFF;
  88.         tbuf[20]=(pitch>>8)&0XFF;
  89.         tbuf[21]=pitch&0XFF;
  90.         tbuf[22]=(yaw>>8)&0XFF;
  91.         tbuf[23]=yaw&0XFF;
  92.         usart1_niming_report(0XAF,tbuf,28);//飞控显示帧,0XAF
  93. }  


  94. int main(void)
  95. {        
  96.          
  97.         u8 i,report=1;
  98.   
  99.         
  100.         delay_init();                     //延时函数初始化        
  101.    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级                 
  102.         uart_init(115200);         //串口初始化为115200
  103.      delay_ms(100);
  104.           MPU_Init();                                        //初始化MPU6050
  105.         
  106.         
  107.             Motor_Init();        
  108.    
  109.            TIM2_PWM_Init(7199,0);         //不分频。PWM频率=72000000/900=80Khz
  110.       PID_Init();
  111.           LED_Init();//LED端口初始化
  112.          

  113.      mpu_dmp_init();
  114.                
  115.         MPU6050_EXTI_Init();//外部中断初始化
  116.          
  117.         
  118.          
  119. while(1)
  120.         {
  121.                         
  122.                
  123.         }         
  124. }

复制代码

所有资料51hei提供下载:
平衡版.7z (277.58 KB, 下载次数: 88)

评分

参与人数 1黑币 +100 收起 理由
admin + 100 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:1 发表于 2019-1-25 15:23 | 显示全部楼层
本帖需要重新编辑补全电路原理图,源码,详细说明与图片即可获得100+黑币(帖子下方有编辑按钮)
回复

使用道具 举报

ID:119642 发表于 2020-2-19 19:59 | 显示全部楼层
黑51这个网站是比较厉害了。这个资料都出来了。
回复

使用道具 举报

ID:730307 发表于 2020-4-16 09:39 | 显示全部楼层
不错不错
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表