陀螺仪控制舵机

文章目录

  • 任务:
  • 思路
  • 改IO接口
  • 完成代码:

任务:

从陀螺仪读取数据,以上电角度为目标,在舵机和开发板和陀螺仪同步转动时,舵机的总是指向目标

需要使用和例程不同的IO口

就是说,把舵机粘在开发板上,陀螺仪插在开发板上,在开发板水平左右转动时,舵机总是指向上电角度

可以接收陀螺仪传感器本身的水平角度漂移,旋转角度在舵机可以达到的范围内
 
 

思路

陀螺仪控制舵机_第1张图片
这个是我们最常用的陀螺仪MPU6050
使用IIC通讯
正常情况下我们不使用STM32的硬件IIC
所以任选两个IO模拟IIC的通讯时序即可
 
陀螺仪控制舵机_第2张图片
陀螺仪控制舵机_第3张图片
陀螺仪控制舵机_第4张图片
陀螺仪控制舵机_第5张图片

pitch俯仰角
yaw偏航角
roll翻滚角
 

改IO接口

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);			
    } 			
}
 



最后:
舵机旋转卡顿的问题
关注一下陀螺仪传回的数据
模块传回的数据当然不会是直接拿过来就能用的

你可能感兴趣的:(STM32,单片机,stm32,嵌入式硬件)