cpolymeris

MSP430 Pentax IR intervalometer 2

Jun 19th, 2012
113
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.88 KB | None | 0 0
  1. #include <msp430.h>
  2. #include <signal.h>
  3.  
  4. #define IR_LED      BIT6
  5. #define TRIGGER     BIT3
  6. #define STATUS_LED  BIT0
  7.  
  8. static volatile int cycle_count;                    // IR carrier cycle count
  9. unsigned long time = 0;                             // current time, 1 click = 32.8ms
  10. unsigned long last_shot = 0;                        // time of last manual shot
  11. unsigned long interval = 100;                       // currently set interval
  12. unsigned long trigger_down_time = 0;                // time button was depressed
  13. int trigger_down = 0;
  14. int interval_on = 0;
  15. int manual_shot = 0;
  16.  
  17. #pragma vector = WDT_VECTOR
  18. __interrupt void wdt_isr(void)
  19. {
  20.     time++;
  21.     __bic_SR_register_on_exit(LPM1_bits);
  22. }
  23.  
  24. #pragma vector = TIMERA0_VECTOR                     // Timer A Capture/Compare 0 interrupt
  25. __interrupt void timera0_isr(void)                  // This ISR must be very simple because there may
  26.                                                     // be as few as 16 cycles available for it to complete
  27. {                                                   //
  28.     --cycle_count;                                  // Decrement cycle count
  29. }
  30.  
  31. #pragma vector = PORT1_VECTOR
  32. __interrupt void port1_isr(void)
  33. {
  34.     if (P1IFG & TRIGGER)
  35.     {
  36.         P1IES ^= TRIGGER;                           // switch interrupt direction
  37.         trigger_down = !trigger_down;               // toggle state
  38.         trigger_down_time = time;
  39.         manual_shot = trigger_down;
  40.         __bic_SR_register_on_exit(LPM1_bits);
  41.     }
  42.  
  43.     P1IFG = 0;                                     // clear p1 interrupts
  44. }                                              
  45.  
  46.  
  47.  
  48. static const int pentax[] = {
  49.     26,                                             // Carrier period in us ( 1 MHz / 38 kHz ~= 26 )
  50.     8,                                              // Number of pairs
  51.     500, 115,                                       // 13 ms on, 3 ms off
  52.     38, 39,                                         // 1 ms on, 1 ms off
  53.     38, 39,                                         // 1 ms on, 1 ms off
  54.     38, 39,                                         // 1 ms on, 1 ms off
  55.     38, 39,                                         // 1 ms on, 1 ms off
  56.     38, 39,                                         // 1 ms on, 1 ms off
  57.     38, 39,                                         // 1 ms on, 1 ms off
  58.     38, 39                                          // 1 ms on, 1 ms off
  59. };
  60.  
  61. void send_code(const int *code)
  62. {
  63.     TACCR0 = *code++ - 1 ;                          // Set timer period
  64.     TACCR1 = TACCR0 >> 1;                           // Set timer on duration - 50% duty cycle
  65.     int pair = *code++;                             // Get pair count
  66.     cycle_count = 5;                                // Setup some initial IR off lead in
  67.     TACCTL0 = CCIE;                                 // Enable Timer A CC0 interrupt
  68.     do {                                            // Do all pairs
  69.         int cc = *code++;                           // Get on cycles
  70.         while(cycle_count > 0);                     // Wait for off cycles to complete
  71.         TACCTL1 = OUTMOD_7;                         // Turn on IR
  72.         cycle_count += cc;                          // Set on cycle count
  73.         cc = *code++;                               // Get off cycles
  74.         while(cycle_count > 0);                     // Wait for on cycles to complete
  75.         TACCTL1 = OUTMOD_0;                         // Turn off IR
  76.         cycle_count += cc;                          // Set off cycle count                                                  
  77.     } while(--pair);                                // Decrement pair count, do next pair if not zero
  78.     while(cycle_count > 0);                         // Wait for off cycles to complete
  79.     TACCTL0 = 0;                                    // Turn off Timer A CC0 interrupt
  80. }
  81.  
  82. int main(void)
  83. {
  84.     WDTCTL = WDTPW | WDTHOLD;                       // Disable watchdog reset
  85.     DCOCTL = 0;                                     // Run at 1 MHz
  86.     BCSCTL1 = CALBC1_1MHZ;                          //
  87.     DCOCTL = CALDCO_1MHZ;                           //
  88.  
  89.     P1DIR |= TRIGGER;                               // Set P1.3 to input
  90.     P1IE  |= TRIGGER;                               // P1.3 enabled interrupts
  91.     P1IES |= TRIGGER;                               // P1.3 Hi/lo edge
  92.     P1IFG &= ~TRIGGER;                              // P1.3 clear IFG
  93.  
  94.     TACTL = TASSEL_2 | MC_1;                        // Timer A config: SMCLK, count up
  95.     TACCTL1 = OUTMOD_0;                             // Make sure IR is off
  96.  
  97.     P1OUT = IR_LED;                                  
  98.     P1DIR = STATUS_LED | IR_LED;                    // Enable PWM output on P1.6
  99.     P1SEL = IR_LED;
  100.  
  101.     WDTCTL = WDTPW | WDTTMSEL | WDTCNTCL;
  102.     IE1 |= WDTIE;
  103.  
  104.     eint();                                         // Enable global interrupts
  105.  
  106.     while(1) {            
  107.         if (interval_on && (time - last_shot >= interval)) // intervalometer
  108.         {
  109.             send_code(pentax);                      // Send Pentax IR code
  110.             last_shot = time;
  111.         }
  112.  
  113.         if (manual_shot)                            // manual triggering
  114.         {
  115.             manual_shot = 0;
  116.             send_code(pentax);
  117.             interval = time - last_shot;            // save interval
  118.             interval = (interval > 15? interval: 15);
  119.             last_shot = time;
  120.         }
  121.        
  122.         if (trigger_down && (time - trigger_down_time) > 30)
  123.                                                     //  hold button for 1 sec to switch modes
  124.         {
  125.             trigger_down_time = time;
  126.             interval_on = !interval_on;
  127.             if (interval_on)
  128.                 P1OUT ^= STATUS_LED;
  129.             else
  130.                 P1OUT &= ~STATUS_LED;
  131.         }
  132.        
  133.         __bis_SR_register(LPM1_bits + GIE);
  134.     }
  135.     return 1;
  136. }
Advertisement
Add Comment
Please, Sign In to add comment