首先,就谈谈舵机的控制原理:
舵机有三根线,分别是电源正负极和信号线 。正负极接6V左右的直流电源,信号线则输出PWM脉冲,
PWM的周期为20mm,宽度(高电平的时间)是从0.5ms--2.5ms对应着舵机角度0度到180度。现在我用单片机的一个引脚P0^0接到信号线,我让引脚变化这样:输出高电平,1.5ms后变低电平20-1.5=18.5ms后再变成高电平。舵机就转到90度,实现舵机的摆动。
以下是测试程序:
/**********************************************************************
该程序是实现一个舵机在两个角度之间摆动。0度和90度
***********************************************************************/
#include <12c5a.H> //STC12C5A系列单片机
void delay(uint16 time); //软件延时函数
void Timer_init(); //定时器初始化函数
void Timer0(uint32 us); //定时器0定时函数
uint16 pwm_valu=500;
sbit pwm1=P2^7; //将舵机插到P0^0口上
/**************************************************************************
函数名:main()
/*************************************************************************/
void main()
{
P2M1=0;
P2M0=0XFF; //将P0口设置成强推免输出,提高带负载能力
Timer_init(); //定时器初始化
Timer0(31); //通过一个定时值进入定时循环
while(1)
{
pwm_valu=500; //脉宽=500us=0.5ms即0度位置
delay(1000);
pwm_valu=1500; //脉宽=1500us=1.5ms即90度位置
delay(1000); //舵机在两个角度之间摆动
}
}
/**************************************************************************************************
函数名:delay(uint16 time)
功能: 软件延时函数
参数: time 定时值,其大小与延时长短成正比
/***************************************************************************************************/
void delay(uint16 time)
{
uint16 i;
uint16 j;
for(i=0;i<1000;i++)
for(j=0;j<time;j++);
}
/***************************************************************************
函数名:timer_init()
功能: 定时器初始化函数
备注:12T
/***************************************************************************/
void Timer_init()
{
EA=1; //开总中断
AUXR|=0x00; //T0,T1工作在12T
TMOD|= 0x11; //T0工作在方式1,16位
ET0 = 1; //开定时器0中断
}
/***************************************************************************
函数名:timer0(uint32 us)
功能: 定时器0定时函数
参数: us,毫秒。 精确定时。
备注: 晶振12M,工作模式12T
/***************************************************************************/
void Timer0(uint32 us)
{
uint32 valu;
valu=0xffff-us; //
TH0=valu>>8; //存放高8位
TL0=(valu<<8)>>8; //存放低8为
TR0 = 1; //T0开始工作
}
/*********************************************************************
函数名:T0zd(void) interrupt 1
功能: 定时器0中断函数
/********************************************************************/
void T0zd(void) interrupt 1
{
static uint8 i=1;
switch(i) //
{
case 1:
{
pwm1=1;
Timer0(pwm_valu); //pwm_valu的值在主函数while循环中不断改变,实现舵机在两个角度之间摆动。
//pwm_walu对应着脉宽值
} break;
case 2:
{
pwm1=0;// pwm1变低
Timer0(20000-pwm_valu);// 保证周期是20MS ,即20 000 us
i=0;
} break;
default:break;
}
i++;
}
串口的测试程序
这是单片机串口程序的编写,可以通过串口助手测试
#include "12c5a.h" //STC12C5A系列单片机
void UART1_Init(void);
void main()
{
UART1_Init();//串口初始化
while(1);//单片机一直运行
}
void UART1_Init(void)
{
SCON |= 0x50; //串口1方式1,接收充许
BRT = 0xF6; //12M,波特率38400
AUXR |= 0x15; //串口1使用独立波特率发生器,独立波特率发生器1T
PCON = 0;//0x7F; //波特率不加倍
EA = 1;
ES = 1; //充许串口1中断
}
//把串口收到的数据发送出去
void UART1_SendOneChar(uint8 valu)
{
SBUF = valu;
while(TI == 0);
TI = 0;
}
//串口中断程序
void UART1_Int(void) interrupt 4
{
uint8 redata;
if(RI == 1) // 检测是不是接收数据引起的中断
{
RI = 0;
redata = SBUF;
UART1_SendOneChar(redata); //发送数据
}
}
以上就是单片机对一个舵机的控制测试程序和串口测试程序