基于51单片机的舵机旋转任意指定角度的程序设计

51智能小车系列文章目录

第一节
基于51单片机霍尔编码器测速、PID算法电机调速系统设计
第一节连接
第二节
基于51单片机的舵机旋转任意指定角度的程序设计



前言

在介绍控制舵机前先简单介绍一下PWM脉宽调制和舵机控制原理。

1.PWM

1.1什么是PWM

PWM,英文名Pulse Width Modulation,是脉冲宽度调制缩写,它是通过对一系列脉冲的宽度进 行调制,等效出所需要的波形(包含形状以及幅值),对模拟信号电平进行数字编码,也就是说通 过调节占空比的变化来调节信号、能量等的变化,占空比就是指在一个周期内,信号处于高电平的 时间占据整个信号周期的百分比,例如方波的占空比就是50%。

1.2如何实现PWM信号输出

  1. 通过芯片内部模块输出,一般观察手册或者芯片IO口都会标明这个是否是PWM口。
  2. 如果没有集成PWM功能,可以通过IO口软件模拟,相对硬件PWM来说精准度略差。

2.控制舵机

2.1什么是舵机

如下图所示,最便宜的舵机sg90,常用三根或者四根接线,黄色为PWM信号控制。
SG90

尺寸:21.5mm * 11.8mm * 22.7mm 重量:9克 (1kg=1公斤=2斤) 无负载速度:0.12秒/60度(4.8V) 0.002s/度 堵转扭矩:1.2-1.4公斤/厘米(4.8V) 使用温度:-30~~+60摄氏度 死区设定:7us (7MHZ) 工作电压:4.8V-6V 位置等级:1024级 脉冲控制精度为2us。

用处:垃圾桶项目开盖用、智能小车的全比例转向、摄像头云台、机械臂等等。

常见的有0-90°、0-180°、0-360°

2.2如何控制舵机

采用PWM控制的方式来进行舵机的操纵,舵机的控制需要MCU产生一个20ms的脉冲信号,以0.5ms到2.5ms的高电平来控制舵机的角度。对于180°舵机的控制数据如下:

0.5ms-------------0度;
1.0ms------------45度;
1.5ms------------90度;
2.0ms-----------135度;
2.5ms-----------180度;


一、接线

舵机的电源线依次对应连接,信号线连接51单片机P2.7口。

二、程序源码

代码如下(示例):

#include <reg52.h>
#include <intrins.h>

sbit PWM = P2^7;  //设定PWM输出的I/O端口

unsigned char count = 0;
unsigned char timer1 ;

unsigned char angle=15;
/*
对于小车
angle=10————左转45度
angle=15————不转0度
angle=20————右转45度
*/
void Timer2_Init(void)		
{
//	T2MOD = 0;	//初始化模式寄存器
		T2CON = 0;	//初始化控制寄存器
		TL2 = 0xA4;	//设置定时初值
		TH2 = 0xFF;	//设置定时初值
		ET2=1;
		EA=1;
		PT2=0;
		TR2 = 1;		//定时器2开始计时
}

void S_pwm()
{
	if(count <= timer1) //5==0° 15==90°
	{ 
		PWM = 1; 
	}
	else 
	{ 
		PWM = 0; 
	}
	count++;
	if (count >= 200) //T = 20ms清零
	{ 
		count = 0; 
	}
	TR0 = 1; //开启T0
}
//中断服务函数模板
void Timer2_Routine() interrupt 5
{
    TF2 = 0;           //中断标志复位
    RCAP2L  = 0xA4;	   //设置低位定时初值
    RCAP2H = 0xFF;	  //设置高位定时初值
	
	S_pwm();

}
 
void turn(signed char angle)
{
	timer1 =angle;
	count=0;		
}

void mian()
{
   //定时器初始化
    Timer2_Init();
    turn(15);//默认0度
   while(1)
   {
       turn(10);//左转45度
   }
}

总结

以上就是今天要讲的内容,本文仅仅简单介绍了舵机旋转指定角度的使用,本人也是小白,如有错误还望指正。

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是基于51单片机控制舵机转动任意角度的详细代码: ```C #include <reg51.h> // 引入51单片机头文件 sbit servo = P1^0; // 定义舵机控制引脚 void main() { unsigned int angle = 0; // 定义角度变量 TMOD = 0x01; // 设置定时器0为模式1 TH0 = 0xFC; // 设定初值,使定时器每10ms中断一次 TL0 = 0x67; TR0 = 1; // 启动定时器0 while(1) { if (angle == 0) { // 如果角度为0,舵机转到初始位置 servo = 1; delay(20); // 延时20ms servo = 0; delay(180); // 延时180ms } else if (angle == 90) { // 如果角度为90,舵机转到中间位置 servo = 1; delay(15); // 延时15ms servo = 0; delay(185); // 延时185ms } else if (angle == 180) { // 如果角度为180,舵机转到最大位置 servo = 1; delay(10); // 延时10ms servo = 0; delay(190); // 延时190ms } else { // 如果角度为其他值,计算脉冲宽度并转动舵机 unsigned int pulse_width = (unsigned int)(angle / 180.0 * 2000.0 + 500.0); // 计算脉冲宽度 servo = 1; delay_us(pulse_width); // 延时脉冲宽度微秒 servo = 0; delay_us(20000 - pulse_width); // 延时20ms减去脉冲宽度微秒 } } } void timer0_isr() interrupt 1 { // 定时器0中断服务程序 TH0 = 0xFC; // 重新赋初值 TL0 = 0x67; } void delay(unsigned int ms) { // 毫秒级延时函数 unsigned int i, j; for(i = ms; i > 0; i--) { for(j = 110; j > 0; j--); } } void delay_us(unsigned int us) { // 微秒级延时函数 unsigned int i, j; for(i = us; i > 0; i--) { for(j = 2; j > 0; j--); } } ``` 上述代码中,使用定时器0每10ms中断一次,并在中断服务程序中重新赋初值,以保证控制舵机的脉冲宽度准确。然后使用一个无限循环,根据角度值计算脉冲宽度并转动舵机。其中,0度、90度和180度的脉冲宽度已经确定,其他角度的脉冲宽度通过公式计算得到。延时函数分别为毫秒级和微秒级,用于控制舵机转动和脉冲宽度延时。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值