Robofun 機器人論壇

 找回密碼
 申請會員
搜索
熱搜: 活動 交友 discuz
查看: 5780|回復: 1

Launchpad+CD4017 8 Servo Control

[複製鏈接]
發表於 2013-8-12 17:31:37 | 顯示全部樓層 |閱讀模式
看這個版面有點冷,先來一些
Souece Code  main.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[8]={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[icount++]);

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;

}
}
*/
 樓主| 發表於 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 的規格,當然有些可以更快一點
您需要登錄後才可以回帖 登錄 | 申請會員

本版積分規則

小黑屋|手機版|Archiver|機器人論壇 from 2005.07

GMT+8, 2024-3-29 03:52 , Processed in 0.191398 second(s), 7 queries , Apc On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回復 返回頂部 返回列表