舵机(sg90,板子是普中的51)
本人小白一枚,昨天用51实现了舵机的几个小功能,帮助和我一样初学的朋友~(。・`ω´・)
如有错误不足还请大家指点
接线
红电源
棕接地
橙色数据线
代码
希望实现两个功能
- 基础转动一定角度
- 实现PWM控制转角渐变
- 实现按键控制角度和转速(延时函数有问题,所以控制效果不好)
- 今天学习的一个小技巧,每实现一个功能,都要及时测试
程序1
// _nop_()延时一个机器周期
#include <reg52.h>
#include <intrins.h>
sbit PWM = P3^7; //设定PWM输出的I/O端口
unsigned char count = 0;
unsigned char timer1 ;
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 Timer0_Init()
{
TMOD &= 0x00;
TMOD |= 0x01; //定时器T0设置成方式1
TH0 = 0xff; //定时常数 0.1ms 晶振为11.0592MHz
TL0 = 0xa4;
ET0 = 1;
TR0 = 1;
EA=1;
}
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;
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--);
}
void Timer0_Init()
{
TMOD &= 0x00;
TMOD |= 0x01; //定时器T0设置成方式1
TH0 = 0xff; //定时常数 0.1ms 晶振为11.0592MHz
TL0 = 0xa4;
ET0 = 1;
TR0 = 1;
EA=1;
}
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;//角度减小
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);
}
}
void Timer0_Init()
{
TMOD &= 0x00;
TMOD |= 0x01; //定时器T0设置成方式1
TH0 = 0xff; //定时常数 0.1ms 晶振为11.0592MHz
TL0 = 0xa4;
ET0 = 1;
TR0 = 1;
EA=1;
}
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();
}
}