舵机(sg90,板子是普中的51)
本人小白一枚,昨天用51实现了舵机的几个小功能,帮助和我一样初学的朋友~(??`ω′?)
如有错误不足还请大家指点
接线
红电源
棕接地
橙色数据线
代码
希望实现两个功能
基础转动一定角度
实现PWM控制转角渐变
实现按键控制角度和转速(延时函数有问题,所以控制效果不好)
今天学习的一个小技巧,每实现一个功能,都要及时测试
程序1
// _nop_()延时一个机器周期#include 《reg52.h》#include 《intrins.h》***it 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》***it 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》***it PWM = P3^7; //设定PWM输出的I/O端口typedef unsigned int u16;typedef unsigned char u8;u8 count = 0;u8 timer1;u8 timer;u16 n;***it k1=P3^1;//角度增加***it 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(); }}