精华内容
下载资源
问答
  • Atmega2560 舵机PWM控制

    2020-11-16 11:04:53
    Atmega2560 舵机PWM控制

    Atmega2560 舵机PWM控制

    舵机Servo 示意图
    在这里插入图片描述
    舵机控制原理
    在这里插入图片描述
    使用芯片:Atmega 2560
    晶振: 16MHz
    产品: freenove_Carwling_Robot
    目标:用16位的四个定时器1,3,4,5分别产生PWM控制12个舵机。由于舵机的控制并不是PWM的硬件连接,所以这里要使用软件中断来控制
    在这里插入图片描述
    在这里插入图片描述
    程序:

    #include <avr/io.h>
    #include <avr/interrupt.h>
    #define F_CPU   16000000UL
    #include <util/delay.h>
    // ********************************************************************************
    // Interrupt Routines
    // ********************************************************************************
    #define scale 180
    
    #define RF_wrist_def 170*182  
    #define RF_elbow_def 110*182 //minus up
    #define RF_shoulder_def 127*182
    
    #define LF_wrist_def 100*182 // inc dn
    #define LF_elbow_def 150*182 //inc up
    #define LF_shoulder_def 130*182 //inc cw
    
    #define RR_wrist_def 170*182
    #define RR_elbow_def 110*182
    #define RR_shoulder_def 90*182
    
    void timer_init(void) { // timer1 init
    	TIMSK1= (1<<TOIE1) | (1<<OCIE1A) | (1<<OCIE1B) | (1<<OCIE1C);
    	TCCR1B |= (1 << CS10) ;// turn on 16 bit timer1 also with /1024
    	
    	TIMSK3= (1<<TOIE3) | (1<<OCIE3A) | (1<<OCIE3B) | (1<<OCIE3C);
    	TCCR3B |= (1 << CS30) ;// turn on 16 bit timer1 also with /1024
    }
    
    ISR(TIMER1_OVF_vect) { // timer1 overflow
    	PORTA |= 0b00000111; //PA0 <--> D22 //
    }
    ISR(TIMER1_COMPA_vect) { // timer1 match
    	PORTA &= ~0x01;
    }
    ISR(TIMER1_COMPB_vect) {
    	PORTA &= ~0x02;
    }
    ISR(TIMER1_COMPC_vect) {
    	PORTA &= ~0x04;
    }
    void RF_wrist(unsigned char angle) {
    	unsigned int temp = angle*scale;
    	OCR1A = temp;
    }
    void RF_elbow(unsigned char angle) {
    	unsigned int temp = angle*scale;
    	OCR1B = temp;
    }
    void RF_shoulder(unsigned char angle) {
    	unsigned int temp = angle*scale;
    	OCR1C = temp;
    }
    ISR(TIMER3_OVF_vect) { // timer1 overflow
    	PORTC |= 1<<0;  //37<-->PC0
    	PORTD |= 1<<7;	//38<-->PD7
    	PORTG |= 1<<2;	//39<-->PG2
    }
    ISR(TIMER3_COMPA_vect) { // timer3 match
    	PORTC &= ~(1<<0);   //37<-->PC0
    }
    ISR(TIMER3_COMPB_vect) {
    	PORTD &= ~(1<<7);	//38<-->PD7
    }
    ISR(TIMER3_COMPC_vect) {
    	PORTG &= ~(1<<2);	//39<-->PG2
    }
    void LF_wrist(unsigned char angle) {
    	unsigned int temp = angle*scale;
    	OCR3C = temp;
    }
    void LF_elbow(unsigned char angle) {
    	unsigned int temp = angle*scale;
    	OCR3B = temp;
    }
    void LF_shoulder(unsigned char angle) {
    	unsigned int temp = angle*scale;
    	OCR3A= temp;
    }
    
    
    unsigned char RF_wrist_cur = 0;
    unsigned char RF_elbow_cur = 0;
    unsigned char RF_shoulder_cur = 0;
    
    unsigned char LF_wrist_cur = 0;
    unsigned char LF_elbow_cur = 0;
    unsigned char LF_shoulder_cur = 0;
    
    unsigned char RR_wrist_cur = 0;
    unsigned char RR_elbow_cur = 0;
    unsigned char RR_shoulder_cur = 0;
    
    unsigned char LR_wrist_cur = 0;
    unsigned char LR_elbow_cur = 0;
    unsigned char LR_shoulder_cur = 0;
    
    void shape_def(void)
    {
    	PORTK |= (1<<7) | (1<<5);
    	OCR1A = RF_wrist_def;
    	OCR1B = RF_elbow_def;
    	OCR1C = RF_shoulder_def;
    	RF_wrist_cur = RF_wrist_def/scale;
    	RF_elbow_cur = RF_elbow_def/scale;
    	RF_shoulder_cur = RF_shoulder_def/scale;
    	
    	OCR3A = LF_shoulder_def;
    	OCR3B = LF_elbow_def;
    	OCR3C = LF_wrist_def;
    	LF_wrist_cur = LF_wrist_def/scale;
    	LF_elbow_cur = LF_elbow_def/scale;
    	LF_shoulder_cur = LF_shoulder_def/scale;
    	_delay_ms(1000);
    	PORTK &= ~((1<<7) | (1<<5));
    }
    
    void Action1(void){
    	PORTK |= (1<<7) | (1<<5);
    	for(unsigned char i=0;i<22;i++)
    	{
    		RF_elbow_cur-=2;
    		RF_elbow(RF_elbow_cur);
    		RF_wrist_cur-=4;
    		RF_wrist(RF_wrist_cur);
    		
    		LF_elbow_cur+=2;
    		LF_elbow(LF_elbow_cur);
    		LF_wrist_cur+=4;
    		LF_wrist(LF_wrist_cur);
    		_delay_ms(40);
    	}
    	for(unsigned char i=0;i<15;i++)
    	{
    		RF_shoulder_cur-=2;
    		RF_shoulder(RF_shoulder_cur);
    		LF_shoulder_cur+=2;
    		LF_shoulder(LF_shoulder_cur);
    		_delay_ms(20);
    	}
    	for (unsigned char j=0;j<3;j++)
    	{
    		for(unsigned char i=0;i<30;i++)
    		{
    			RF_shoulder_cur+=2;
    			RF_shoulder(RF_shoulder_cur);
    			LF_shoulder_cur-=2;
    			LF_shoulder(LF_shoulder_cur);
    			_delay_ms(20);
    		}
    		for(unsigned char i=0;i<30;i++)
    		{
    			RF_shoulder_cur-=2;
    			RF_shoulder(RF_shoulder_cur);
    			LF_shoulder_cur+=2;
    			LF_shoulder(LF_shoulder_cur);
    			_delay_ms(20);
    		}
    	}
    	PORTK &= ~((1<<7) | (1<<5));
    }
    
    int main( void ) {
    	DDRA = 0xFF;
    	DDRK = 0xFF;
    	DDRC = 0xFF;
    	DDRD = 0xFF;
    	DDRG = 0xFF;
    	timer_init();
    	sei();
    	shape_def();
    	Action1();
    	shape_def();
    	while(true) {
    	}
    }
    
    展开全文
  • 按键控制舵机PWM电路按键控制舵机PWM电路按键控制舵机PWM电路
  • VHDL语言996舵机PWM按键控制实现。
  • 舵机PWM信号介绍 单舵机调速算法 舵机为随动机构
  • 按键控制舵机PWM电路C语言版.rar 单片机 PWM
  • STM32F1通过PWM信号, 控制舵机旋转角度. 完整示例, 代码清晰.
  • Arduino+16PWM舵机驱动板程序16PWM舵机驱动板程序16PWM舵机驱动板程序16PWM舵机驱动板程序
  • 按键控制舵机PWM电路C语言版(含proteus仿真文件,C程序)
  • 假设现在舵机稳定在A点,这时候CPU发出一个PWM信号,舵机全速由A点转向B点,在这个过程中需要一段时间,舵机才能运动到B点。 保持时间为Tw 当Tw≥△T时,舵机能够到达目标,并有剩余时间; 当Tw≤△T时,舵机不能...
  • 舵机PWM转模拟电压(带正反控制) -----------------本文由“麦粒电子”撰写,并提供相应产品服务。---------------- 叙述 上文讲到讲遥控器接收机信号转换成模拟电压,用于驱动直流无刷电机的案例。其中的信号转换...

    舵机PWM转模拟电压(带正反控制)

    -----------------本文由“麦粒电子”撰写,并提供相应产品服务。----------------

    叙述

    上文讲到讲遥控器接收机信号转换成模拟电压,用于驱动直流无刷电机的案例。其中的信号转换器4路转换信号可用于DIY电瓶车电机的场景。有朋友做了一个履带车,左右各安装上一个直流无刷电机(直接用电瓶车电机安装)、再准备一副遥控器,讲遥控器接收机接收机接上信号转换板子,再将输出接到电机驱动器用于控制转速。
    在这里插入图片描述

    这个时候有个问题就出现了。履带车需要原地转向的功能的话,那两个电机就需要一正一反运动。对有些驱动器而言是可以实现正反转控制的,但是这个时候就需要多出一路信号来控制正反转信号线。故在信号转换板子上就需要多一路来控制电器驱动器的正反转信号线,我们这边就设计了一块控制板带用继电器来控制这路信号。
    在这里插入图片描述

    输入输出
    IN1(PWM输入)OUT1(模拟电压);DIR1(继电器常开常闭端)
    IN2(PWM输入)OUT2(模拟电压);DIR2(继电器常开常闭端)

    NOTE:INx输入控制着OUTx电压比例输出,而DIRx动作要看具体的使用模式而动作。

    举例

    履带车模式使用举例:

    油门拨杆不动,就左右转向拨杆推动,那这个时候履带车实际上就是原地转向,那信号转换板识别到这个拨杆信号的时候,就会将一路继电器闭合,另一路常开,同时给出两路模拟电压信号驱动电器转动。这样就实现了正反控制。

    带转向机模式使用举例:

    有些小车的模式是电机驱动前进后退,转向是通过转向机来实现的(汽车就是典型转向机模式)。这个时候其实就需要2路模拟电压信号,和1路正反转继电器信号。遥控器接收机的油门通道和转向通道接到信号转接板,信号转接板根据离油门中位位置大小来判断是正控制还是反控制电器转(给出油门电压和继电器动作控制),转向电压则单独给转向机即可。

    以上就是一些应用场景。当然针对不同的场景,信号转换板的内部程序是不一样的,试使用要求而定。

    欢迎技术交流。。。

    展开全文
  • 51单片机 精确控制舵机pwm

    千次阅读 2016-09-05 19:13:33
    实现特定pwm 100级别舵机控制输出,其他级别也很简单,太低了可能不行 前提条件: 1. 舵机控制频率是 50hz 2. 舵机占空比时间是0.5 - 2.5 ms 算法: 0.5 - 2.5 跨度是2ms (2000 us) 要实现精确控制,100级别...
    /*
    
    实现特定pwm 100级别舵机控制输出,其他级别也很简单,太低了可能不行


    前提条件:
    1. 舵机控制频率是 50hz
    2. 舵机占空比时间是0.5 - 2.5 ms
    算法:
    0.5 - 2.5 跨度是2ms (2000 us)
    要实现精确控制,100级别, 2ms / 100 = 20us,定时器基准时间就是20us
    内部计数器pwm_cnt 取值范围是25 - 125 产生0.5 ms - 2.5ms的高电平时间
    低电平,不精确调整,采用500us定时基准,有一定的误差,但是应该不影响。
    */


    //TL0 = 0xEE; //设置定时初值
    //TH0 = 0xFF; //设置定时初值 20us 重装值


    //TL0 = 0x33; //设置定时初值
    //TH0 = 0xFE; //设置定时初值 500 us重装值
    unsigned char pwm_flag;
    unsigned char pwm_cnt;


    unsigned char duty_cycle; //舵机占空比 (0 - 100)
    sbit pwm_out = P1 ^ 1;


    void timer0_isr(void) interrupt 1 using 1
    {
        if(pwm_flag)
        {
            TL0 = 0xEE;
            TH0 = 0xFF;//重装20us值
            pwm_cnt++;
            if(pwm_cnt == duty_cycle + 25)
            {
                pwm_out = 0;
                pwm_cnt = 0;
                pwm_flag = 0;   //翻转pwm_out
            }else
            {
                pwm_out = 1;
            }


        }else
        {
            TL0 = 0x33;
            TH0 = 0xFE;//重装500us值     
            pwm_cnt++;
            if(pwm_cnt == 35)
            {
                pwm_cnt = 0;
                pwm_out = 1;
                pwm_flag = 1;   //翻转pwm_out
            }else{
                pwm_out = 0;
            }
        }


    }


    void Timer0Init(void) //20微秒@11.0592MHz
    {
        TMOD = 0x01;                    //set timer0 as mode1 (16-bit)
        TL0 = 0xEE;                     //initial timer0 low byte
        TH0 = 0xFF;                //initial timer0 high byte
        TR0 = 1;                        //timer0 start running
        ET0 = 1;                        //enable timer0 interrupt
        EA = 1;                         //open global interrupt switch


        pwm_cnt = 0;
        pwm_flag = 1;               // 高电平先行
    }
    void main(void)
    {
        Timer0Init();
        duty_cycle = 99;
        while(1);
        return;

    }


    用模拟器调试,应该可以,没有在实际的舵机上调试,应该超不多。

    展开全文
  • 不用定时器,使用特殊的软件延时方法可以达到多路PWM控制舵机,即使不能并行输出的C51也可以做到
  • #资源达人分享计划#
  • AT89S52定时器0控制舵机正反转程序
  • 使用方法含在代码的注释内,只要有基础的单片机知识即可了解,及其详尽
  • 以proteus和keil软件为基础,介绍了在proteus环境下利用51单片机产生多路pwm脉冲的实现方法。
  • PWM,SBUS,PPM信号转模拟电压的方案 -----------------本文由“麦粒电子”撰写,并提供相应产品服务和交流。---------------- 案例场景 有个内部采用电瓶车的驱动器的无线小车,现在需要使用遥控器控制小车的前进...

    PWM,SBUS,PPM信号转模拟电压的方案

    -----------------本文由“麦粒电子”撰写,并提供相应产品服务和交流。----------------

    • 案例场景

      有个内部采用电瓶车的驱动器的无线小车,现在需要使用遥控器控制小车的前进后退。也就是说:把之前电瓶车的手动油门把手换成无线控制的。

      遥控器选择目前市面上有好多的品牌:“天地飞,futaba,斯翼等。遥控器分为接收器和发射器:发射器就是控制人手里拿的摇杆那一部分;接收器则是信号接收端。用来给小车的电机驱动器发送信号的。

      但是现在有个问题,接收机的输出信号并不能直接给电机驱动器使用。因为常见遥控接收机的输出信号一般有三种:舵机PWM信号、SBUS、PPM。而电瓶车的电机驱动器的输入信号要求一般是个模拟电压(常见的电瓶车把手其实就是一个旋转电位器,旋转到不同的位置会输出不同的电压值,以此来控制电机驱动器,从而达到调节电机转速的问题。)

      因此,要想使用遥控器,必须解决接收机输出信号转成模拟电压的问题。为此,我们设计了一款信号转换模块。下图为增加转换板之后的系统框架图

    • 解决方案

      1. 舵机PWM转电压

        舵机PWM,基本上每个接收机都会输出的一种比较常见PWM信号:一般信号频率50HZ,信号高电平变化时间在1ms-2ms之间变化(不同的遥控器会有小幅度的差异)。舵机PWM基础知识请点击:转载于CSDNPinus_x博主。

        转换模块的核心思路就是采集接收机输出的PWM型号,接着分析高电平时间,然后根据高电平时间输出相应的线性变化模拟电压值。

        一般舵机PWM输出的高电平时间为1ms-2ms之间变化,但是实际上我们为了匹配不同的遥控器和留有一定余量,我们设定电平电话的高电平区间为1.1ms-1.9ms之间。也就是说当采集到1.1ms的高电平PWM信号时,模拟电压输出最小值(0V);当采集到1.9ms的高电平时间PWM信号时,模拟电压输出最大值(5V)。

        本文设计的模块中,一共留出了4路PWM转电压的通道。

      2. SBUS信号转电压

        sbus信号是Futaba公司定制的一种数字传输信号,一共数据包中包含了所有遥控器的通道数值。(天地飞管这路信号叫“Wbus”,本质没有区别)因此,本文设计中为sbus(wbus)设计了一路通道,用来收集带有sbus(wbus)等信号输出的接收机。

        在采集完一帧信号后,只根据摇杆变化的4路信号输出相应的4通道电压值。

      3. PPM信号转电压

        PPM信号其实是一种合成的PWM型号。前面单路的舵机PWM信号每个都单独都占用一个硬件 通道,要想4路变化就要有4路单路的硬件通道,这样就会导致硬件接口过多。PPM信号则是把多路PWM信号合成到一路通道。这样既降低了硬件通道的数量,同时也能传输多路PWM信号。

    • 总结

      每个品牌的sbus信号 通道值最大最小值的变化区别也是有区别的,所以为了尽量囊括多种遥控器,模块在程序设计上做了余量考虑。直接反应到每个遥控器的现象就是拨杆最低和最高位置附近会有一段小量程变化,不会引起输出电压值的变化。这并不影响功能的实现(需要说明的是PWM和PPM也做了余量设计)。

      最后,将模块接到接收机和电机控制器的输入端。拨动摇杆,电机转速如期变化。OK,收工。

    展开全文
  • 它具有和舵机相同的控制信号。 ▲ PWM控制的直流电机 下面测量控制信号与它的转动之间的关系。   02测量方式 使用 两轴机械臂整体控制模块 的模块来驱动直流电机模块,使用 SERVO命令改变输出PWM脉冲信号的...
  • 电调和舵机PWM信号

    千次阅读 2019-07-07 19:07:25
    信号频率为50Hz,一个周期为20ms情况下 电调的PWM:高电平脉宽为1ms表示停转,高电平脉宽为2ms表示满油门运转 舵机PWM:高电平脉宽1.5ms是归中,1ms和2ms分别为左右方向满舵(全转) ...
  • STM32——舵机PWM

    2019-07-15 22:19:04
    舵机简介 使用PWM控制舵机
  • pwm控制舵机

    2018-05-13 15:36:20
    stm32f103x系列 pwm波控制舵机转动源程序代码,测试通过
  • PWM舵机驱动

    2021-02-26 19:25:29
    有时候我们也需要去驱动PWM舵机,毕竟价格低廉,实用性强。 这分为两部分,分别在LeServo和PWMServo文件里 文章目录一、底层驱动代码二、二次封装代码 一、底层驱动代码 # PWM舵机驱动 #!/usr/bin/python3 # ...
  • 6路pwm舵机

    2016-07-18 23:07:40
    多路pwm 舵机 stm32f103
  • PWM舵机控制程序

    2018-10-09 14:43:27
    舵机控制程序,及其PWM实现方式,如何控制等实现过程。
  • PWM脉宽信号调制是现代电子行业中使用较为广泛的一种脉冲信号,其典型应用就是舵机控制。以Proteus和Keil软件为基础,介绍了在Proteus环境下利用51单片机产生多路PWM脉冲的实现方法。最后以一个典型的应用实例验证了...
  • PWM控制舵机

    千次阅读 2021-03-03 20:31:05
    学习PWM舵机的控制:舵机的控制就是通过一个固定的频率,给其不同的占空比的,来控制舵机不同的转角。 180度舵机(自用) 舵机频率为50Hz,而脉冲的高电平部分一般为0.5ms-2.5ms范围来控制舵机0-180度。 高电平...
  • PWM6路舵机

    2016-05-18 08:45:20
    STM32PWM控制6路舵机
  • 利用单片机产生7路PWM然后去控制舵机的方法
  • PWM舵机控制

    2018-01-01 13:58:42
    根据工作原理,舵机的具体控制方法就是需要一个20ms左右的时基脉冲, 该脉冲的高电平部分一般为0.5ms~2.5ms范围内的角度控制脉冲部分。 脉冲宽度从0.5ms~2.5ms,相对应舵盘的位置为0~180度,呈线性变化。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,329
精华内容 1,331
关键字:

舵机pwm