智能小车舵机转向程序

如题所述

#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
uint count;
uchar jd;
sbit le1=P1^0; //*光电传感器*//
sbit PWM=P3^5; //舵机pwm//

init()
{
TMOD=0x01;//设定定时器
TH0 = 0xFE;
TL0 = 0x0c;//设定定时初始值
EA=1;
ET0=1;
TR0=1;
}

void delay(uint z) //延时
{
uint x,y;
for(x=z;x>0;x--)
for(y=125;y>0;y--);
}

void timer0() interrupt 1 //产生pwm信号控制舵机,周期20ms
{
TH0 = 0xFE;
TL0 = 0x0c; //设定定时初始值
if(count<jd) //判断0.5ms次数是否小于角度标识
{
PWM=1; //确定小于,pwm输出高电平
// delay(180); //延时一会,可以减慢舵机转速
}
else
PWM=0; //大于则输出低电平
count=count+1; //0.5ms次数加1
count=count%40; //次数始终保持为40即保持周期为20ms
}

void xunji() //循迹函数,读取光电管状态
{
if(le1!=0)
{
delay(10);
if(le1==0)
{
jd++;
count=0;
while(le1==0);
}
} //分析光电管状态,看你的电路检测到黑线输出1或者是0
else
{
count=0;
jd=3; //舵机归中
}
}

void main()
{
jd=3; //角度初始化90°: 1=0.5ms 舵机为0° 2=1ms 舵机为45°3、4、5、同上
count=0; //初始化赋值零
init(); //定时器初始化
while(1)
{
xunji(); //舵机检测
}
}
温馨提示:答案为网友推荐,仅供参考
第1个回答  推荐于2020-02-06
//只利用一个定时器 T0,定时时间为 0.5ms,定义一个角度标识,数值为 1、2、3、4、5,
//实现 0.5ms、1ms、1.5ms、2ms、2.5ms 高电平的输出,再定义一个变量,数值最大为 40,实现周期为 20ms。
//每次进入定时中断,判断此时的角度标识,进行
//相应的操作。比如此时为 5,则进入的前 5 次中断期间,信号输出为高电平,即为 2.5ms 的
//高电平。剩下的 35 次中断期间,信号输出为低电平,即为 17.5ms 的低电平。这样总的时间
//是 20ms,为一个周期。
//用51板上s1和s2按键
//用P1^7输出 PWM信号控制舵机

#include "reg52.h"
unsigned char count; //0.5ms次数标识
sbit pwm =P1^7 ; //PWM信号输出
sbit jia =P3^0; //角度增加按键检测IO口
sbit jan =P3^1; //角度减少按键检测IO口
sbit jianwei=P3^4; //按键位
unsigned char jd; //角度标识
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
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; //11.0592MZ晶振,0.5ms
TR0=1; //定时器开始
}
void Time0_Int() interrupt 1 //中断程序
{
TH0 = 0xfe; //重新赋值
TL0 = 0x33;
if(count<jd) //判断0.5ms次数是否小于角度标识
pwm=1; //确实小于,PWM输出高电平
else
pwm=0; //大于则输出低电平
count=(count+1); //0.5ms次数加1
count=count%40; //次数始终保持为40 即保持周期为20ms
}
void keyscan() //按键扫描
{
if(jia==0) //角度增加按键是否按下
{
delay(10); //按下延时,消抖
if(jia==0) //确实按下
{
jd++; //角度标识加1
count=0; //按键按下 则20ms周期从新开始
if(jd==6)
jd=5; //已经是180度,则保持
while(jia==0); //等待按键放开
}
}
if(jan==0) //角度减小按键是否按下
{
delay(10);
if(jan==0)
{
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;
jianwei=0;
count=0;
Time0_Init();
while(1)
{
keyscan(); //按键扫描
display();
}
}本回答被网友采纳

相关了解……

你可能感兴趣的内容

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 非常风气网