历史上的今天
今天是:2025年02月27日(星期四)
2020年02月27日 | STC单片机关于舵机pwm控制源程序(单个与多个速度控制都有)
2020-02-27 来源:51hei
单片机源程序如下:
/*****************************************************************************
** 文件: main.c
** 作者: Zheng23
** 日期:
** 功能:产生8路PWM输出控制8路舵机,方法:将20毫秒分成8个2500微秒,
即8个单元,先计算出第一个单元的舵机PWM控制线的脉冲宽度,因
为控制舵机的脉冲宽度最大为2500微秒,剩余的(20000 - 2500)
毫秒就是剩下的7个单元时间,第一个单元的舵机PWM控制线全部为
低电平了,这时就可以安心的处理剩下的7个单元的事情了,同理
第二个单元也是一样,这样循环下去就可以控制8路PWM输出了。
/*****************************************************************************/
//#include //#include"STC89C5xRC.H" //一定要用12M的晶振 //一定要用12M的晶振 //一定要用12M的晶振 //一定要用12M的晶振 //一定要用12M的晶振 //一定要用12M的晶振 #include "reg51.h" #define bool bit #define uint8 unsigned char #define uint16 unsigned short int #define uint32 unsigned long sbit SERVO0=P0^0; //控制舵机的PWM输出口 sbit SERVO1=P0^1; sbit SERVO2=P0^2; sbit SERVO3=P0^3; sbit SERVO4=P0^4; sbit SERVO5=P0^5; sbit SERVO6=P0^6; sbit SERVO7=P0^7; sbit LED=P2^7; //调试用 uint16 ServoPwmDuty[8] = {1500,1500,1500,1500,1500,1500,1500,1500}; //PWM脉冲宽度 uint16 ServoPwmDutySet[8] = {1500,1500,1500,1500,1500,1500,1500,1500}; //PWM脉冲宽度 double ServoPwmDutyInc[8]; //为了速度控制,当PWM脉宽发生变化时,每2.5ms或20ms递增的PWM脉宽 bool Flag_20ms = 0; //20毫秒标识位,在定时中断里面置位 bool Flag_2_5ms = 0; //2.5毫秒标识位,在定时中断里面置位 bool ServoPwmDutyHaveChange = 0; //脉宽有变化标志位 uint16 ServoTime = 2000; //舵机从当前角度运动到指定角度的时间,也就是控制速度 /*********************************************************** * 名 称: DelayMs(uint16 ms) * 功 能: 延时ms毫秒 * 入口参数: ms 毫秒 * 出口参数: 无 * 说 明: /**********************************************************/ void DelayMs(uint16 ms) { uint16 i,j; for(i=0;i<800;i++) //89单片机用85,12系列单片机用800 for(j=0;j /*********************************************************** * 名 称:InitTimer0() * 功 能:时钟0初始化 * 入口参数:无 * 出口参数:无 * 说 明:12M晶振,12分频,所以计数器每递增一个数就是1微秒,完全满足舵机控制的精度要求 因为定时器是TH0,TL0都要全部计数到0xFF后在计1个数就会产生中断,所以要想产生 x毫秒的中断,那么TH0,TL0就应该赋值(0xFFFF-x) 从这个值开始计数产生定时中断 /**********************************************************/ void InitTimer0(void) { // AUXR &= 0x7F; //定时器时钟12T模式 // AUXR |= 0x00; //T0,T1工作在12T TMOD &= 0xF0; //设置定时器模式 TMOD |= 0x01; //设置定时器模式 TL0 = 0x00; //设置定时初值 TH0 = 0x00; //设置定时初值 TF0 = 0; //清除TF0标志 TR0 = 1; //定时器0开始计时 ET0 = 1; //开定时器0中断 } /*********************************************************** * 名 称:Timer0Value(uint16 pwm) * 功 能:给定时器0计数器赋值产生定时中断 * 入口参数:pwm 控制舵机的PWM脉冲宽度值(范围:500~2500) * 出口参数:无 * 说 明:12M晶振,12分频,所以计数器每递增一个数就是1微秒,完全满足舵机控制的精度要求 因为定时器是TH0,TL0都要全部计数到0xFF后在计1个数就会产生中断,所以要想产生 pwm毫秒的中断,那么TH0,TL0就应该赋值(0xFFFF-pwm) 从这个值开始计数产生定时中断 /**********************************************************/ void Timer0Value(uint16 pwm) { uint16 value; value=0xffff-pwm; TR0 = 0; TL0=value; //16位数据给8位数据赋值默认将16位数据的低八位直接赋给八位数据 TH0=value>>8; //将16位数据右移8位,也就是将高8位移到低八位,再赋值给8位数据 TR0 = 1; } /*********************************************************** * 名 称: ServoPwmDutyCompare() * 功 能: 脉宽变化比较及速度控制 * 入口参数: 无 * 出口参数: 无 * 说 明: /**********************************************************/ void ServoPwmDutyCompare() { uint8 i; static uint16 ServoPwmDutyIncTimes; //需要递增的次数 static bool ServoRunning = 0; //舵机正在以指定速度运动到指定的脉宽对应的位置 if(ServoRunning == 0 && ServoPwmDutyHaveChange)//停止运动并且脉宽发生变化时才进行计算 { ServoPwmDutyHaveChange = 0; // ServoPwmDutyIncTimes = ServoTime*2/5; //ServoTime/(20/8) //当每2.5ms调用一次ServoPwmDutyCompare()函数时用此句 ServoPwmDutyIncTimes = ServoTime/20; //当每20ms调用一次ServoPwmDutyCompare()函数时用此句 for(i=0;i<8;i++) { //if(ServoPwmDuty[i] != ServoPwmDutySet[i]) { if(ServoPwmDutySet[i] > ServoPwmDuty[i]) { ServoPwmDutyInc[i] = ServoPwmDutySet[i] - ServoPwmDuty[i]; ServoPwmDutyInc[i] = -ServoPwmDutyInc[i]; } else { ServoPwmDutyInc[i] = ServoPwmDuty[i] - ServoPwmDutySet[i]; } ServoPwmDutyInc[i] /= ServoPwmDutyIncTimes;//每次递增的脉宽 } } ServoRunning = 1; //舵机开始动作 } if(ServoRunning) { ServoPwmDutyIncTimes--; for(i=0;i<8;i++) { if(ServoPwmDutyIncTimes == 0)
史海拾趣
|
C/C++ code //Send.exe keybd_event(VK_MENU, 0x0, KEYEVENTF_SILENT, 0); keybd_event(VK_MENU, 0x0, KEYEVENTF_SILENT | KEYEVENTF_KEYUP, 0); //Rev.exe BOOL CRev::PreTranslateMessage(MSG* pMsg) { &n ...… 查看全部问答> |
|
SHNotificationAdd在WINCE 5.0 .net下不弹出气泡通知 如下代码在windows mobile手机上是可以弹出气泡的,但是在wince 5.0开发板上弹不出来.根据MSDN似乎应该是可以的。 SHNP_INFORM Notification bubble displays for the set duration, then disappears. Note For Windows Mobile, this enum ...… 查看全部问答> |
|
CPU:S3C2440 调试环境:H-JTAG+ADS1.2 问题:读出501ID号不对 详述:501作为2440的图像显示模块,与2440连接方式为非 UMA方式,MMIO_BASE=0x2000_0000+0x03E0_0000,501上电 后MMIO_BASE+0x000060寄存器中初始化为0x0501xxa0,但 目前读出的数据 ...… 查看全部问答> |
|
1. S/W Engineer (Codec) 1) 4+ years working experience of video, audio codec development 2) Candidates should have strong knowledge and hands-on experience on MPEG-2/4, H.264, AAC/AAC+ algorithm 3) C/C++ and Verilog HDL program ...… 查看全部问答> |
|
ERROR: The Top module has not been specified. This can happen if no sources have been added to the project, 是什么意思?… 查看全部问答> |
|
这芯片怎么回事,我使用了SD16A的第一、二、三通道(AIN0、AIN1、AIN2),每五通道(AIN4)与TIMERA的PWM(TA1、TA2)是同一个引脚。我使用了PWM输出。在使用中发现,只要我打开SD16A的第三通道,TA1引脚输出就一直为低电平,不受PWM控制,当我关掉 ...… 查看全部问答> |
|
我在SD卡上构建dosfs文件系统是总是出错: 代码如下 #include \"copyright_wrs.h\"#include \"vxWorks.h\"#include \"taskLib.h\"#include \"blkIo.h\"#include \"stdlib.h\"#include \"stdio.h\"#include \"string.h\"#include \"dosFsLib.h\"#i ...… 查看全部问答> |




