51单片机按键控制舵机问题

#include<reg52.h>
#include"DUOJI.h"
void kongzhi(unsigned short q);
sbit OUT=P1^1;
sbit KEY1=P2^0;
sbit KEY2=P2^1;
void main()
{
unsigned short h=60;
kongzhi(h);
while(1)
{
if(KEY1==0)
{ yanshi(10);
if(KEY1==0)
{ while(KEY1==0)
{ if(h<=220)
{ h+=1;
kongzhi(h);
}
}
}
}
if(KEY2==0)
{ yanshi(10);
if(KEY2==0)
{
while(KEY2==0)
{ if(h>=20)
{ h-=1;
kongzhi(h);
}
}
}
}
}
}

void kongzhi(unsigned short q)
{ unsigned short u;
u=q;
OUT=1;
duoji(q);
OUT=0;
duoji(800-q);
}
#ifndef __DUOJI_H__
#define __DUOJI_H__
#include<reg52.h>
void yanshi(unsigned char x)
{ unsigned char i,z;
for(i=0;i<x;i++)
for(z=0;z<120;z++);
}
void duoji(unsigned char i)
{ unsigned char y,a;
for(y=0;y<i;y++)
for(a=0;a<3;a++);
}
#endif
问什么每次上电舵机会忘一边转一小点, unsigned short h=60; kongzhi(h);这句不是让舵机转到终点吗?那个舵机延时函数是25us的,60刚好是1.5ms,如果不是请问怎样才能用软件产生延时来控制舵机啊?跪求大神们,

/**舵机控制——火柴天堂作品-20120314**/
/**50Hz舵机,0.5ms-2.5ms 对应 0-180°(-90°~90°)**/
/**51系列单片机,晶振12MHz,P1.0输出50Hz PWM调制方波(即周期20ms)驱动舵机,方波由T0定时器产生
P11-P17,7个光电检测,P11-130.5°,P12-108°,P13-99°,P14-90°,P15-81°,P16-72°,P17-49.5°,优先级高-低:P14→P11/P17→P12/P16→P13/P15 **/
#include"reg52.h" //包含52系列头文件
#define uchar unsigned char //定义 无符号字符型
#define uint unsigned int //定义 无符号整型
//#define TRUE 1 //定义 逻辑真
//#define FALSE 0 //定义 逻辑假

//最小角度4.5°,时间应该为2ms×4.5°/180°=50us,故定时器T0定时时间为 50us
#define th0 0xce //50us for Model2 at 12HMz Fosc
#define DutyDeno 40 //定义 占空比分母(舵机转动范围) 为:180°/4.5°=40
#define SteeringBasic 10 //舵机基准角 0.5ms, 0.5ms/50us=10
#define SteerineSigne 400 //舵机信号 20ms, 20ms/50us=400
uchar code SteeringList[8]={0,29,24,22,20,18,16,11}; //P11-P17光电检测对应舵机转角列表,单位4.5°,第一个元素为空

sbit PS1=P1^0; //定义 光电开关1 接口
sbit PS2=P1^1; //定义 光电开关2 接口
sbit PS3=P1^2; //定义 光电开关3 接口
sbit PS4=P1^3; //定义 光电开关4 接口
sbit PS5=P1^4; //定义 光电开关5 接口
sbit PS6=P1^5; //定义 光电开关6 接口
sbit PS7=P1^6; //定义 光电开关7 接口
sbit Steering=P1^7; //定义 舵机输出 接口
#define PS1_Value 1 //定义 光电开关1 值
#define PS2_Value 2 //定义 光电开关2 值
#define PS3_Value 3 //定义 光电开关3 值
#define PS4_Value 4 //定义 光电开关4 值
#define PS5_Value 5 //定义 光电开关5 值
#define PS6_Value 6 //定义 光电开关6 值
#define PS7_Value 7 //定义 光电开关7 值

uchar DutyNume; //定义 占空比分子(舵机转角) 变量,单位4.5°

void Timer0() interrupt 1 //定时器T0 中断 函数
{
static uint duty_time=0; //定义静态变量,作为 占空比 输出时间的参考值(50us)
duty_time=++duty_time%SteerineSigne; //该句等效于:duty_time++;duty_time%=SteerineSigne;
if(duty_time<DutyNume+SteeringBasic) Steering=1; //若计时时间小于 占空比分子,则输出应为 高电平
else Steering=0; //若计时时间大于 占空比分子,则输出应为 低电平
}

void TimerInit() //定时器初始化 函数
{
TMOD=0x02; //T0 8位自重装定时器
EA=1; //允许系统中断
ET0=1; //允许T0中断
TH0=th0;
TL0=th0; //50us 初值
TR0=1; //T0开始计时
}

uchar PhotoSwitchScan() //光电开关扫描 函数
{
if(!PS4) return PS4_Value; //返回光电开关对应值
if(!PS1) return PS1_Value;
if(!PS7) return PS7_Value;
if(!PS2) return PS2_Value;
if(!PS6) return PS6_Value;
if(!PS3) return PS3_Value;
if(!PS5) return PS5_Value; //返回光电开关对应值
return PS4_Value; //其它情况,均保持跟最高级别一致
}

void PhotoSwitchResp() //光电开关响应 函数
{
//uchar PS_value=PhotoSwitchScan(); //扫描光电开关
//if(PS_value)DutyNume=SteeringList[PS_value]; //占空比分子 加1,即舵机转角加4.5°,到180°后,再加归零
DutyNume=SteeringList[PhotoSwitchScan()];
}

void main() //主函数
{
TimerInit(); //调用 定时器初始化 函数
while(1) //循环系统
{
PhotoSwitchResp(); //调用 光电开关响应 函数
}
}
温馨提示:答案为网友推荐,仅供参考
第1个回答  2015-04-04
需要给你写一份吗追问

你能不能给我详细讲解讲解?因为刚学单片机 C语言也不是很过关,就是一小白

追答

代做的