从陀螺仪读取数据,以上电角度为目标,在舵机和开发板和陀螺仪同步转动时,舵机的总是指向目标
需要使用和例程不同的IO口
就是说,把舵机粘在开发板上,陀螺仪插在开发板上,在开发板水平左右转动时,舵机总是指向上电角度
可以接收陀螺仪传感器本身的水平角度漂移,旋转角度在舵机可以达到的范围内
这个是我们最常用的陀螺仪MPU6050
使用IIC通讯
正常情况下我们不使用STM32的硬件IIC
所以任选两个IO模拟IIC的通讯时序即可
pitch俯仰角
yaw偏航角
roll翻滚角
IO口的方向设置
只是改变了SDA,一个是in输入,一个是呕吐输出
CRL对应0~7 一共八个端口
CRH对应8~15 一共八个端口
0XFFFFFFFF 一共八个F 一位F是四字节
从最右边开始是第一个端口,依次往左。需要哪个端口,就把哪个端口对应位置改为0
8和3不用更改是固定的,但后面的数是需要计算0之后有几位F,如下所示0之后有7个F那么就是4*7=28
//IO最重要的是改这里
#define MPU_SDA_IN() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)8<<28;}//H 12
#define MPU_SDA_OUT() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)3<<28;}
//CRL 0~7 CRH 8~15
#define MPU_IIC_SCL PBout(6) //SCL
#define MPU_IIC_SDA PBout(7) //SDA
#define MPU_READ_SDA PBin(7) //ÊäÈëSDA
void MPU_IIC_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//ÏÈʹÄÜÍâÉèIO PORTBʱÖÓ
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7; // ¶Ë¿ÚÅäÖÃ
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //ÍÆÍìÊä³ö
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO¿ÚËÙ¶ÈΪ50MHz
GPIO_Init(GPIOB, &GPIO_InitStructure); //¸ù¾ÝÉ趨²ÎÊý³õʼ»¯GPIO
GPIO_SetBits(GPIOB,GPIO_Pin_6|GPIO_Pin_7); //PB10,PB11 Êä³ö¸ß
}
int main(void)
{
unsigned char flag = 0;
char buf[10];
unsigned int t = 0;
float pitch,roll,yaw; //Å·À½Ç
short aacx,aacy,aacz; //¼ÓËٶȴ«¸ÐÆ÷ÔʼÊý¾Ý
short gyrox,gyroy,gyroz; //ÍÓÂÝÒÇÔʼÊý¾Ý
short temp; //ζÈ
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //ÉèÖÃNVICÖжϷÖ×é2:2λÇÀÕ¼ÓÅÏȼ¶£¬2λÏìÓ¦ÓÅÏȼ¶
delay_init(); //ÑÓʱ³õʼ»¯
OLED_Init();
OLED_ShowString(2,0,"First INIT",16);
while(MPU_Init())
{
OLED_Clear();
OLED_ShowString(2,0,"NO MPU CONNECT",16);
} //³õʼ»¯MPU6050+
OLED_Clear();
while(1)
{
t++;
if(t%3 == 0)
{
OLED_ShowString(2,2,"Try to INIT again",16);
MPU_Init();
OLED_ShowString(2,2,"INIT DMP DRV.. ",16);
}
flag = mpu_dmp_init();
delay_ms(200);
OLED_ShowNum(108,0,flag,16);
if(flag==0)
break;
OLED_ShowString(2,0,"MPU ERROR",16);
}
OLED_Clear();
OLED_ShowString(2,0,"MPU OK",16);
delay_ms(500);
OLED_Clear();
while(1)
{
t++;
if(t%10 == 0)
{
if(mpu_dmp_get_data(&pitch,&roll,&yaw)==0)
{
temp=MPU_Get_Temperature(); //µÃµ½Î¶ÈÖµ
MPU_Get_Accelerometer(&aacx,&aacy,&aacz); //µÃµ½¼ÓËٶȴ«¸ÐÆ÷Êý¾Ý
MPU_Get_Gyroscope(&gyrox,&gyroy,&gyroz); //µÃµ½ÍÓÂÝÒÇÊý¾Ý
sprintf(buf," TEMP:%2.2fC ",(float)temp/100);
OLED_ShowString(2,0,buf,16);
temp=pitch*10;
sprintf(buf,"PITCH:%2.1f ",(float)temp/10);
OLED_ShowString(2,2,buf,16);
temp=roll*10;
sprintf(buf," ROLL:%2.1f ",(float)temp/10);
OLED_ShowString(2,4,buf,16);
temp=yaw*10;
sprintf(buf," YAW:%2.1f ",(float)temp/10);
OLED_ShowString(2,6,buf,16);
}
}
SG90_angle(90-1.5*yaw);
}
}
最后:
舵机旋转卡顿的问题
关注一下陀螺仪传回的数据
模块传回的数据当然不会是直接拿过来就能用的