标题:
单片机驱动sg90舵机程序问题
[打印本页]
作者:
363249
时间:
2020-3-2 09:31
标题:
单片机驱动sg90舵机程序问题
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);
}
}
}
作者:
f556
时间:
2020-3-2 11:31
舵机驱动原理是:20ms中高电平占多少,对应多少角度,不是发一个脉冲就能到位的,原则上是发多个相同的脉冲,到了相应角度,舵机停在此角度,如果有外力破坏了此角度,它能重新修正到此角度。
“多个相同的脉冲”是关键。或者说反复、重复一直发脉冲。
你 while(--i)
{
中是只有一个脉冲的做法,思路需重理
作者:
sea_blue
时间:
2020-3-2 11:40
这个是模拟舵机,需要总宽度为20ms的占空比连续信号。
作者:
之一知足
时间:
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
}
作者:
黎明初至
时间:
2020-3-2 15:49
舵机不是直流电机,给电即走,他是通过脉冲占空比来驱动的。
作者:
lovexulu
时间:
2020-3-2 22:33
先仔细了解一下舵机驱动原理吧,你这个代码驱动不了的。另外延迟函数1个就够了,搞那么多延迟干嘛呢。
作者:
haierzaifei11
时间:
2020-3-4 15:33
先仔细了解一下舵机驱动原理吧,你这个代码驱动不了的。
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1