alpha 發表於 2013-8-12 17:31:37

Launchpad+CD4017 8 Servo Control

看這個版面有點冷,先來一些
Souece Codemain.c


/*
* main.c MSP430G2553 Control 8 SERVO With CD4017
* CD4017 With 8 Servos
* connect Servo Signal to CD4017.Output1...Output8
*/
#include <msp430g2553.h>

#define CPU_FQ 16 //16Mhz
#define CPU_F 16000000
#define SERVO_INIT 1000

void delay_us( double x)
{

unsigned long count=0;
while(count++<=(x*CPU_FQ))

_nop();
}

void delay_ms(unsigned long x)
{
unsigned long count=0;
while(count++<=(x*CPU_FQ*1000))

_nop();
}

#define delay_us(x) __delay_cycles((long)(CPU_F*(double)x/1000000.0))
#define delay_ms(x) __delay_cycles((long)(CPU_F*(double)x/1000.0))

#define CLK_0       P1OUT &=~BIT0
#define CLK_1       P1OUT |= BIT0// CD4017.CLK on P1.0
#define RST_0       P2OUT &=~BIT6
#define RST_1       P2OUT |= BIT6// CD4017.RST on P2.6


unsigned int postion={0,100,300,500,600,750,900,999};//Servo Position from 0 to 999
unsigned char yn=0;

void delayus(long i)
{

TACCR0 = i;

TACTL = TASSEL_2+ID_3+ MC_1;// SMCLK, div 8, up mode,TACTL = TASSEL_2 + MC_1 + ID_3+

TACCTL0 = CCIE;      // Enable interrupts for CCR0.

yn=1;
                                       // clear timer

__enable_interrupt();

while(yn==1);

_disable_interrupt();
}

void run_servo(void)
{
unsigned char icount=0;
RST_0;
// to move CD4017 to Output 1
CLK_1;
delayus(1);
CLK_0;
while(icount<8)
{

delayus(SERVO_INIT+postion);

CLK_1;

delay_us(1);

CLK_0;
}
// to move CD4017 to Output 0
CLK_1;
delayus(1);
CLK_0;
delayus(9000);
RST_1;
//delay_us(1);
}



void main(void)
{
unsigned int i,j;
WDTCTL = WDTPW + WDTHOLD;//關閉看門狗
BCSCTL1 = CALBC1_8MHZ;                  // Set DCO to 16MHz
DCOCTL =CALDCO_8MHZ; // enable P2.6 / P2.7 to Digial IO
P1SEL = 0;// set P1 to digial IO
P2SEL = 0;// set P2 to digial IO
P1DIR = BIT0; // Set P1.0 to Outpot
P2DIR = BIT6; //設定P2.6為輸出
while(1)
{
      run_servo();
}
}
#pragma vector = TIMER0_A0_VECTOR
__interrupt void Timer0_A0 (void)
{

yn=0;
}
/*
/*
*
* This file is part of the MSP430 PWM example. It controls two servos on P1.6 and P2.2.
*
* Copyright (C) 2012 Stefan Wendler <sw@kaltpost.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.If not, see <http://www.gnu.org/licenses/&gt;.


#include<msp430.h>

void delay()
{

P1OUT ^= BIT0;


volatile unsigned long i;

i = 49999;

do (i--);

while (i != 0);
}

int main(void)
{

WDTCTL = WDTPW + WDTHOLD;


P1DIR |= BIT0;
// Internal LEDs P1.0 of Launchpad is output

    P1DIR |= BIT6;
// P1.6/TA0.1 is used for PWM, thus also an output -> servo 1
    P2DIR |= BIT2;
// P2.2/TA1.1 is used for PWM, thus also an output -> servo 2


P1OUT = 0;
// Clear all outputs P1

P2OUT = 0;
// Clear all outputs P2


P1SEL |= BIT6;                        // P1.6 select TA0.1 option

P2SEL |= BIT2;                        // P2.2 select TA1.1 option


// if SMCLK is about 1MHz (or 1000000Hz),

// and 1000ms are the equivalent of 1 Hz,

// then, by setting CCR0 to 20000 (1000000 / 1000 * 20)

// we get a period of 20ms

TA0CCR0 = 20000-1;                           // PWM Period TA0.1

TA1CCR0 = 20000-1;                           // PWM Period TA1.1


// setting 1500 is 1.5ms is 0deg. servo pos

TA0CCR1 = 1500;                            // CCR1 PWM duty cycle

TA1CCR1 = 1500;                            // CCR1 PWM duty cycle


TA0CCTL1 = OUTMOD_7;                     // CCR1 reset/set

TA0CTL   = TASSEL_2 + MC_1;                // SMCLK, up mode

TA1CCTL1 = OUTMOD_7;                     // CCR1 reset/set

TA1CTL   = TASSEL_2 + MC_1;                // SMCLK, up mode


// loop just blinks build in LEDs to show activity

for (;;)

{

delay();

TA0CCR1 = 1000;

TA1CCR1 = 2000;


delay();

TA0CCR1 = 1500;

TA1CCR1 = 1500;


delay();

TA0CCR1 = 2000;

TA1CCR1 = 1000;


delay();

TA0CCR1 = 1500;

TA1CCR1 = 1500;

}
}
*/

alpha 發表於 2013-8-12 17:45:01

這是使用 CD4017 來驅動8個Servo,CD4017其實可以 Shift 10 個 PWN 訊號,但是上電時 Output 0 就 HI,所以這一腳不用,如果真的需要用到10個,可以多用一支 IO 來控制 CD4017的電源

來說一下 RC SERVO 的 PWM 訊號,一開始會有一段 1ms 的HI ,接下來的 HI 會決定其轉動的角度,0ms 為 0度, 0.5ms 為 90度,1ms 為 180度,接下來只少需要 18ms 的 Low ,整個 Period 為 20ms ,也就是 50Hz,這是一般Servo 的規格,當然有些可以更快一點
頁: [1]
查看完整版本: Launchpad+CD4017 8 Servo Control