找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2596|回复: 6
打印 上一主题 下一主题
收起左侧

单片机驱动sg90舵机程序问题

[复制链接]
跳转到指定楼层
楼主
ID:370407 发表于 2020-3-2 09:31 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
t = 0.5ms——————-舵机会转动 0 °      
t = 1.0ms——————-舵机会转动 45°
t = 1.5ms——————-舵机会转动 90°
t = 2.0ms——————-舵机会转动 135°
t = 2.5ms——————-舵机会转动180

//        为什么只能转一次后面有程序为什么不执行?
//        delayus2x(245);      这个245值是怎么算出来的?
#include<reg52.h>
sbit a=P1^0;
#define uchar unsigned char
#define uint unsigned int
void delay(uint z)
{
        uint x,y;
        for(x=z;x>0;x--)
                for(y=110;y>0;y--);
}

void delayus2x(unsigned char t)
{   
while(--t);
}

void delay500us()
{
                delayus2x(245);   //   245

}
void delay2500us()
{
                delayus2x(245);     
                delayus2x(245);
                delayus2x(245);
                delayus2x(245);
                delayus2x(245);
                delayus2x(245);

}
void main()     
{
while(1)
{
            uint i=50;
                while(--i)                           
                {
                        a=1;
                        delay500us();    //      转0度       为什么换成  delay2500us(); 也是转一下   不执行下面的程序   
                        a=0;
                        delay(1000);

                        
                        a=1;
                        delay2500us();  //      转180度      这里明明还有动作
                        a=0;
                        delay(1000);
                        a=1;
                        delay500us();   //      转0度
                        a=0;
                        delay(1000);
                        a=1;
                        delay2500us();  //      转180度
                        a=0;
                        delay(1000);
                }  
}
}

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:282850 发表于 2020-3-2 11:31 | 只看该作者
舵机驱动原理是:20ms中高电平占多少,对应多少角度,不是发一个脉冲就能到位的,原则上是发多个相同的脉冲,到了相应角度,舵机停在此角度,如果有外力破坏了此角度,它能重新修正到此角度。
“多个相同的脉冲”是关键。或者说反复、重复一直发脉冲。
你  while(--i)                           
                {
中是只有一个脉冲的做法,思路需重理
回复

使用道具 举报

板凳
ID:682002 发表于 2020-3-2 11:40 | 只看该作者
这个是模拟舵机,需要总宽度为20ms的占空比连续信号。
回复

使用道具 举报

地板
ID:342451 发表于 2020-3-2 11:45 | 只看该作者
这是我当时写的一个简单的51定时器输出PWM方式控制三个舵机按顺序依次旋转。你可以借鉴下,不推荐用延迟函数的方式去控制舵机

#include "reg51.h"//此文件中定义了单片机的一些特殊功能寄存器

typedef unsigned int u16;//对数据类型进行声明定义
typedef unsigned char u8;

sbit KEY=P3^1;//控制按键

sbit Servo_1=P2^0;//舵机输出
sbit Servo_2=P2^1;//舵机输出
sbit Servo_3=P2^2;//舵机输出

u16 Servo_PWM1,Servo_PWM2,Servo_PWM3;//三个舵机的PWM值

//PWM:5-22  
//对应0-180°
#define LOW 5
#define HIGH 22

u8  Flag_step;//舵机动作步骤
bit start;//随着按键按下开始动作

void delay_ms(u16 j)  //j=1,1ms
{
        u8 i=250;
        for(;j>0;j--)
        {
                 while(--i);
                 i=249;
                 while(--i);
                 i=250;
        }
}

void step(void)//舵机动作
{
        if(start==1)//按键按下,标志位置1,满足条件进入if()
        {
                if(Flag_step==1)//第一步
                {
                        Servo_PWM1=HIGH;//一舵机转到180
                        delay_ms(500);//延时一段时间,根据需求更改时间,灵活可调
                        Flag_step=2;        //下一步                               
                }
                if(Flag_step==2)//第二步
                {
                        Servo_PWM1=LOW;//一舵机转到0
                        delay_ms(500);//延时一段时间
                        Flag_step=3;//下同,分别是二三舵机动作
                }
                if(Flag_step==3)
                {
                        Servo_PWM2=HIGH;
                        delay_ms(500);
                        Flag_step=4;                       
                }
                if(Flag_step==4)
                {
                        Servo_PWM2=LOW;
                        delay_ms(500);
                        Flag_step=5;                       
                }
                if(Flag_step==5)
                {
                        Servo_PWM3=HIGH;
                        delay_ms(500);
                        Flag_step=6;                       
                }
                if(Flag_step==6)
                {
                        Servo_PWM3=LOW;
                        delay_ms(500);
                        Flag_step=1;//形成一个循环,回到第一步
                        start=0;//将标志位置0,等待下一次按键按下,将标志位置1,重新开始一周期
                }
        }
}
/*******************************************************************************
* 函 数 名         : Timer1Init
* 函数功能                   : 定时器1初始化
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void Timer1Init()
{
        TMOD|=0X10;//选择为定时器1模式,工作方式1,仅用TR1打开启动。
        TH1=0XFF;        //给定时器赋初值,定时0.1ms
        TL1=0X9C;       
        ET1=1;//打开定时器1中断允许
        EA=1;//打开总中断
        TR1=1;//打开定时器                       
}
/*******************************************************************************
* 函 数 名       : main
* 函数功能                   : 主函数
* 输    入       : 无
* 输    出             : 无
*******************************************************************************/
void main()
{       
        Timer1Init();//定时器1初始化
        start=0;//初始状态舵机不动作
        Flag_step=1;//初始第一步
        Servo_PWM1=5;//将三个舵机初始化成0°位置
        Servo_PWM2=5;
        Servo_PWM3=5;
        while(1)
        {
                if(KEY==0)//按键按下
                {
                        start=~start;//重新开始一个周期
                        while(!KEY);//等待按键松开
                }
                step();//舵机动作
        }               
}
/*******************************************************************************
* 函 数 名         : void Timer1() interrupt 3
* 函数功能                     : 定时器0中断函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void Timer1() interrupt 3
{
        static u16 t;
        TH1=0XFF;        //给定时器赋初值,定时0.1ms
        TL1=0X9C;
        t++;
        //根据改变Servo_PWM1内容,改变占空比,从而达到控制舵机达到不同的角度
        //————      ————
        //    ——————    ————————.......
        if(t<Servo_PWM1)Servo_1=1;//高电平输出
        if(t>=Servo_PWM1)Servo_1=0;//低电平输出
       
        if(t<Servo_PWM2)Servo_2=1;
        if(t>=Servo_PWM2)Servo_2=0;
       
        if(t<Servo_PWM3)Servo_3=1;
        if(t>=Servo_PWM3)Servo_3=0;       
       
        if(t>200)t=0;//舵机控制频率50HZ,200*0.1=20ms
}

回复

使用道具 举报

5#
ID:697917 发表于 2020-3-2 15:49 | 只看该作者
舵机不是直流电机,给电即走,他是通过脉冲占空比来驱动的。
回复

使用道具 举报

6#
ID:687694 发表于 2020-3-2 22:33 | 只看该作者
先仔细了解一下舵机驱动原理吧,你这个代码驱动不了的。另外延迟函数1个就够了,搞那么多延迟干嘛呢。
回复

使用道具 举报

7#
ID:679425 发表于 2020-3-4 15:33 | 只看该作者
先仔细了解一下舵机驱动原理吧,你这个代码驱动不了的。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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