舵机(sg90,板子是普中的51)

本人小白一枚,昨天用51实现了舵机的几个小功能,帮助和我一样初学的朋友~(。・`ω´・)
如有错误不足还请大家指点

接线

红电源

棕接地

橙色数据线

代码

希望实现两个功能

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

程序1

// _nop_()延时一个机器周期
#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的值

// _nop_()延时一个机器周期
#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 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;y<n;y++);
}
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 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();
	}
}
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐