Skip to content

Instantly share code, notes, and snippets.

@debreuil
Created August 31, 2011 05:02
Show Gist options
  • Select an option

  • Save debreuil/1182852 to your computer and use it in GitHub Desktop.

Select an option

Save debreuil/1182852 to your computer and use it in GitHub Desktop.
7 servos and ADC running on MSP430 LaunchPad
/*
Freeware. source [email protected]
ADC pin: P1.0
PWM signal pin: P1.2
ADC signal is just a light sensor with a 1K resistor to 3.3V
*/
#include <msp430g2231.h>
#define servoCount 7
#define pwmPin0 0x01
#define oneMS 1000
volatile int ADCdata;
int state = 0;
int curServo = 0;
int pinMask = pwmPin0;
int servoLoc[servoCount] = {500,500,500,500,500,500};
int incArray[servoCount] = {7,22,34,58,72,96};
void main(void)
{
WDTCTL = WDT_MDLY_0_5; // WDT ~0.5ms interval timer
IE1 |= WDTIE; // Enable WDT interrupt
// ADC
ADC10CTL0 = ADC10SHT_2 + ADC10ON; // sample and hold 16 cycles, ref on
ADC10AE0 |= INCH_1; // P1.0 ADC option select
ADC10DTC1 = 0x002; // 2 conversions
// first pin and [count] consecutive to out
P1DIR |= ((1 << servoCount) - 1) * (pwmPin0 << 1);
P1OUT = 0; // set all out pins to 0
BCSCTL1 = CALBC1_1MHZ; // Running at 1 MHz
DCOCTL = CALDCO_1MHZ;
TACTL = MC_0; // off
while(1)
{
__bis_SR_register(LPM0_bits + GIE); // LPM0, WDT_ISR will force exit
if((state % 4 == 0) && (state < servoCount * 4))
{
curServo = state >> 2;
pinMask = (1 << curServo) * (pwmPin0 << 1);
if(curServo == (servoCount - 1)) // special case ADC controlled servo
{
// adc10 is 10 bit, so 0-1024. 1100 is about 1ms, so it works out without scaling.
servoLoc[curServo] = (ADCdata - 450) * 5;
}
else // these just go up and down at different rates
{
servoLoc[curServo] += incArray[curServo];
if( (servoLoc[curServo] >= 900) || (servoLoc[curServo] <= 100) )
{
if(curServo == 0)
{
curServo = 0;
}
incArray[curServo] = -incArray[curServo];
}
}
// turn on out pin, timerA reaching TACCR0 will fire an event that turns it off
P1OUT |= pinMask;
// count 1ms plus 0-1ms pulses on aclk which is calibrated 1MHz
TACCR0 = servoLoc[curServo] + oneMS;
TACTL = TASSEL_2 + MC_1 + TAIE + TACLR + OUT; // ACLK, upmode, interrupt enabled
TACCTL0 |= CCIE;
}
else if(state == 30) // read analog input before wrap around at 40 0.5ms counts
{
ADC10SA = (unsigned int)&ADCdata; // store data here
ADC10CTL0 |= ENC + ADC10SC; // Start sampling
}
state++;
if(state >= 40)
{
state = 0;
}
}
}
#pragma vector = TIMERA0_VECTOR
__interrupt void CCR0_ISR(void)
{
//TACCTL0 &= ~CCIE;
TACTL = MC_0; // timer A off, interrupt disabled
P1OUT = 0;
}
#pragma vector = WDT_VECTOR
__interrupt void WDT_ISR(void)
{
__bic_SR_register_on_exit(LPM0_bits); // Exit LPM0
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment