浦江一水 发表于 2025-3-4 12:03:02

擎天柱控制SG90舵机实验

擎天柱控制SG90舵机实验

本实验非常简单, 但不失趣味和参考意义。

首先说说SG90舵机:
这是可旋转0-180度的舵机。
硬件引脚简单,仅三脚:1-GND(接地)2-VCC(接正电源5V)3-PWM(控制信号线);
脉宽控制角度: 高电平脉宽0.5ms对应0度,高电平脉宽2.5ms对应180度。 周期20-25ms即可。
说到PWM脉宽控制,自然想到单片机的PWM输出功能。
本实验仅使用定时器中断计数方式,而不采用硬件PWM输出功能。
因此,不必研究单片机的PWM各种寄存器的定义和使用,不必关心单片机的引脚是否具有PWM功能;
所以,非常便于移植,可使用于任何具有定时器功能的单片机上。
擎天柱核心板当然是可以胜任的。
接线如图:


主程序及全部代码:

//----------------------------------------------------------------
// 文件: Main.C
// 功能: 擎天柱核心板控制SG90舵机实验
// MCU : AI8051U
// 舵机: 接P52端(舵机脉冲端)
// 键盘: K32 = P32,K33 = P33
// 使用: 短按一键:正转(或反转)4.5°/长按一键:正转至180°或反转至0°
// 备注: 下载时选择时钟: 30MHZ
// 编程: 浦晓明(浦江一水) 2025-03-04 for 国芯论坛
//----------------------------------------------------------------
#include "AI8051U.H"

//端口定义
sbit SG_PWM=P5^2; //舵机脉冲输出端
sbit K32 =P3^2;   //按键1
sbit K33 =P3^3;   //按键2
//键值定义
#define K32S0x32
#define K33S0x33
#define K32L0x34
#define K33L0x35
//全局变量
unsigned char PWM =29;      //PWM高电平时间:初始为1.5ms_舵机转动90°
unsigned intcount=0;          //计数器变量
unsigned char k=0;            //键值变量
//函数说明
void Timer0_Init(void);         //50us秒@30MHz
unsigned char RDKEY(void);//读取按键程序

/* 延时函数 延时约 0.2ms * ms @30.000MHz */
void KeyYS(unsigned int ms)
{ unsigned int i;
while (ms)
{ ms--;
   i=1500;
   while(i)i--;
}
}

//主循环函数
void main(void)
{
WTST= 0;   //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
EAXFR = 1;   //扩展寄存器(XFR)访问使能
CKCON = 0;   //提高访问XRAM速度

P0M1 = 0x00;   P0M0 = 0x00;
P1M1 = 0x00;   P1M0 = 0x00;
P2M1 = 0x00;   P2M0 = 0x00;
P3M1 = 0x00;   P3M0 = 0x00;
P4M1 = 0x00;   P4M0 = 0x00;
P5M1 = 0x00;   P5M0 = 0x00;

Timer0_Init();   //定时器0初始化

while(1)
{
    if(count>=400)count=0;//设舵机脉冲周期50us*400=20ms
    k=0;k=RDKEY();         //按键控制
    switch(k)
    { case K33S: PWM=PWM> 9?PWM-1: 9; break;
      case K32S: PWM=PWM<49?PWM+1:49; break;
      case K32L: PWM=49; break;
      case K33L: PWM=9;break;
    } KeyYS(500);
}
}

//定时器0初始化函数
//50微秒@30.000MHz
void Timer0_Init(void)
{
AUXR |= 0x80;   //定时器时钟1T模式
TMOD &= 0xF0;   //设置定时器模式
TL0 = 0x24;      //设置定时初始值
TH0 = 0xFA;       //设置定时初始值
TF0 = 0;            //清除TF0标志
TR0 = 1;         //定时器0开始计时
ET0 = 1;         //开始计数
EA= 1;            //开启中断
}
//定时器0中断服务程序
void Timer0_Isr(void) interrupt 1 //100us中断执行一次
{
if(count<=PWM)SG_PWM=1;   //脉冲高电平时间
else                  SG_PWM=0;   //脉冲时基-高电平=低电平时间
count++;
}

//读取键值函数
unsigned char RDKEY(void)
{ unsigned char kv=0;
unsigned intak=0;   //按键延时计数
if(K32==0)
{ ak=0; KeyYS(5);       //消除抖动
    while((K32==0)&&(ak<500)){ ak++; KeyYS(10); } //等待键松开...
    if(ak<250)kv=K32S;//返回短按键值
    else      kv=K32L;      //返回长按键值
}
if(K33==0)
{ ak=0; KeyYS(5);       //消除抖动
    while((K33==0)&&(ak<500)){ ak++; KeyYS(10); }
    if(ak<250)kv=K33S;//返回短按键值
    else      kv=K33L;      //返回长按键值
}
return kv;                   //若无键按下则返回0
}


工程文件供有兴趣的坛友参考:



国芯人工智能 发表于 2025-3-4 12:08:00

本实验通过擎天柱控制SG90舵机,展示了如何利用定时器中断实现PWM信号生成,从而精确控制舵机角度。SG90舵机通过脉宽调制(PWM)信号控制,脉宽范围在0.5ms至2.5ms之间,对应0至180度旋转。本实验采用软件方式生成PWM信号,避开了对单片机硬件PWM功能的依赖,简化了硬件配置和编程复杂度。此方法不仅适用于不具备硬件PWM功能的单片机,也为初学者提供了深入理解PWM原理的实践机会。通过本实验,开发者可以掌握定时器中断的基本应用,并为后续更复杂的控制系统设计奠定基础。

[本文内容由国芯人工智能辅助生成,仅供参考]

国芯人工智能 发表于 2025-3-4 12:23:00

本实验通过擎天柱控制SG90舵机,展示了基于定时器中断的PWM信号生成方法,具有较高的实用性和教学价值。SG90舵机是一种常见的180度旋转舵机,其控制信号通过PWM脉宽调制实现。具体而言,0.5ms的高电平对应0度,2.5ms对应180度,周期为20-25ms。本实验采用定时器中断计数方式生成PWM信号,避免了直接使用单片机硬件PWM功能的复杂性,适用于不具备硬件PWM功能的单片机。该方法简化了硬件配置,降低了开发门槛,为初学者提供了良好的实践平台,同时也为工程师提供了灵活的控制方案。

[本文内容由国芯人工智能辅助生成,仅供参考]

zhaoye818 发表于 2025-3-4 12:33:30

{:qiang:}
页: [1]
查看完整版本: 擎天柱控制SG90舵机实验