#include "reg52h"
unsigned char count; //05ms次数标识
sbit pwm =P1^7 ; //PWM信号输出
sbit jia =P3^6; //角度增加按键检测IO口
sbit jan =P3^7; //角度减少按键检测IO口
unsigned char jd; //角度标识
unsigned char flag;
sbit dula=P2^6;
sbit wela=P2^7;
unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
void delay(unsigned char i)//延时
{
unsigned char j,k;
for(j=i;j>0;j--)
for(k=125;k>0;k--);
}
void Time0_Init() //定时器初始化
{
TMOD = 0x01; //定时器0工作在方式1
IE = 0x82;
TH0 = 0xfe;
TL0 = 0x33; //110592MZ晶振,05ms
TR0=1; //定时器开始
}
void Time0_Int() interrupt 1 //中断程序
{
TH0 = 0xfe; //重新赋值
TL0 = 0x33;
if(flag!=29||jd!=1) //这个判断是为了在0度时让信号线只输出30个周期的PWM信号,然后就让信号线为低电平
{
if(count<jd) //判断05ms次数是否小于角度标识
pwm=1; //确实小于,PWM输出高电平
else
pwm=0;
}
count=(count+1); //05ms次数加1
if(count==39) //次数始终保持为40 即保持周期为20ms
{
count=0;
if(jd==1)
if(flag!=29)
flag=flag+1; //如果30个周期已经到了,则保持这个flag为29,使在前面的判断中不在输出PWM信号
}
}
void keyscan() //按键扫描
{
if(jia==0) //角度增加按键是否按下
{
delay(10); //按下延时,消抖
if(jia==0) //确实按下
{ flag=0; //有键按下就让flag为0,这样当再次要使电机为0度时可以再次输出30个周期的PWM信号
jd++; //角度标识加1
count=0; //按键按下 则20ms周期从新开始
if(jd==6)
jd=5; //已经是180度,则保持
while(jia==0); //等待按键放开
}
}
if(jan==0) //角度减小按键是否按下
{
delay(10);
if(jan==0)
{flag=0; //有键按下就让flag为0,这样当再次要使电机为0度时可以再次输出30个周期的PWM信号
jd--; //角度标识减1
count=0;
if(jd==0)
jd=1; //已经是0度,则保持
while(jan==0);
}
}
}
void display() //数码管显示函数
{
unsigned char bai,shi,ge;
switch(jd) //根据角度标识显示相应的数值
{
case 1: //为1,角度为0,前3个数码管显示000
bai=0;
shi=0;
ge=0;
break;
case 2:
bai=0;
shi=4;
ge=5;
break;
case 3:
bai=0;
shi=9;
ge=0;
break;
case 4:
bai=1;
shi=3;
ge=5;
break;
case 5: //为5,角度为180,前3个数码管显示180
bai=1;
shi=8;
ge=0;
break;
}
dula=0;
P0=table[bai];
dula=1;
dula=0;
wela=0;
P0=0xfe;
wela=1;
wela=0;
delay(5);
P0=table[shi];
dula=1;
dula=0;
P0=0xfd;
wela=1;
wela=0;
delay(5);
P0=table[ge];
dula=1;
dula=0;
P0=0xfb;
wela=1;
wela=0;
delay(5);
}
void main()
{
jd=1;
flag=0;
count=0;
pwm=0;
Time0_Init();
while(1)
{
keyscan(); //按键扫描
display();
}
}
首先开明白你的舵机控制原理,它要求输入的脉冲期是20ms,其中高电平在15ms时舵臂在0位
在20ms时舵臂在右90度位 在15ms时舵臂在左90度位 舵机有3根线,一根线是电源正,另一根电源负,还有一根(一般为白线)是控制线,就是输入的脉冲信号的
程序中可以用两个定时器,一个定时20ms,另外一个定时1到2ms可变,就可以让舵机动作
下面程序供参考,先不考虑按键问题,能让舵机动作就 成功一大半
/双定时器产生PWM波,控制舵机
//定时器0负责置高电平和控制定时器1的开停,定时器1负责置低电平
#include<STC12C5AH>
#define uchar unsigned char
#define uint unsigned int
sbit PWM=P3^7;//经试验,此引脚信号可以直接送舵机不用放大
uchar b=1500;//定时15ms的初值
void Delay1ms(uint i) //1ms延时程序
{
uint j;
for(;i>0;i--)
{
for(j=0;j<125;j++)
{;}
}
}
void main()
{
b=1500;
TMOD=0X11;
TH0=(65536-20000)/256;
TL0=(65536-20000)%256;
TH1=(65536-b)/256;
TL1=(65536-b)%256;
ET0=1;
EA=1;
TR0=1;
PWM=1;
P1M0=0X0F; //低4位配置为推挽输出 ,普通51单片机无此寄存器
P1M1=0X00;
while(1)
{
P1=0; //这是让行走电机正向转动的,用的是L298N模块
b=1500;Delay1ms(2000);//直行
b=1000;Delay1ms(1000);//左转
b=1500;Delay1ms(2000);//直行
b=2000;Delay1ms(1000);//右转
b=1500;Delay1ms(2000);//直行
P1=0x05;//这是让行走电机反向转动的
b=1500;Delay1ms(2000);//后退
b=1000;Delay1ms(1000);//后左转
b=1500;Delay1ms(2000);//后退
b=2000;Delay1ms(1000);//后右转
b=1500;Delay1ms(2000);//后退
}
}
void timer0()interrupt 1//定时器0中断
{
TH0=(65536-20000)/256;
TL0=(65536-20000)%256;
PWM=1;
TR1=1;
ET1=1;
}
void timer1()interrupt 3//定时器1中断
{
TH1=(65536-b)/256;//改变b的值就可转向
TL1=(65536-b)%256;
PWM=0;
TR1=0;
ET1=0;
}
180度舵机是一特殊的机器人专用舵机。你所说的0-180度,在专业玩家里不这样说的,而是说成±90度。即顺时针90度,逆时针90度。
你可以自己写一个的。这种舵机比较特殊,但是只要满足一下PWM就可以实现了:
1 周期T=20ms(即50HZ),占空比500us-2500us。
2 500us舵机逆时针转90度,2500us舵机顺时针转90读。 (其中0度是1500us)
3 即: TL+TH=20ms 改变TH的值,舵机角度随之改变。参数参照以上12点。
TL TH
_____ ____
_________| |_________| | _________|
4 电路原理很简单,接好电源,地,信号线。
信号线接到单片机或者其他能输出PWM的控制脚。
舵机是一种位置伺服的驱动器,适用于那些需要角度不断变化并可以保持的控制系统。其工作原理是:控制信号由接收机的通道进入信号调制芯片,获得直流偏置电压。它内部有一个基准电路,产生周期为20ms,宽度为15ms的基准信号,将获得的直流偏置电压与电位器的电压比较,获得电压差输出。最后,电压差的正负输出到电机驱动芯片决定电机的正反转。当电机转速一定时,通过级联减速齿轮带动电位器旋转,使得电压差为0,电机停止转动。编程的时候也很简单,你将一根管脚初始化为低电平,然后写一个while循环,在循环中将该脚职位高电平,延时,再拉为低电平,如此不停的循环就是PWM波,你需要控制的是高电平产生的时间,根据高电平的时间来控制舵机的角度的,希望能帮的上你
以上就是关于怎么用按键控制舵机的程序全部的内容,包括:怎么用按键控制舵机的程序、那个大神帮写一个89c52rc单片机控制9g舵机程序、那位大神给段c语言控制舵机从0~180持续来回转动的程序,不胜感激等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)