舵机程序
- 格式:pdf
- 大小:1.38 MB
- 文档页数:4


stm32控制舵机程序章节标题:基于STM32的舵机控制程序设计第一章:引言(约250字)1.1 研究背景控制舵机是机器人、无人机、航空模型等众多领域的关键技术之一。
而STM32系列的微控制器以其高性能、低功耗和丰富的外设资源被广泛应用于嵌入式控制系统。
本章主要介绍了舵机的作用及其在控制系统中的重要性,同时说明了选择STM32微控制器作为控制舵机的硬件平台的原因。
第二章:控制理论(约250字)2.1 舵机原理舵机是一种能够根据外部输入信号控制角度的电动执行器。
其通过接收PWM信号来确定输出位置和角度,通常在0至180度之间运动。
本章介绍了舵机的工作原理,包括PWM控制信号的作用、舵机内部的反馈控制电路等内容。
2.2 PID控制理论PID控制是一种常用的闭环控制方法,能够根据反馈信号调整输出信号,通过比较实际输出与期望输出的差异来实现控制。
本章详细介绍了PID控制的原理和算法,并提出了使用PID控制舵机的基本思路。
第三章:硬件设计(约250字)3.1 系统框架在舵机控制系统中,使用STM32微控制器作为控制芯片,通过引脚与舵机进行连接,实现对舵机的控制。
本章主要介绍了硬件设计的系统框架,包括STM32微控制器的选择、电源设计、信号输入输出设计等。
3.2 电路原理图本章详细描述了电路原理图设计,包括电源管理模块、驱动电路等详细设计内容。
同时对于舵机的接线方式和引脚定义进行了说明。
第四章:软件设计(约250字)4.1 程序流程本章介绍了在STM32上开发舵机控制程序的流程,包括初始化舵机控制模块、设置PWM输出引脚、编写控制算法等。
4.2 PID算法实现详细描述了如何在STM32上实现PID控制算法,包括参数调整、误差计算、控制输出计算等步骤。
同时,结合实际舵机控制需求,对PID控制算法进行优化。
4.3 实验验证通过实验验证了基于STM32的舵机控制程序的有效性和性能优势。
通过与传统控制方法进行对比,并分析实验数据,评估了该程序的稳定性和响应速度。
舵机控制程序 Final revision on November 26, 2020在机器人机电控制系统中,舵机控制效果是性能的重要影响因素。
舵机可以在微机电系统和航模中作为基本的输出执行机构,其简单的控制和输出使得单片机系统非常容易与之接口。
舵机是一种位置伺服的驱动器,适用于那些需要角度不断变化并可以保持的控制系统。
其工作原理是:控制信号由接收机的通道进入信号调制芯片,获得直流偏置电压。
它内部有一个基准电路,产生周期为20ms,宽度为的基准信号,将获得的直流偏置电压与电位器的电压比较,获得电压差输出。
最后,电压差的正负输出到电机驱动芯片决定电机的正反转。
当电机转速一定时,通过级联减速齿轮带动电位器旋转,使得电压差为0,电机停止转动。
舵机的控制信号是PWM信号,利用占空比的变化改变舵机的位置。
一般舵机的控制要求如图1所示。
图1 舵机的控制要求单片机实现舵机转角控制可以使用FPGA、模拟电路、单片机来产生舵机的控制信号,但FPGA成本高且电路复杂。
对于脉宽调制信号的脉宽变换,常用的一种方法是采用调制信号获取有源滤波后的直流电压,但是需要50Hz(周期是20ms)的信号,这对运放器件的选择有较高要求,从电路体积和功耗考虑也不易采用。
5mV以上的控制电压的变化就会引起舵机的抖动,对于机载的测控系统而言,电源和其他器件的信号噪声都远大于5mV,所以滤波电路的精度难以达到舵机的控制精度要求。
也可以用单片机作为舵机的控制单元,使PWM信号的脉冲宽度实现微秒级的变化,从而提高舵机的转角精度。
单片机完成控制算法,再将计算结果转化为PWM信号输出到舵机,由于单片机系统是一个数字系统,其控制信号的变化完全依靠硬件计数,所以受外界干扰较小,整个系统工作可靠。
单片机系统实现对舵机输出转角的控制,必须首先完成两个任务:首先是产生基本的PWM周期信号,本设计是产生20ms的周期信号;其次是脉宽的调整,即单片机模拟PWM信号的输出,并且调整占空比。
pwm控制舵机程序章节一:引言在机器人工程和自动化领域中,舵机是常用的控制组件之一。
它具有小型化、高功率密度、高稳定性和高精度控制等优点,被广泛应用于机械手臂、无人机、汽车模型等领域。
PWM(脉宽调制)技术是一种常用的舵机控制方法,通过调整PWM信号的占空比来控制舵机的位置和角度。
本论文将介绍PWM控制舵机的原理和实现方法,以及相关的电路设计和程序编写。
本文的目的是帮助读者理解PWM控制舵机的基本原理和实现过程,并为舵机控制系统的设计和开发提供参考。
章节二:PWM控制舵机原理2.1 脉宽调制技术脉宽调制技术是一种将模拟信号转换为数字信号的方法。
它通过改变数字信号中的脉冲宽度来模拟模拟信号的幅度变化。
在PWM控制舵机中,通常使用的是固定频率的PWM信号。
通常,脉宽调制技术通过改变脉冲的占空比(High电平的时间与周期的比值)来实现不同的输出。
2.2 舵机工作原理舵机是一种基于PWM信号控制的电机。
它通过接收PWM信号来控制转轴的角度。
舵机通常由电机、伺服控制电路和位置反馈元件组成。
伺服控制电路将接收到的PWM信号与位置反馈进行比较,并控制电机的转动来实现所需的舵机位置和角度。
章节三:PWM控制舵机的电路设计3.1 舵机电路原理图本文设计的舵机电路采用基于微控制器的PWM信号发生器和舵机驱动器。
PWM信号发生器负责产生固定频率的PWM信号,而舵机驱动器负责将PWM信号转换为电机驱动信号以控制舵机的转动。
电路的主要部分是使用可编程微控制器作为信号发生器和驱动器的核心组件。
3.2 电路参数设计本文设计的电路需要满足舵机的工作电压、驱动电流和PWM信号的频率要求。
根据所选用的舵机型号和规格,确定电路中的关键参数,包括驱动电压、最大输出电流、PWM信号频率等。
章节四:PWM控制舵机程序编写4.1 硬件初始化在编写PWM控制舵机程序之前,首先需要进行硬件初始化,包括设置PWM信号发生器和驱动器的引脚和参数,以及舵机电路的供电。
//*************************************************************** **********//* *//* *************************舵机控制************************ * //* *//*************************************************************** **********#include "main.h"UINT8 Far_Line;UINT8 Near_Line;UINT8 Far_Value;UINT8 Near_Value;UINT16 OUT;UINT8 Angle_Far;UINT8 Angle_Start;//*************************************************************** **********//* *//* **********************图像滤波处理函数********************* * //* 函数:void ImageFilterII(UINT8 f_line)//* 函数功能:至多连续4行0可以做处理*//* 输入参数:无//*************************************************************** **********UINT8 IsStraight(UINT8 start_ln,UINT8 end_ln){UINT8 i;UINT8 flg = 0;for(i=start_ln;i<end_ln;i++){if(((GuideLine[i] - GuideLine[i+1] > 7)||(GuideLine[i] - GuideLine[i+1] < (-7)))||(GuideLine[i] == 0)){flg = 1;break;}}if(flg == 0) //是否为直线判定{return 1;}else{return 0;}}//*************************************************************** **********//* *//* **********************图像滤波处理函数********************* * //* 函数:void ImageFilterII(UINT8 f_line)//* 函数功能:至多连续4行0可以做处理*//* 输入参数:无//*************************************************************** **********void ImageFilterII(UINT8 f_line){UINT8 i,j;INT8 div;UINT8 start_ln,end_ln;j=0;Angle_Far = 22;for(i=1;i<f_line;i++){if((GuideLine[i]==0)&&(GuideLine[i-1]!=0)){j=i; //由有数据到无数据}if((GuideLine[i]==0)&&(GuideLine[i+1]!=0)) //由无数据到有数据{if((i-j < 4) //一般的滤波,最多滤除4行&&(GuideLine[j-1] - GuideLine[i+1] < 16)&&(GuideLine[j-1] - GuideLine[i+1] > (-16))){for(;j<i+1;j++){GuideLine[j]=(GuideLine[j-1]>>1)+(GuideLine[i+1]>>1);}}else if(i-j < 12) // 出现黑三角的判定{Angle_Far = j;// far_ln = 8 则要到18行才出现黑线// far_ln = 10 则要到19行才出现黑线// far_ln = 13 则要到21行才出现黑线// far_ln = 15 则要到23行才出现黑线// far_ln = 19 则要到25行才出现黑线start_ln = i + 1;if(f_line - i >= 4){end_ln = i + 4;}else{break;}if((IsStraight(start_ln,end_ln))&&(j > 7)){Angle_Start = 1; //出现了黑三角for(;j<=i;j++){GuideLine[j] = (GuideLine[j-1]>>1)+(GuideLine[i+1]>>1);}}else{for(;j<f_line;j++){GuideLine[j+1] = 0;}break; //跳出整个程序}}else{for(;j<f_line;j++){GuideLine[j+1] = 0;}break; //跳出整个程序}}}UINT8 TEST_CTL_FLG;UINT8 Last_far_ln;UINT8 p1=0;UINT8 p2=0;UINT8 p3=0;UINT8 p4=0;UINT8 d1=0;UINT8 d2=0;UINT8 d3=0;UINT8 d4=0;UINT8 Lv1=0;UINT8 Lv2=0;UINT8 Lv3=0;UINT8 Lv4=0;UINT8 sL=0;UINT8 rL=0;//*************************************************************** **********//* *//* **********************图像滤波处理函数********************* * //* 函数:void ImageFilterII(UINT8 f_line)//* 函数功能:至多连续4行0可以做处理*//* 输入参数:无//*************************************************************** **********void PID_NEW(UINT8 near_ln,UINT8 far_ln,UINT8 filter_line){struct _Car *temp1;UINT8 i;UINT8 p,d;temp1 = &Car;ImageFilterII(filter_line);while(GuideLine[far_ln]==0) //处理行没有提取黑线{far_ln--;if(far_ln==0)break;}TEST_CTL_FLG = 0;Far_Line = far_ln;Far_Value = GuideLine[far_ln];Near_Value = GuideLine[near_ln];//黑三角检测和控制if(Angle_Start == 1) //进入三角{TEST_CTL_FLG = 1;if((Angle_Far >= 22)&&(far_ln >= 22)){Angle_Start = 0;}if(far_ln < 20){goto loop;}}temp1->CtrlPar.Lst_Erro = GuideLine[near_ln] - VIDEO_CENTER; //近线偏差temp1->CtrlPar.Erro = GuideLine[far_ln] - VIDEO_CENTER; //远线偏差temp1->CtrlPar.Dif_Erro = temp1->CtrlPar.Erro - temp1->CtrlPar.Lst_Erro; //远线偏差减近线偏差if(far_ln>Lv1){TEST_CTL_FLG = 2;temp1->CtrlPar.Dty_Erro = ((p1*(temp1->CtrlPar.Erro))>>4)+ ((d1*(temp1->CtrlPar.Dif_Erro))>>4); }else if(far_ln>Lv2) //弯道上的转角{//分段控制,增大弯道转角????TEST_CTL_FLG = 3;//远线偏差加远线偏差减近线偏差(弯道时起加大偏转作用)p=p2;d=d2;if(far_ln>Lv3){TEST_CTL_FLG = 4;p=p3; //大S弯交接入口d=d3;}if(far_ln>Lv4){ TEST_CTL_FLG = 5; //大S弯交接处p=p4;d=d4;}temp1->CtrlPar.Dty_Erro = ((p*(temp1->CtrlPar.Erro))>>4)+ ((d*(temp1->CtrlPar.Dif_Erro))>>4);}temp1->CtrlPar.Dty_Out =STEER_DTY_CENTER + temp1->CtrlPar.Dty_Erro;if(Straight_Cnt>12) //直道刚进入弯道;值越大,越提前入弯{if(far_ln<sL) //判断是否最远行太近{TEST_CTL_FLG = 6;if(temp1->CtrlPar.Dty_Out > STEER_DTY_CENTER){temp1->CtrlPar.Dty_Out = STEER_DTY_MAX ;}else if(temp1->CtrlPar.Dty_Out < STEER_DTY_CENTER){temp1->CtrlPar.Dty_Out = STEER_DTY_MIN ;}}}else if(Straight_Cnt<=12) //已经在弯道{if(far_ln <= rL){TEST_CTL_FLG = 7;if(temp1->CtrlPar.Dty_Out > STEER_DTY_CENTER) //如果太近判断之前舵机转向直接偏到最大{temp1->CtrlPar.Dty_Out = STEER_DTY_MAX;}else if(temp1->CtrlPar.Dty_Out < STEER_DTY_CENTER){temp1->CtrlPar.Dty_Out = STEER_DTY_MIN;}}}loop:if(temp1->CtrlPar.Dty_Out > STEER_DTY_MAX){temp1->CtrlPar.Dty_Out = STEER_DTY_MAX;}else if(temp1->CtrlPar.Dty_Out < STEER_DTY_MIN){temp1->CtrlPar.Dty_Out = STEER_DTY_MIN;}SetDirection(temp1->CtrlPar.Dty_Out);OUT = temp1->CtrlPar.Dty_Out;}//*************************************************************** **********//* *//* **********************S道处理函数********************* *//* 函数:void PID_S()//* 函数功能:S道处理*//* 输入参数:无//*************************************************************** **********UINT8 S_C=30;UINT8 S_C1=0;UINT8 S_P=12;UINT8 S_D=0;void PID_S(){struct _Car *temp1;temp1 = &Car;if(S_C1==1) S_C=StartNum;//方案选择temp1->CtrlPar.Lst_Erro = GuideLine[0] - VIDEO_CENTER; //近线偏差temp1->CtrlPar.Erro = VIDEO_CENTER-GuideLine[S_C]; //远线偏差temp1->CtrlPar.Dif_Erro = temp1->CtrlPar.Erro - temp1->CtrlPar.Lst_Erro; //远线偏差减近线偏差temp1->CtrlPar.Dty_Erro = ((S_P*(temp1->CtrlPar.Erro))>>4) +((S_D*(temp1->CtrlPar.Dif_Erro))>>4);temp1->CtrlPar.Dty_Out = STEER_DTY_CENTER +temp1->CtrlPar.Dty_Erro;if(Straight_Cnt>12){if(StartNum<20) //判断是否最远行太近{TEST_CTL_FLG = 8;if(temp1->CtrlPar.Dty_Out > STEER_DTY_CENTER){temp1->CtrlPar.Dty_Out = STEER_DTY_MAX ;}else if(temp1->CtrlPar.Dty_Out < STEER_DTY_CENTER){temp1->CtrlPar.Dty_Out = STEER_DTY_MIN ;}}}if(temp1->CtrlPar.Dty_Out > STEER_DTY_MAX) {temp1->CtrlPar.Dty_Out = STEER_DTY_MAX;}else if(temp1->CtrlPar.Dty_Out < STEER_DTY_MIN) {temp1->CtrlPar.Dty_Out = STEER_DTY_MIN;}SetDirection(temp1->CtrlPar.Dty_Out);}。