求大神,12M晶振stc89c52驱动舵机,舵机不转
时间:10-02
整理:3721RD
点击:
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit KEY1 = P3^5; //定义调速的按键
sbit DC = P1^0; //定义舵机的控制端口
uchar CYCLE; //定义周期
uchar PWM; //定义低电平时间
/*********************************
函数:Delay_1ms()
参数:t
返回:无
功能:延时子程序,延时时间为 1ms * del。
使用晶振是12M。
**********************************/
void Delay_1ms(uchar c)
//{
// uint i,j;
// for(i=0;i<t;i++)
// {
// for(j=0;j<=100;j++)
// {
// _nop_();
// }
// }
//}
//{
// unsigned char a,b;
// for(;c>0;c--)
// for(b=38;b>0;b--)
// for(a=130;a>0;a--);
//}
{
uchar a,b;
for(;c>0;c--)
for(b=142;b>0;b--)
for(a=2;a>0;a--);
}
/*********************************
函数:Time0Init()
参数:无
返回:无
功能:设置定时器0的工作方式2定时时长为100微秒,
并打开中断和启动定时器。
该例中使用的单片机晶振为12M。
**********************************/
void Time0Init(void)
{
TMOD = 0x02; //设定定时器0工作在方式2模式
TH0 = 0x00; //定时时长为100微秒的初值自动重载
TL0 = 0x9C; //定时时长为100微秒的初值
ET0 = 1; //打开定时器0中断
EA = 1; //打开总中断
TR0 = 1; //启动定时器
}
/*********************************
函数:Time0Int()
参数:无
返回:无
说明:定时器0中断函数。用于处理PWM的信号。
**********************************/
void Time0Int(void) interrupt 1
//using 1
{
static uchar Count; //当前处于周期的什么时刻
TH0 = 0x00; //定时时长为100微秒的初值自动重载
TL0 = 0x9C;
if(Count >= PWM) //判断低电平时间是否结束
{
DC = 1; //
}
else DC= 0;
Count++;
if(Count == 200) //一个周期结束
{
Count=0;
if(PWM != 0) //如果左右时间是0 保持原来状态
{
DC = 0; //
}
}
}
/*********************************
函数:Key()
参数:无
返回:无
功能:判断KEY1是否按下并让数码管显示和给PWM提供低电平时长。
**********************************/
void Key(void)
{
static uchar Number = 1; //定义档位,初始化为1档
if(KEY1 == 0) // 判断是否有按键按下
{
Delay_1ms(15); //延时抗干扰信号
if(KEY1 == 0) //再次判断是否有按键按下
{
Number++; //按一下P3.2口,就给直流电机换一个档位
if(Number == 6) //等于6时,给档位重新赋值1
{
Number = 1;
}
switch(Number)
{
case 1:
{
P0=0x06; //数码管显示1
PWM=175; //高电平2.5毫秒,舵机旋转到右极限(为+90度)
break;
}
case 2:
{
P0=0x5B; //数码管显示2
PWM=180; //高电平2毫秒,舵机旋转角度为+45度
break;
}
case 3:
{
P0=0x4F; //数码管显示3
PWM=185; //高电平1.5毫秒,舵机旋转角度为0度
break;
}
case 4:
{
P0=0x66; //数码管显示4
PWM=190; //高电平1毫秒,舵机旋转角度为-45度
break;
}
case 5:
{
P0=0x6d; //数码管显示5
PWM=195; //高电平0.5毫秒,舵机旋转角度为-90度
break;
}
default:
break;
}
while(1) //按键释放
{
if(KEY1 == 1) //判断是否释放
{
break;
}
}
}
}
}
/*********************************
函数:Main()
参数:无
返回:无
功能:主函数
**********************************/
void Main(void)
{
Time0Init(); //定时器0初始化
// Time0Int();
CYCLE = 200; //定义PWM周期为20毫秒
P0 = 0xfe; //数码管最后一位亮
while(1)
{
Key();
}
}
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit KEY1 = P3^5; //定义调速的按键
sbit DC = P1^0; //定义舵机的控制端口
uchar CYCLE; //定义周期
uchar PWM; //定义低电平时间
/*********************************
函数:Delay_1ms()
参数:t
返回:无
功能:延时子程序,延时时间为 1ms * del。
使用晶振是12M。
**********************************/
void Delay_1ms(uchar c)
//{
// uint i,j;
// for(i=0;i<t;i++)
// {
// for(j=0;j<=100;j++)
// {
// _nop_();
// }
// }
//}
//{
// unsigned char a,b;
// for(;c>0;c--)
// for(b=38;b>0;b--)
// for(a=130;a>0;a--);
//}
{
uchar a,b;
for(;c>0;c--)
for(b=142;b>0;b--)
for(a=2;a>0;a--);
}
/*********************************
函数:Time0Init()
参数:无
返回:无
功能:设置定时器0的工作方式2定时时长为100微秒,
并打开中断和启动定时器。
该例中使用的单片机晶振为12M。
**********************************/
void Time0Init(void)
{
TMOD = 0x02; //设定定时器0工作在方式2模式
TH0 = 0x00; //定时时长为100微秒的初值自动重载
TL0 = 0x9C; //定时时长为100微秒的初值
ET0 = 1; //打开定时器0中断
EA = 1; //打开总中断
TR0 = 1; //启动定时器
}
/*********************************
函数:Time0Int()
参数:无
返回:无
说明:定时器0中断函数。用于处理PWM的信号。
**********************************/
void Time0Int(void) interrupt 1
//using 1
{
static uchar Count; //当前处于周期的什么时刻
TH0 = 0x00; //定时时长为100微秒的初值自动重载
TL0 = 0x9C;
if(Count >= PWM) //判断低电平时间是否结束
{
DC = 1; //
}
else DC= 0;
Count++;
if(Count == 200) //一个周期结束
{
Count=0;
if(PWM != 0) //如果左右时间是0 保持原来状态
{
DC = 0; //
}
}
}
/*********************************
函数:Key()
参数:无
返回:无
功能:判断KEY1是否按下并让数码管显示和给PWM提供低电平时长。
**********************************/
void Key(void)
{
static uchar Number = 1; //定义档位,初始化为1档
if(KEY1 == 0) // 判断是否有按键按下
{
Delay_1ms(15); //延时抗干扰信号
if(KEY1 == 0) //再次判断是否有按键按下
{
Number++; //按一下P3.2口,就给直流电机换一个档位
if(Number == 6) //等于6时,给档位重新赋值1
{
Number = 1;
}
switch(Number)
{
case 1:
{
P0=0x06; //数码管显示1
PWM=175; //高电平2.5毫秒,舵机旋转到右极限(为+90度)
break;
}
case 2:
{
P0=0x5B; //数码管显示2
PWM=180; //高电平2毫秒,舵机旋转角度为+45度
break;
}
case 3:
{
P0=0x4F; //数码管显示3
PWM=185; //高电平1.5毫秒,舵机旋转角度为0度
break;
}
case 4:
{
P0=0x66; //数码管显示4
PWM=190; //高电平1毫秒,舵机旋转角度为-45度
break;
}
case 5:
{
P0=0x6d; //数码管显示5
PWM=195; //高电平0.5毫秒,舵机旋转角度为-90度
break;
}
default:
break;
}
while(1) //按键释放
{
if(KEY1 == 1) //判断是否释放
{
break;
}
}
}
}
}
/*********************************
函数:Main()
参数:无
返回:无
功能:主函数
**********************************/
void Main(void)
{
Time0Init(); //定时器0初始化
// Time0Int();
CYCLE = 200; //定义PWM周期为20毫秒
P0 = 0xfe; //数码管最后一位亮
while(1)
{
Key();
}
}
换个自带PWM的单片机吧,定时器作为PWM的发生源不好用,而且舵机是靠一定频率的PWM来驱动的,是周期小于2ms的PWM,stc系列的就选stc12c5a60s2吧,它有两路PWM。频率可通过定时器来调。很方便。