PWM控制舵机 C程序
PWM调速的C语言程序编写(非常简单)
PWM调速的C语言程序编写关于PWM的原理在上一篇文章中已经说的很详细了,现在就细说一下pwm C语言程序的编写。
C语言中PWM的编写有这么几种方法;一、用普通的I/O 口输出的PWM ,二、使用定时计数器编写,三、就是使用片内PWM了。
1 先说使用普通的I\O口编写PWM程序了。
使用I/O口输出PWM波形你必须首先明白PWM他的实质是:调制占空比,占空比就是波形中高电平的长度与整个波长的比值。
我们写C语言的目的是写PWM波形的一个周期。
在这个周期内高低电平的比值是可以改变的。
这也就符合了PWM的原意脉宽调制。
即高电平的宽度的调制。
当然了PWM他也可用于改变频率,我们这里只先说他改变脉宽。
一旦我们的C语言程序写完那么他产生的PWM波形的频率就一定了。
(也可写频率变化的PWM,难度有点大)一般我们控制使用1K到10K的PWM波进行控制。
当然了你也可在要求不是很高的地方使用频率更低的PWM波。
比如在飞思卡尔智能车比赛中我们学校使用的PWM波频率只有600HZ.我们要改变一个PWM波周期内的高电平的宽度显然需要将一个PWM波的周期分成单片机可以控制的N个小的周期,N的取值越大你的调速等级越高,但产生的PWM频率就越低。
我们下面以实现100级调速为例编写PWM程序。
先写出程序再慢慢给大家分析void pwm (uchar x,uint y) //X 为占空比 Y为函数使用时间{ uint i,j,a,b;for(i=y;i>0;i--)//定时外函数{for(j=7;j>0;j--)//定时内函数{for(a=y;a>0;a--) / /PWM波高电平宽度{PORTA=0X01;}for(b=100-y;b>0;b--) //PWM低电平宽度{PORTA=0X00;}}}}这个程序够简单吧轻松的实现AVR单片机的PA.0口输出7KHZ左右的PWM脉冲你可以将PORTA=0X01;改为P1.0=0X01;就可以移植到51单片机上了为什么使用参数Y定时是因为用普通I/O口控制它的开关没有使用定时器编写的灵活。
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信号发生器和驱动器的引脚和参数,以及舵机电路的供电。
PWM调速C程序编写
例如:实现周期为1000us,占空比为20%的PWM,用PA0实现
首先设置T0为83 (11.0592M晶振)
T1为65501
首先初始化PA0=1,两个定时器同时打开,在定时器T1中断时拉低PA0,
在定时器T0中断时在拉高PA0,同时将两定时器初始值初始化T0为83,T1为65501
一开始设置PA0为高电平,当count1加到200的时候拉低PA0,
等count1到1000了在拉高PA0,同时复位count1=0,
不过这样做的缺点是精度不高,要是PWM所需周期段,精度高的话还是用两个定时器来实现;
************************************************/
SREG=0x80;
while(1);
}
#pragma vector = TIMER0_OVF_vect
__interrupt void TIMER0_OVF(void)
{
PWM_PA0=1;
TCNT0=0x53;
}
#pragma vector = TIMER1_OVF_vect
__interrupt void TIMER1_OVF(void)
}
void timer0_init(void)
{
SREG=0x80;
TIMSK|=(1<<TOIE0);
TCCR0|=(0<<CS02)|(0<<CS01)|(1<<CS00);
TCNT0=0x91;
}
void main(void)
{
port_init();
pwm舵机控制
pwm舵机控制第一章:引言随着自动化技术的不断发展,舵机成为机器人、无人机、智能家居等领域中重要的执行器之一。
舵机控制的准确性和稳定性对于这些应用来说至关重要。
PWM(脉宽调制)技术已被广泛应用于舵机控制中,它通过控制舵机电源的脉冲宽度来实现舵机的位置控制。
本论文将重点研究PWM舵机控制方法,并进行相关性能分析和实验验证。
第二章:PWM舵机控制原理2.1 PWM技术概述脉宽调制技术是一种通过改变控制信号的脉冲宽度来控制设备的平均功率输出的方法。
在舵机控制中,PWM技术被用于控制电源脉冲信号的宽度,进而控制舵机的角度或位置。
通常,PWM信号的高电平代表一个角度,而低电平则代表另一个角度。
2.2 PWM舵机控制原理PWM舵机控制分为两个阶段:位置检测和角度控制。
在位置检测阶段,舵机读取输入信号的脉宽,通过内部电路将其转化为相应的角度。
而在角度控制阶段,PWM信号控制舵机的转动。
具体来说,当PWM信号的脉冲宽度大于一个阈值时,舵机向一个方向转动;当脉冲宽度小于该阈值时,舵机向另一个方向转动。
第三章:PWM舵机控制方法3.1 基于PID控制算法的PWM舵机控制PID控制算法是一种常用的控制算法,可以根据目标值与实际值的误差来调整控制信号,进而实现对舵机位置的控制。
在PWM舵机控制中,可以使用PID控制算法来计算控制信号的脉冲宽度,使舵机保持在目标角度附近。
3.2 基于反馈机制的PWM舵机控制在PWM舵机控制中,可以通过添加反馈机制来提高舵机的姿态控制精度。
反馈机制可以通过使用角度传感器或加速度传感器等设备来获取舵机的实际位置信息,并将其与目标位置进行比较。
通过不断调整控制信号的脉冲宽度,可以使舵机快速准确地达到目标姿态。
第四章:实验与结果分析本章将进行一系列实验来验证PWM舵机控制方法的性能。
实验中将计算不同PWM信号脉冲宽度对舵机位置和角度的影响,并进行比较分析。
通过实验结果的对比和分析,可以评估不同的舵机控制方法的优缺点,为实际应用提供指导。
基于C51单片机的直流电机PWM调速控制(包含原理图及C源代码)
基于C51单片机的直流电机PWM调速控制--SQ这是最近一阶段自己学习所获,现分享与大家。
这里采用A T89C52单片机做主控制芯片,实现两路直流电机的PWM调速控制,另外还可以实现转向、显示运行时间、显示档位等注:考虑小直流电机自身因素,调速范围仅设有四级电路原理图:C语言程序源代码:/******************** 硬件资源分配*********************/数码管:显示电机状态(启停、正反、速度)、运行时间、是否转弯按键:K4 启动/暂停K3 正反转/转弯允许K2 加速/左转/运行时间清零K1 减速/右转/停止定时器:T0 数码管动态显示,输出PWMT1 运行时间记录********************************************************//*******主程序文件PWM.c******/#include <reg52.h>#include "Afx.h"#include "Config.c"#define CIRCLE 5 //脉冲周期//按键定义uchar key,key_tmp=0, _key_tmp=0;//显示定义uchar LedState=0xF0; //LED显示标志,0xF0不显示,Ox00显示uchar code LED_code_d[4]={0xe0,0xd0,0xb0,0x70}; //分别选通1、2、3、4位uchar dispbuf[4]={0,0,0,0}; //待显示数组uchar dispbitcnt=0; //选通、显示的位uchar mstcnt=0;uchar Centi_s=0,Sec=0,Min=0; //分、秒、1%秒//程序运行状态标志bit MotState=0; //电机启停标志bit DirState=0; //方向标志0前,1后uchar State1=-1;uchar State2=-1;uchar State3=0;uchar State4=-1;uchar LSpeed=0;uchar RSpeed=0;//其他uint RunTime=0;uint RTime_cnt=0;uint LWidth;uint RWidth; //脉宽uint Widcnt=1;uint Dispcnt;//函数声明void key_scan(void);void DisBuf(void);void K4(void);void K3(void);void K2(void);void K1(void);void disp( uchar H, uchar n );void main(void){P1|=0xF0;EA=1;ET0=1;ET1=1;TMOD=0x11;TH0=0xFC;TL0=0x66; //T0,1ms定时初值TH1=0xDB;TL1=0xFF; //T1,10ms定时初值TR0=1;Widcnt=1;while(1){key_scan();switch(key){case 0x80: K1(); break;case 0x40: K2(); break;case 0x20: K3(); break;case 0x10: K4(); break;default:break;}key=0;DisBuf();LWidth=LSpeed;RWidth=RSpeed;}}//按键扫描**模拟触发器防抖void key_scan(void){key_tmp=(~P3)&0xf0;if(key_tmp&&!_key_tmp) //有键按下{key=(~P3)&0xf0;}_key_tmp=key_tmp ;}//按键功能处理/逻辑控制void K4(void){if(State4==-1){State4=1;TR1=1;dispbuf[3]=1;LedState=0x00; //打开LEDMotState=1; //打开电机LSpeed=1;RSpeed=1; //初速设为1}else if(State4==1){State4=0;TR1=0;MotState=0; //关闭电机}else if(State4==0){MotState=1;if(State3==0){State4=1;TR1=1;}else if(State3==1){LSpeed=2;RSpeed=2;}}}void K3(void){if(State4==1)DirState=!DirState;if(State4==0){if(State3==0){State3=1; //可以转向标志1可以,0不可以TR1=1;dispbuf[3]=9;MotState=1;LSpeed=2;RSpeed=2;}else if(State3==1){State3=0;TR1=0;dispbuf[3]=0;MotState=0;}}}void K2(void){if(State4==1&&LSpeed<4&&RSpeed<4){LSpeed++;RSpeed++;}else if(State4==0){if(State3==0){//State4=-1;//LedState=0xF0;MotState=0;Sec=0;Min=0;}else if(State3==1&&LSpeed<4&&RSpeed<4){//TurnState=0;LSpeed=2;RSpeed++;}}}void K1(void){if(State4==1&&LSpeed>1&&RSpeed>1){LSpeed--;RSpeed--;}else if(State4==0){if(State3==0){State4=-1;LedState=0xF0;MotState=0;}else if(State3==1&&LSpeed<4&&RSpeed<4){//TurnState=1;LSpeed++;RSpeed=2;}}}//显示预处理void DisBuf(void){if(RTime_cnt==100){Sec++;RTime_cnt=0;}if(Sec==60){Min++;Sec=0;}if(State4==1){dispbuf[0]=Sec%10;dispbuf[1]=Sec/10;dispbuf[2]=Min;if(!DirState) //正转dispbuf[3]=LSpeed;if(DirState) //反转dispbuf[3]=LSpeed+4;}if(State4==0){if(State3==0){dispbuf[0]=Sec%10;dispbuf[1]=Sec/10;dispbuf[2]=Min;dispbuf[3]=0;}if(State3==1){dispbuf[0]=RSpeed;dispbuf[1]=LSpeed;dispbuf[2]=Min;dispbuf[3]=9;}}}//LED驱动void disp( uchar H, uchar n ){P1=n;P1|=LedState ;P1|=LED_code_d[H];}//T0中断**显示/方波输出void Time_0() interrupt 1{TH0=0xFC;TL0=0x66;Widcnt++;Dispcnt++;//电机驱动/方波输出if(Widcnt>CIRCLE){Widcnt=1;}if(Widcnt<=LWidth)LMot_P=!DirState&&MotState;elseLMot_P=DirState&&MotState;LMot_M=DirState&&MotState;if(Widcnt<=RWidth)RMot_P=!DirState&&MotState;elseRMot_P=DirState&&MotState;RMot_M=DirState&&MotState;//显示if(Dispcnt==5){disp(dispbitcnt,dispbuf[dispbitcnt]);dispbitcnt++;if(dispbitcnt==4){dispbitcnt=0;}Dispcnt=0;}}//T1中断**运行时间void Time_1() interrupt 3{TH1=0xDB;TL1=0xFF;RTime_cnt++;}/******配置文件Afx.h******/#ifndef _AFX_#define _AFX_typedef unsigned char uchar;typedef unsigned int uint;typedef unsigned long ulong;#endif/******IO配置文件Config.c******/#ifndef _Config_#define _Config_#include "Afx.h"#include <reg52.h>//显示定义sbit led=P3^2;//电机引脚定义sbit LMot_P=P2^2; sbit LMot_M=P2^3; sbit RMot_P=P2^0; sbit RMot_M=P2^1;#endif。
pwm占空比程序c语言程序
pwm占空比程序c语言程序Pulse Width Modulation (PWM) is a crucial concept in electronicsand can be implemented using a C language program. PWM is a method of controlling the amount of power delivered to an electronic device by varying the ON time and OFF time of a digital signal. This is achieved by changing the duty cycle of the signal, which is the ratio of ON time to the total time of one cycle. In a simple PWM circuit, the duty cycle determines the average voltage applied to the load, allowing for precise control of devices like motors, LEDs, and heaters.在电子学中,脉冲宽度调制(PWM)是一个至关重要的概念,可以通过使用C语言程序来实现。
PWM是一种控制向电子设备传送的功率量的方法,方法是通过改变数字信号的开启时间和关闭时间。
这是通过改变信号的占空比来实现的,占空比是开启时间与一个周期总时间的比例。
在一个简单的PWM电路中,占空比决定了施加到负载上的平均电压,从而实现对电机、LED和加热器等设备的精确控制。
Implementing a PWM program in C language involves using timer modules and I/O pins on a microcontroller. The timer is used togenerate a periodic signal, which is then modulated to create the desired PWM waveform. By manipulating the timer settings, such as the prescaler and period, the frequency and duty cycle of the PWM signal can be adjusted. The duty cycle is usually expressed as a percentage, with 0% representing a fully OFF signal and 100% representing a fully ON signal. This flexibility allows for customization of the PWM output to match the requirements of specific applications.在C语言中实现PWM程序涉及使用微控制器上的定时器模块和I/O引脚。
舵机控制程序简单
舵机控制程序简单第一章:引言(约200字)舵机是一种用于控制机械系统位置和速度的装置,广泛应用于各种机器人和自动化系统中。
它具有速度快、响应灵敏、精确度高等特点,因此在诸多领域都发挥着重要作用。
本论文将介绍一种简单的舵机控制程序,目的是实现对舵机位置的精确控制。
第二章:舵机控制原理(约300字)舵机控制基于脉宽调制(PWM)技术,即通过调整PWM信号的高电平时间来控制舵机的位置。
一般情况下,舵机可以控制在0到180度的范围内,其中90度为中间位置。
通过发送特定脉冲宽度的PWM信号,舵机可以定位到所需的位置。
舵机的输入信号通常为20ms周期的PWM信号,其高电平时间在0.5ms到2.5ms之间,对应着舵机位置的0到180度。
第三章:舵机控制程序设计(约400字)在设计舵机控制程序时,需要利用控制器(如Arduino)和相应的编程语言(如C++)来实现。
首先,需要将舵机控制引脚连接到控制器上,并设置控制引脚为输出模式。
然后,在主循环中,使用控制语句来发送特定脉宽的PWM信号来控制舵机位置。
可以根据需求设置不同的脉宽值,以达到精确控制舵机位置的目的。
例如,如果想将舵机定位到90度,可以发送1.5ms的高电平脉宽信号。
在程序设计中,可以使用函数来简化代码,使得控制舵机的过程更加清晰和灵活。
例如,可以设计一个函数用于设置舵机位置,用户只需调用该函数并输入目标位置即可。
同时,还可以添加对舵机位置范围的判断,以确保用户输入的位置在舵机可控范围内。
第四章:实验结果与讨论(约300字)通过编写舵机控制程序并进行实验,我们可以得到舵机精确控制位置的效果。
试验中,我们设定舵机定位到90度,并观察实际位置是否与设定位置一致。
实验结果表明,舵机在良好的控制条件下,能够实现较高的位置控制精度。
然而,由于舵机本身的特性和控制器的限制,可能存在一定的位置偏移和响应延迟。
在论文中,我们还会探讨一些可能影响舵机控制效果的因素,如控制器的采样率、舵机的质量和机械结构等。
单片机pwm控制舵机
单片机pwm控制舵机第一章:引言(大约200字)随着科技的不断发展,单片机技术在现代工业和自动化领域中的应用越来越广泛。
在这些应用中,控制舵机是非常常见的需求之一。
舵机通过调节输入的脉冲宽度来改变输出角度,因此使用脉冲宽度调制(PWM)信号来控制舵机的运动是一种常见的方法。
本论文将探讨如何使用单片机实现PWM控制舵机的方法和技术。
第二章:PWM控制舵机的原理与设计(大约300字)本章将介绍PWM控制舵机的原理和设计。
首先,将详细介绍PWM的概念和工作原理,以及舵机的工作原理。
然后,将讨论如何使用单片机生成PWM信号,并通过改变脉冲宽度来控制舵机的角度。
接下来,将介绍舵机控制电路的基本组成部分和连接方式。
最后,将给出一个具体的PWM控制舵机的电路设计示例。
第三章:单片机编程实现PWM控制舵机(大约300字)本章将介绍如何使用单片机进行编程,实现PWM控制舵机。
首先,将介绍使用哪种编程语言来编写单片机的程序,例如C 语言或汇编语言。
然后,将详细介绍如何编写程序来生成PWM信号,并通过改变脉冲宽度来控制舵机的角度。
此外,还将讨论如何根据实际需求调整PWM信号的频率和占空比。
最后,将给出一个具体的单片机编程实现PWM控制舵机的示例代码。
第四章:实验结果与讨论(大约200字)本章将介绍使用本论文中所提到的方法和技术实现PWM控制舵机的实验结果和讨论。
首先,将介绍所采用的实验平台和测试设备。
然后,将详细介绍实验过程和实验结果。
对于实验结果的讨论,将分析PWM信号的频率和占空比对舵机控制精度的影响。
最后,将讨论实验中可能遇到的问题和改进的方向。
结论(大约100字)通过本论文的研究,我们可以得出结论:使用单片机实现PWM控制舵机是一种可行且有效的方法。
通过调整PWM信号的脉冲宽度,可以精确控制舵机的角度。
同时,通过单片机编程实现PWM控制舵机也是相对简单的。
通过进一步的研究和实践,可以不断改进这一方法并应用于更广泛的应用领域中。
舵机pwm控制原理
舵机PWM控制原理
PWM(Pulse Width Modulation)控制是一种通过控制脉冲宽度来控制输出信号的技术。
对于舵机而言,PWM控制可以通过控制舵机的电流来控制舵机的位置和速度。
舵机的PWM控制原理如下:
1. 舵机接收PWM信号,其中高电平表示舵机需要保持静止,低电平表示舵机需要转动。
2. 舵机根据接收到的PWM信号,通过内部电路将低电平信号转换为舵机转动的电流,而高电平信号则被忽略。
3. 舵机根据接收到的PWM信号的周期和占空比来计算舵机的转动角度和速度。
4. 舵机通过内部的位置反馈系统来检测舵机的位置和速度,并根据反馈信号来调整舵机的转动角度和速度。
舵机的PWM控制可以通过调整PWM信号的占空比来控制舵机的转动角度和速度。
占空比越大,舵机转动的角度和速度就越大;占空比越小,舵机转动的角度和速度就越小。
通过调整PWM信号的占空比,可以实现对舵机的精确控制。
利用PWM信号控制舵机
在机器人机电控制系统中,舵机控制效果是性能的重要影响因素。
舵机可以在微机电系统和航模中作为基本的输出执行机构,其简单的控制和输出使得单片机系统非常容易与之接口。
舵机是一种位置伺服的驱动器,适用于那些需要角度不断变化并可以保持的控制系统。
其工作原理是:控制信号由接收机的通道进入信号调制芯片,获得直流偏置电压。
它内部有一个基准电路,产生周期为20ms,宽度为1.5ms的基准信号,将获得的直流偏置电压与电位器的电压比较,获得电压差输出。
最后,电压差的正负输出到电机驱动芯片决定电机的正反转。
当电机转速一定时,通过级联减速齿轮带动电位器旋转,使得电压差为0,电机停止转动。
舵机的控制信号是PWM信号,利用占空比的变化改变舵机的位置。
一般舵机的控制要求如图1所示。
单片机实现舵机转角控制可以使用FPGA、模拟电路、单片机来产生舵机的控制信号,但FPGA成本高且电路复杂。
对于脉宽调制信号的脉宽变换,常用的一种方法是采用调制信号获取有源滤波后的直流电压,但是需要50Hz(周期是20ms)的信号,这对运放器件的选择有较高要求,从电路体积和功耗考虑也不易采用。
5mV以上的控制电压的变化就会引起舵机的抖动,对于机载的测控系统而言,电源和其他器件的信号噪声都远大于5mV,所以滤波电路的精度难以达到舵机的控制精度要求。
也可以用单片机作为舵机的控制单元,使PWM信号的脉冲宽度实现微秒级的变化,从而提高舵机的转角精度。
单片机完成控制算法,再将计算结果转化为PWM信号输出到舵机,由于单片机系统是一个数字系统,其控制信号的变化完全依靠硬件计数,所以受外界干扰较小,整个系统工作可靠。
单片机系统实现对舵机输出转角的控制,必须首先完成两个任务:首先是产生基本的PWM周期信号,本设计是产生20ms的周期信号;其次是脉宽的调整,即单片机模拟PWM信号的输出,并且调整占空比。
当系统中只需要实现一个舵机的控制,采用的控制方式是改变单片机的一个定时器中断的初值,将20ms分为两次中断执行,一次短定时中断和一次长定时中断。
c单片机C语言编写的PWM程序
89c51单片机C语言编写的PWM程序PWM, 单片机, C语言, 程序, 编写分享到:新浪微博 QQ空间开心网人人网说明:本程序使用STC89C52RC单片机,22.1184MHz晶振,要使用本程序需要自己修改,我是用来控制直流电机的,外接了L298驱动电路,有问题或意见请回复,谢谢^_^#include "reg52.H"#include "MyType.h"//=============L298端口定义===============sbit ENA = P3^6;?//左轮驱动使能sbit IN1 = P0^3;?//左轮黑线(-)sbit IN2 = P0^4;?//左轮红线(+)sbit IN3 = P0^5;?//右轮红线(-)sbit IN4 = P0^6;?//右轮黑线(+)sbit ENB = P3^7;?//右轮驱动使能//=============PWM================#define PWM_COUST 100?//PWM细分等份uchar MOTO_speed1;??//左边电机转速uchar MOTO_speed2; ??//右边电机转速uchar PWM_abs1;???//左边电机取绝对值后占空比uchar PWM_abs2;???//左边电机取绝对值后占空比?uchar PWM_var1=20;??//左边电机直走速度(不同的电机,此参数不同)uchar PWM_var2=20;??//右边电机直走速度uchar PWMAnd = 0;??//PWM自增变量/****************************************************************** 名称:motor(char speed1,char speed2);功能:同时调节电机的转速参数:speed1:电机1的PWM值;speed2:电机2的PWM值?? speed>0.正转;speed<0.反转(-100~100)调用:extern int abs(int val); 取绝对值返回:/******************************************************************/ void motor(char speed1,char speed2){??//==============左边电机=============?if (speed1>0)??{??IN1 =0;IN2 =1;//正转??}???else if (speed1<0)??{??IN1 =1;IN2 =0;//反转??}?//==============右边电机=============?if (speed2>0)??{??IN3 =1;IN4 =0;//正转??}?else if (speed2<0)??{??IN3 =0;IN4 =1;//反转??}}/******************************************************************名称:motor_PWM();功能:PWM占空比输出参数:无调用:无返回:无/******************************************************************/void motor_PWM (){?uchar PWM_abs1;?uchar PWM_abs2;?PWM_abs1=MOTO_speed1;?PWM_abs2=MOTO_speed2;?if (PWM_abs1>PWMAnd) ENA=1;??? //左边电机占空比输出??else ENA=0;?if (PWM_abs2>PWMAnd) ENB=1;??? //右边电机占空比输出??else ENB=0;?if (PWMAnd>=PWM_COUST) PWMAnd=0;? //PWM计数清零??else PWMAnd+=1;}???/******************************************************************名称:void TIME_Init ();功能:定时器初始化指令:调用:无返回:无/******************************************************************/void TIME_Init ()?{//=========定时器T2初始化 PWM==================?T2CON = 0x00;? ?T2MOD = 0x00;? ?RCAP2H = 0xff;?//定时0.1ms? ?RCAP2L = 0x47;? ?TH2 = 0xff;? ?TL2 = 0x47;?ET2 = 1;??//定时器2中断开?TR2 = 1;??//PWM定时器关,PWM周期为10ms?}/******************************************************************名称:void PWM_Time2 () interrupt 5功能:T2中断,PWM控制参数:调用:motor_PWM();//PWM占空比输出返回:/******************************************************************/?void PWM_Time2 () interrupt 5{? ?TR2 = 0;?TF2 = 0;?ET2 = 0;?//定时器0中断禁止?motor_PWM();//PWM占空比输出?ET2 = 1;?//定时中断0开启?TR2 = 1;}main(){TIME_Init ()?;motor(50,50);//左右电机的转速都是50}。
单片机输出PWM温控程序C语言代码
单片机PWM温控C语言程序部分代码#include <reg52.h>#include <at89x52.h>#include <keyscan.h>extern void scan_full(void);extern unsigned char key_scan(void);extern bit key_ok;unsigned char pwm_set,key_value;unsigned char count;sbit PWM=P3^6; //将PWM定义为P3口的第六位?bit up,down,set_flag;unsigned char code BCD[]={0x3f,0x06,0x5b,0x4f, //此处是将0-F转换成0x66,0x6d,0x7d,0x07, //相应的BCD码0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};void delay1(unsigned char t){while(t--);}void pwm(void) interrupt 5//定时器2产生PWM波形{TF2=0; //定时器2的溢出标志要软件清除,//但当RCLK或TCLK为1时由硬件清除if((count>=pwm_set)&amt;&amt;(count<10))PWM=1;elsePWM=0;count++;if(count==10)count=0x00;}void key_pwm(unsigned char x)//把键值转化为PWM设置值{switch(x) //把矩阵键盘转化为独立键盘{case 1:up=1;break;case 2:down=1;break;case 3:set_flag=!set_flag;break;default:break;}//设置PWM参数:pwm_setif(up&amt;&amt;set_flag){pwm_set++;up=0;if(pwm_set>=10)pwm_set=0x00;}if(down&amt;&amt;set_flag){pwm_set--;down=0;if(pwm_set==0xff) //减到-1?pwm_set=9;}if(!set_flag){up=0;down=0;}}void main(void){TH2=0xb1; //定时20MSTL2=0xe0;RCAP2H=0xb1;//定时器2溢出会把该单元内容送到TH2和TL2 RCAP2L=0xe0;EA=1;ET2=1;TR2=1;while(1){scan_full(); //看是否有键按下if(key_ok) //有键按下,则判断到底是哪个键按下{key_value=key_scan();//键值送key_value暂存P0=~BCD[key_value]; /*此三句是将键值显示出来*/P2=0xfe;delay1(200);key_pwm(key_value); //调用键值转PWM设置参数函数key_value=0x00; //清除键值,以免一次按下,多次响应}P0=~BCD[pwm_set]; /***此三句是将pwm_set值显示出来*/P2=0xfd;delay1(200);}}#include <reg52.h>//#include <at89x52.h>//unsigned char code BCD[]={0x3f,0x06,0x5b,0x4f, //此处是将0-F转换成//相应的BCD码 :// 0x66,0x6d,0x7d,0x07,// 0x7f,0x6f,0x77,0x7c,// 0x39,0x5e,0x79,0x71};//unsigned char code KEY[]={0x00,0x00,0x01,0x02,0x03,//此处是为使程序通用,当键值不是按// 0x04,0x05,0x06,0x07,//这个排列时,把此表更改即可// 0x08,0x09,0x0a,0x0b,//最前面的那个0x00是为了查表方便,// 0x0c,0x0d,0x0e,0x0f};//因为键值是从1开始的sfr key_port=0x90; //定义P1口为键盘扫描口bit key_ok=0; //有键按下的标志/*************延时子程序*****************调用一次用时18微秒,t每加1,用时增加6微秒*/void delay(unsigned char t){while(t--);}unsigned char r_left(unsigned char x)//循环左移一位{x<<=1;x++;return(x);}/*************粗判有无键按下**************有键按下则将key_ok置1************/void scan_full(void){unsigned char temp;key_port=0xf0; //低半字节为行线,高半字节为列线temp=P1;if(temp!=0xf0)key_ok=1;elsekey_ok=0;}/************键盘扫描程序*****************************功能:返回键值,当无键按下时,返回0*************/unsigned char key_scan(void){unsigned char temp,count=0x01,key_value;//按键返回值unsigned char x_scan=0xfe,y_scan=0xef;//行、列扫描码unsigned char i,j,y; //行数和列数while(1){scan_full(); //粗判是否有键按下if(key_ok==1){key_ok=0;delay(200); //延时去抖动scan_full(); //再次粗判是否有键按下if(key_ok==1){for(i=0;i<4;i++) //扫描4行{key_port=x_scan;for(j=0;j<4;j++) //每行4列{temp=key_port;temp=temp&amt;0xf0;y=y_scan&amt;0xf0;if(temp==y){while(key_ok!=0)//等待按键松开{scan_full();}key_value=count;return(key_value);//找到键值,马上返回}else{count++;y_scan=r_left(y_scan);}}y_scan=0xef; //扫描完一列,重新对列扫描量赋初值x_scan=r_left(x_scan);//行扫描码左移一位,扫描下一行}}}return(key_value);//没键按下,返回0}}//unsigned char key(void)//{// unsigned char x;// unsigned char y;// x=key_scan();// return(x);// y=KEY[x];// return y;//}。
利用PWM信号控制舵机
在机器人机电控制系统中,舵机控制效果是性能的重要影响因素。
舵机可以在微机电系统和航模中作为基本的输出执行机构,其简单的控制和输出使得单片机系统非常容易与之接口。
舵机是一种位置伺服的驱动器,适用于那些需要角度不断变化并可以保持的控制系统。
其工作原理是:控制信号由接收机的通道进入信号调制芯片,获得直流偏置电压。
它内部有一个基准电路,产生周期为20ms,宽度为1.5ms的基准信号,将获得的直流偏置电压与电位器的电压比较,获得电压差输出。
最后,电压差的正负输出到电机驱动芯片决定电机的正反转。
当电机转速一定时,通过级联减速齿轮带动电位器旋转,使得电压差为0,电机停止转动。
舵机的控制信号是PWM信号,利用占空比的变化改变舵机的位置。
一般舵机的控制要求如图1所示。
单片机实现舵机转角控制可以使用FPGA、模拟电路、单片机来产生舵机的控制信号,但FPGA成本高且电路复杂。
对于脉宽调制信号的脉宽变换,常用的一种方法是采用调制信号获取有源滤波后的直流电压,但是需要50Hz(周期是20ms)的信号,这对运放器件的选择有较高要求,从电路体积和功耗考虑也不易采用。
5mV以上的控制电压的变化就会引起舵机的抖动,对于机载的测控系统而言,电源和其他器件的信号噪声都远大于5mV,所以滤波电路的精度难以达到舵机的控制精度要求。
也可以用单片机作为舵机的控制单元,使PWM信号的脉冲宽度实现微秒级的变化,从而提高舵机的转角精度。
单片机完成控制算法,再将计算结果转化为PWM信号输出到舵机,由于单片机系统是一个数字系统,其控制信号的变化完全依靠硬件计数,所以受外界干扰较小,整个系统工作可靠。
单片机系统实现对舵机输出转角的控制,必须首先完成两个任务:首先是产生基本的PWM周期信号,本设计是产生20ms的周期信号;其次是脉宽的调整,即单片机模拟PWM信号的输出,并且调整占空比。
当系统中只需要实现一个舵机的控制,采用的控制方式是改变单片机的一个定时器中断的初值,将20ms分为两次中断执行,一次短定时中断和一次长定时中断。
树莓派舵机控制c语言
树莓派舵机控制c语言第一章:引言树莓派是一款功能强大的微型电脑,具有广泛的应用领域。
其中,舵机控制是树莓派的一个重要应用之一。
本论文将介绍如何使用C语言控制树莓派上的舵机,实现精确的运动控制。
本章将对树莓派和舵机的背景进行介绍,目的是引出本论文的研究内容和意义。
第二章:树莓派舵机控制的原理与方法本章将详细介绍树莓派舵机控制的原理与方法。
首先,将介绍舵机的工作原理和控制方式。
舵机是一种用来控制角度和位置的设备,其工作原理是通过接收电信号来调整电机的输出角度。
其次,将介绍树莓派的GPIO引脚和PWM输出功能。
GPIO引脚是树莓派上的通用输入输出引脚,可以通过改变引脚的电平来控制外部设备的工作状态。
PWM(脉冲宽度调制)信号是一种特殊的信号,可以实现模拟信号的输出。
本章还将介绍如何通过C语言编程控制树莓派的GPIO引脚和PWM功能,从而实现舵机的精确控制。
第三章:树莓派舵机控制的实现与应用本章将介绍如何使用C语言编写代码来实现树莓派舵机控制。
首先,将介绍树莓派系统的搭建和设置,包括安装操作系统、设置GPIO引脚等。
然后,将详细介绍如何使用C语言编写程序来控制树莓派的GPIO引脚和PWM功能。
最后,将通过实验验证树莓派舵机控制的有效性和精确性。
本章还将介绍一些树莓派舵机控制的应用场景,如机器人、智能家居等。
第四章:总结与展望本章将对全文进行总结,并展望树莓派舵机控制的未来发展方向。
总结部分将对树莓派舵机控制的主要研究内容和取得的研究成果进行概括,并分析其优缺点。
展望部分将对树莓派舵机控制在未来的发展方向进行预测,探讨其可能存在的问题和挑战,并提出相应的解决方案。
第一章:引言树莓派是一款功能强大的微型计算机,广泛应用于物联网、教育等领域。
舵机是一种常见的电机,具有使物体按照特定角度旋转的功能。
树莓派舵机控制是指通过树莓派中的GPIO引脚和PWM功能来驱动舵机,实现精确的角度控制。
本论文将介绍使用C语言编程控制树莓派舵机的原理、方法和实现过程。
PWM控制舵机 C程序
#include "reg52.h"sbit control_signal=P0^0;sbit turn_left=P3^0;sbit turn_right=P3^1;unsigned char PWM_ON=15 ;//定义高电平时间/******************************************************************//* 延时函数 *//******************************************************************/ void delay(unsigned int cnt){while(--cnt);}void display(){if(PWM_ON>=5&&PWM_ON<=7) P1=0xFD; //1灯亮,舵机接近或到达右转极限位置if(PWM_ON>7&&PWM_ON<=10) P1=0xFB; //2灯亮if(PWM_ON>10&&PWM_ON<=13) P1=0xF7; //3灯亮if(PWM_ON>13&&PWM_ON<=16) P1=0xEF; //4灯亮,舵机到达中间位置if(PWM_ON>16&&PWM_ON<=19) P1=0xDF; //5灯亮if(PWM_ON>19&&PWM_ON<=22) P1=0xBF; //6灯亮if(PWM_ON>22&&PWM_ON<=25) P1=0x7F; //7灯亮,舵机接近或到达左转极限位置}/******************************************************************//* 主函数 *//******************************************************************/ void main(){//bit Flag;TMOD |=0x01; //定时器设置 0.1ms in 11.0592M crystal TH0=(65536-78)/256;TL0=(65536-78)%256; //定时0.1mSET0=1;//定时器中断打开EA=1;//总中断//IE= 0x82; //打开中断TR0=1;// PWM_ON=15 //的取值范围是6-25while(1){if(turn_left==0){delay(1000);if(turn_left==0){while(!turn_left){}PWM_ON+=1;if(PWM_ON>25)PWM_ON=25;}}if(turn_right==0){delay(1000);if(turn_right==0){while(!turn_right){}PWM_ON-=1;if(PWM_ON<6)PWM_ON=6;}}display();}}/******************************************************************/ /* 定时器中断函数 */ /******************************************************************/ void tim(void) interrupt 1 using 1{static unsigned char count;TH0=(65536-78)/256;TL0=(65536-78)%256; //定时0.1mS,经过示波器的测量if (count<PWM_ON){control_signal = 1; //给高电平}else{control_signal=0 ;}count++;if(count == 200){count=0; //20ms一个周期}}。
STM32PWM控制舵机的main程序
#include <stm32f10x.h>#include <stdio.h>#include <usart.h>#include <Nvic_Exit.h>#include <delay.h>#include <tft.h>#include <ov7670.h>#include<I2C.h>#include "stm32f10x_tim.h"#include "include.h"#include "Image.h"void RCC_Configuration(void);void GPIO_Configuration(void);void USART_Configuration(void);void NVIC_Configuration(void);void EXIT_configuration();void IO_Init(void);void Timer3_configuration();void Timer1_configuration();#define STRM 500#define STRL 330#define STRR 670//#define STRE 1200main(){RCC_Configuration();;//系统时钟设置delay_init(72);//延时初始化IO_Init();GPIO_Configuration();NVIC_Configuration();USART_Configuration();Timer3_configuration();Timer1_configuration();delay_ms(1000);TIM3->CCR2 = 504;// 电机初始化中间值GPIO_WriteBit( GPIOB,GPIO_Pin_0, 1);//灯亮GPIO_WriteBit( GPIOB,GPIO_Pin_1, 1);delay_ms(1000); //等待4s,等待初始化完毕delay_ms(1000);delay_ms(1000);delay_ms(1000);TIM3->CCR2 = 560;// TIM3->CCR1 = 380; //向右转delay_ms(1000);delay_ms(1000);// TIM3->CCR1 = 650;while(1){TIM3->CCR2 = 550;/*// TIM3->CCR1 = 380; //向右转delay_ms(100);TIM3->CCR1= 504;delay_ms(100);// TIM3->CCR1 = 650;delay_ms(100);TIM3->CCR1= 504; TIM3->CCR1= 504; TIM3->CCR1= 504; TIM3->CCR1= 504; */}}void RCC_Configuration(void){SystemInit();// Enable GPIO clockRCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO|RCC_APB2Periph_TIM1|RCC_APB2Periph_USART1,ENABLE);// Enable USART2 ClockRCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2|RCC_APB1Periph_TIM3,ENABLE);}void IO_Init(void){RCC->APB2ENR|=1<<0;//开启辅助时钟RCC->APB2ENR|=1<<2;//先使能外设PORTA时钟RCC->APB2ENR|=1<<3;//先使能外设PORTB时钟RCC->APB2ENR|=1<<4;//先使能外设PORTC时钟GPIOC->CRL=0X88888888; //PORTC 输入//摄像头八位输入GPIOC->CRH=0X33333333;GPIOC->ODR=0XFFFF;GPIOA->CRH=0X33333333; //PORTA上拉输出//摄像头输出GPIOA->CRL=0X33333333;GPIOA->ODR=0XFFFF;GPIOB->CRL=0X33333333; //PB0-7 上拉输出GPIOB->CRH=0X33333333; //PB8-15 上拉输出GPIOA->ODR=0XFFFF;JTAG_Set(JTAG_SWD_DISABLE);//JTAG功能禁止,复用JTAG端口}//保持原有配置void GPIO_Configuration(void){GPIO_InitTypeDef GPIO_InitStructure;//****** TIM1 CH1(PA8) CH4 (PA11) ******************************GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_11;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推完输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);//****** TIM3 CH1 ch2 (PA6 pa7) ******************************GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推完输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);//******** 外部中断GPIO 初始化***************GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_4;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);/* 设置USART1的Tx脚(PA.9)为第二功能推挽输出模式*/GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA , &GPIO_InitStructure);/* 设置USART1的Rx脚(PA.10)为浮空输入脚*/GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(GPIOA , &GPIO_InitStructure);}/****************************************************************************** ** 函数名: USART_Configuration保持原有配置* 函数描述: 设置USART1* 输入参数: None* 输出结果: None* 返回值: None******************************************************************************* /void USART_Configuration(void){/* 定义USART初始化结构体USART_InitStructure */USART_InitTypeDef USART_InitStructure;/**波特率为9600bps*8位数据长度*1个停止位,无校验*禁用硬件流控制*禁止USART时钟*时钟极性低*在第2个边沿捕获数据*最后一位数据的时钟脉冲不从SCLK 输出*/USART_ART_BaudRate = 9600;USART_ART_WordLength = USART_WordLength_8b;USART_ART_StopBits = USART_StopBits_1;USART_ART_Parity = USART_Parity_No ;USART_ART_HardwareFlowControl = USART_HardwareFlowControl_None;USART_ART_Mode = USART_Mode_Rx | USART_Mode_Tx;USART_Init(USART1 , &USART_InitStructure);/* 使能USART1 */USART_Cmd(USART1 , ENABLE);}void NVIC_Configuration(void){NVIC_InitTypeDef NVIC_InitStructure;//中断默认参数// Configure the NVIC Preemption Priority BitsNVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;//通道设置为串口2中断NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //中断占先等级1NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //中断响应优先级1NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //打开中断NVIC_Init(&NVIC_InitStructure);//********** 外部中断(PA0 PA4)****************************************NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; //更新事件NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //抢占优先级0NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //响应优先级1NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //允许中断NVIC_Init(&NVIC_InitStructure);}void EXIT_configuration(){EXTI_InitTypeDef EXTI_InitStructure;EXTI_ClearITPendingBit(EXTI_Line0);GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);EXTI_InitStructure.EXTI_Line = EXTI_Line0;EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_Init(&EXTI_InitStructure);EXTI_GenerateSWInterrupt(EXTI_Line0);}//timer1 的通道1 输出电机控制pwm pa8void Timer1_configuration(){//TIM_DeInit(TIM1);TIM_TimeBaseInitTypeDef TIM1_TimeBaseStructure;TIM_OCInitTypeDef TIM_OCInitStructure;TIM1_TimeBaseStructure.TIM_Period = 7200-1; // 0xFFFF; 计数初值!@#$%^&*()~TIM1_TimeBaseStructure.TIM_Prescaler = 200; //0xF; 分频TIM1_TimeBaseStructure.TIM_ClockDivision = 0x0;TIM1_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//TIM1_TimeBaseStructure.TIM1_RepetitionCounter= 1000-1; //设置了周期计数器值;RCR向下计数器每次计数至0,会产生!@#$%^&*()~//一个更新事件且计数器重新由RCR值(N)开始计数。
舵机控制C程序
舵机控制C程序标准化管理部编码-[99968T-6889628-J68568-1689N]舵机控制C程序#include<reg51.h>#defineucharunsignedchar#defineuintunsignedint/*变量定义*/ucharkey_stime_counter,hight_votage=15,timeT_counter;bitkey_stime_ok;/*引脚定义*/sbitcontrol_signal=P0^0;sbitturn_left=P3^4;sbitturn_right=P3^5;/***************************************************************** 名称:定时器0初始化功能:20ms定时,11.0592M晶振初值20ms初值0.1ms*****************************************************************/ voidTimerInit(){control_signal=0;TMOD=0x01;//设置定时器0为工作方式1EA=1;//开总中断ET0=1;//定时器0中断允许TH0=0xFF;//定时器装初值TL0=0xA3;TR0=1;//启动定时器0}/**********************************************定时器0中断服务函数***********************************************/voidtimer0(void)interrupt1using0{TH0=0xFF;TL0=0xA3;//定时器0重新装入数值if(++key_stime_counter>=200){key_stime_counter=0;control_signal=1;key_stime_ok=1;//20ms到timeT_counter=0;}if(key_stime_ok&&(++timeT_counter>=hight_votage)){key_stime_ok=0;timeT_counter=0;control_signal=0;//hight_votage*0.1ms到}}/*********************************************名称:键盘扫描功能:在按键稳定期内判断键值,并返回键值**********************************************/ ucharkeyscan(void){staticcharkey_state=0;staticcharkey_value=0;ucharkey_press,key_return=0;key_press=turn_left&turn_right;//读按键I/O电平switch(key_state){case0://按键初始态if(key_press==0)key_state=1;//键被按下,但需要确认是否是干扰break;case1://按键确认态if(key_press==0)//如有键按下则不是干扰,判断键值{if(turn_left==0)//判断是哪一个按键被按下key_value=1;//按键较多时可采用switch选择结构elseif(turn_right==0)key_value=2;elsekey_value=0;key_state=2;//状态转换到键释放态}elsekey_state=0;//按键已抬起,属于干扰,转换到按键初始态break;case2:if(key_press==1){key_return=key_value;//按键释放后再输出键值,如果按下键就输出则可省略key_valuekey_value=0;key_state=0;//如果按键释放,转换到按键初始态}break;}returnkey_return;//返回键值}/*********************************************名称:按键处理功能:**********************************************/voidkey_operation(void){switch(keyscan())//根据键值不同,执行不同的内容{case1:hight_votage-=1;if(hight_votage<5)hight_votage=5;break;case2:hight_votage+=1;if(hight_votage>25)hight_votage=25;break;default:break;}}//LED显示函数voiddiplay(){if(hight_votage>=5&&hight_votage<=7)P1=0xFD;//1灯亮,舵机接近或到达右转极限位置if(hight_votage>7&&hight_votage<=10)P1=0xFB;//2灯亮if(hight_votage>10&&hight_votage<=13)P1=0xF7;//3灯亮if(hight_votage>13&&hight_votage<=16)P1=0xEF;//4灯亮,舵机到达中间位置if(hight_votage>16&&hight_votage<=19)P1=0xDF;//5灯亮if(hight_votage>19&&hight_votage<=22)P1=0xBF;//6灯亮if(hight_votage>22&&hight_votage<=25)P1=0x7F;//7灯亮,舵机接近或到达左转极限位置}/*主程序*/voidmain(void){TimerInit();while(1){key_operation();diplay();}}。
舵机C语言控制
利用单片机PWM信号进行舵机控制基于单片机的舵机控制方法具有简单、精度高、成本低、体积小的特点,并可根据不同的舵机数量加以灵活应用。
在机器人机电控制系统中,舵机控制效果是性能的重要影响因素。
舵机可以在微机电系统和航模中作为基本的输出执行机构,其简单的控制和输出使得单片机系统非常容易与之接口。
舵机是一种位置伺服的驱动器,适用于那些需要角度不断变化并可以保持的控制系统。
其工作原理是:控制信号由接收机的通道进入信号调制芯片,获得直流偏置电压。
它内部有一个基准电路,产生周期为20ms,宽度为1.5ms的基准信号,将获得的直流偏置电压与电位器的电压比较,获得电压差输出。
最后,电压差的正负输出到电机驱动芯片决定电机的正反转。
当电机转速一定时,通过级联减速齿轮带动电位器旋转,使得电压差为0,电机停止转动。
舵机的控制信号是PWM信号,利用占空比的变化改变舵机的位置。
一般舵机的控制要求如图1所示。
单片机实现舵机转角控制可以使用FPGA、模拟电路、单片机来产生舵机的控制信号,但FPGA成本高且电路复杂。
对于脉宽调制信号的脉宽变换,常用的一种方法是采用调制信号获取有源滤波后的直流电压,但是需要50Hz(周期是20ms)的信号,这对运放器件的选择有较高要求,从电路体积和功耗考虑也不易采用。
5mV以上的控制电压的变化就会引起舵机的抖动,对于机载的测控系统而言,电源和其他器件的信号噪声都远大于5mV,所以滤波电路的精度难以达到舵机的控制精度要求。
也可以用单片机作为舵机的控制单元,使PWM信号的脉冲宽度实现微秒级的变化,从而提高舵机的转角精度。
单片机完成控制算法,再将计算结果转化为PWM信号输出到舵机,由于单片机系统是一个数字系统,其控制信号的变化完全依靠硬件计数,所以受外界干扰较小,整个系统工作可靠。
单片机系统实现对舵机输出转角的控制,必须首先完成两个任务:首先是产生基本的PWM周期信号,本设计是产生20ms的周期信号;其次是脉宽的调整,即单片机模拟PWM 信号的输出,并且调整占空比。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#include "reg52.h"
sbit control_signal=P0^0;
sbit turn_left=P3^0;
sbit turn_right=P3^1;
unsigned char PWM_ON=15 ;//定义高电平时间
/******************************************************************/
/* 延时函数 */
/******************************************************************/ void delay(unsigned int cnt)
{
while(--cnt);
}
void display()
{
if(PWM_ON>=5&&PWM_ON<=7) P1=0xFD; //1灯亮,舵机接近或到达右转极限位置if(PWM_ON>7&&PWM_ON<=10) P1=0xFB; //2灯亮
if(PWM_ON>10&&PWM_ON<=13) P1=0xF7; //3灯亮
if(PWM_ON>13&&PWM_ON<=16) P1=0xEF; //4灯亮,舵机到达中间位置
if(PWM_ON>16&&PWM_ON<=19) P1=0xDF; //5灯亮
if(PWM_ON>19&&PWM_ON<=22) P1=0xBF; //6灯亮
if(PWM_ON>22&&PWM_ON<=25) P1=0x7F; //7灯亮,舵机接近或到达左转极限位置}
/******************************************************************/
/* 主函数 */
/******************************************************************/ void main()
{
//bit Flag;
TMOD |=0x01; //定时器设置 0.1ms in 11.0592M crystal TH0=(65536-78)/256;
TL0=(65536-78)%256; //定时0.1mS
ET0=1;//定时器中断打开
EA=1;//总中断
//IE= 0x82; //打开中断
TR0=1;
// PWM_ON=15 //的取值范围是6-25
while(1)
{
if(turn_left==0)
{
delay(1000);
if(turn_left==0)
{
while(!turn_left){}
PWM_ON+=1;
if(PWM_ON>25)
PWM_ON=25;
}
}
if(turn_right==0)
{
delay(1000);
if(turn_right==0)
{
while(!turn_right){}
PWM_ON-=1;
if(PWM_ON<6)
PWM_ON=6;
}
}
display();
}
}
/******************************************************************/ /* 定时器中断函数 */ /******************************************************************/ void tim(void) interrupt 1 using 1
{
static unsigned char count;
TH0=(65536-78)/256;
TL0=(65536-78)%256; //定时0.1mS,经过示波器的测量
if (count<PWM_ON)
{
control_signal = 1; //给高电平
}
else
{
control_signal=0 ;
}
count++;
if(count == 200)
{
count=0; //20ms一个周期
}
}。