Created
August 31, 2011 05:02
-
-
Save debreuil/1182852 to your computer and use it in GitHub Desktop.
7 servos and ADC running on MSP430 LaunchPad
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| 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