我们不仅销售产品,我们还传播知识
商品分类

使用51单片机控制舵机入门


舵机(sg90,板子是普中的51)
用51实现了舵机的几个小功能,帮助和我一样初学的朋友~(。・`ω´・)
如有错误不足还请大家指点

接线
红电源

棕接地

橙色数据线

代码
希望实现两个功能

基础转动一定角度
实现PWM控制转角渐变
实现按键控制角度和转速(延时函数有问题,所以控制效果不好)
今天学习的一个小技巧,每实现一个功能,都要及时测试

程序1

#include<reg52.h>

#include<intrins.h>

sbit PWM = P3^7; //设定PWM输出的I/O端口
unsigned char count = 0;
unsigned char timer1 ;
/*
对于180°舵机
t = 0.5ms——————-舵机会转动 0 °
t = 1.0ms——————-舵机会转动 45°
t = 1.5ms——————-舵机会转动 90°
t = 2.0ms——————-舵机会转动 135°
t = 2.5ms——————-舵机会转动180
*/

/延时程序/
void delay1s(void) //误差 0us
{
unsigned char a,b,c;
for(c=167;c>0;c–)
for(b=171;b>0;b–)
for(a=16;a>0;a–);
nop(); //if Keil,require use intrins.h
}

/定时器T0初始化/
void Timer0_Init()
{
TMOD &= 0x00;
TMOD |= 0x01; //定时器T0设置成方式1

TH0 = 0xff;   //定时常数 0.1ms 晶振为11.0592MHz
TL0 = 0xa4;

ET0 = 1;      
TR0 = 1; 
EA=1; 
}

/T0中断初始化/
void Time0_Init() interrupt 1
{
TR0 = 0;
TH0 = 0xff; // 0.1ms
TL0 = 0xa4;

if(count <= timer1) //5==0° 15==90°
{ 
    PWM = 1; 
}
else 
{ 
    PWM = 0; 
}
count++;
if (count >= 200) //T = 20ms清零
{ 
    count = 0; 
}
TR0 = 1; //开启T0

}
void main()
{
Timer0_Init();
while(1)
{

    timer1 =5;//舵机恢复到0°的位置
    count=0;//让定时器重新计数
    delay1s();
    timer1 =15;//舵机旋转90°
    count=0;
    delay1s();
}

}

程序2

程序2和程序1里面count和timer1两个值的功能恰好相反,这个需要注意。。。

#include <reg52.h>

#include <intrins.h>

sbit PWM = P3^7; //设定PWM输出的I/O端口
typedef unsigned int u16;
typedef unsigned char u8;
u8 count = 0;
u8 value,timer1;//用于调节占空比
bit DIR;
/*
对于180°舵机
t = 0.5ms——————-舵机会转动 0 °
t = 1.0ms——————-舵机会转动 45°
t = 1.5ms——————-舵机会转动 90°
t = 2.0ms——————-舵机会转动 135°
t = 2.5ms——————-舵机会转动180
*/

/延时程序/
void delay1s(void) //误差 0us
{
unsigned char a,b,c;
for(c=167;c>0;c–)
for(b=171;b>0;b–)
for(a=16;a>0;a–);
nop(); //if Keil,require use intrins.h
}
void delay100ms(void) //误差 0us
{
unsigned char a,b,c;
for(c=19;c>0;c–)
for(b=20;b>0;b–)
for(a=130;a>0;a–);
}

/定时器T0初始化/
void Timer0_Init()
{
TMOD &= 0x00;
TMOD |= 0x01; //定时器T0设置成方式1

TH0 = 0xff;   //定时常数 0.1ms 晶振为11.0592MHz
TL0 = 0xa4;

ET0 = 1;      
TR0 = 1; 
    EA=1; 
}

/T0中断初始化/
void Time0_Init() interrupt 1
{
TR0=0;
TH0 = 0xff; // 0.1ms
TL0 = 0xa4;

count++;
if(count>100)
    {   
        count=0;
        if(DIR==1)
        {   
            value++;
            delay100ms();
        }
        if(DIR==0)
        {   
            value--;
            delay100ms();
        }
    }
    if(value==25)
    {   
        DIR=0;
    }
    if(value==5)
    {   
        DIR=1;
    }
    if(timer1>200)
    {   
        timer1=0;
    }
    if(timer1<value)
    {   
        PWM=1;
    }
    else
    {   
        PWM=0;
    }
    timer1++;
    TR0=1;

}
void main()
{
Timer0_Init();
while(1)
{

    delay1s();
}

}

程序3

使用按键控制角度,这个实现起来比较简单,控制角度只需要修改程序1中timer1的值

#include <reg52.h>

#include <intrins.h>

// nop()延时一个机器周期

sbit PWM = P3^7; //设定PWM输出的I/O端口
typedef unsigned int u16;
typedef unsigned char u8;
u8 count = 0;
u8 timer1;
u8 timer;
u16 n;
sbit k1=P3^1;//角度增加
sbit k2=P3^0;//角度减小
/*
对于180°舵机
t = 0.5ms——————-舵机会转动 0 °
t = 1.0ms——————-舵机会转动 45°
t = 1.5ms——————-舵机会转动 90°
t = 2.0ms——————-舵机会转动 135°
t = 2.5ms——————-舵机会转动180
*/

/延时程序/
void delay(u16 n)//一个n约延时1ms
{
u16 x,y;
for(x=0;x<114;x++) for(y=0;y0;c–)
for(b=171;b>0;b–)
for(a=16;a>0;a–);
nop(); //if Keil,require use intrins.h
}
/按键扫描程序/
void keyscan()
{
if(k1==0)
{
if(k1==0)
delay(100);
{
timer+=5;
}
while(!k1);
}
if(k2==0)
{
if(k2==0)
delay(100);
{
timer-=5;
}
while(!k2);
}

}

/定时器T0初始化/
void Timer0_Init()
{
TMOD &= 0x00;
TMOD |= 0x01; //定时器T0设置成方式1

TH0 = 0xff;   //定时常数 0.1ms 晶振为11.0592MHz
TL0 = 0xa4;

ET0 = 1;      
TR0 = 1; 
EA=1; 
}

/T0中断初始化/
void Time0_Init() interrupt 1
{
TR0 = 0;
TH0 = 0xff; // 0.1ms
TL0 = 0xa4;

if(count <= timer1) //5==0° 15==90°
{ 
    PWM = 1; 
}
else 
{ 
    PWM = 0; 
}
count++;
if (count >= 200) //T = 20ms清零
{ 
    count = 0; 
}
TR0 = 1; //开启T0

}
void main()
{
Timer0_Init();
timer1=5;
n=500;
while(1)
{
keyscan();
if(timer>25)
{
timer=5;
}
timer1=timer;
count=0;
delay1s();
timer1=5;
count=0;
delay1s();
}
}

发表回复

登录后才能评论
微信群
微信群
联系我们

联系我们

微信:13823392571

在线咨询:点击这里给我发消息

工作时间:周一至周五,9:30-18:30,节假日休息

微信客服
微信客服
分享本页
返回顶部