Friday, July 19, 2013

MSP430 Reaktionszeitmesser in C mit IAR Embedded Workbench

Reaktionszeitmesser für den Texas Instruments MSP430 

(C) by Sebastian Foss 2013

Als Umgebung habe ich dafür IAR Embedded Workbench benutzt.
Es handelt sich um den MSP430 G2553, welcher auch auf dem TI Launchpad zu finden ist.
Ein wirklich guter, und vorallem sparsamer Controller!

#include "msp430g2553.h"
#include <stdint.h>

#define TASTER BIT3
#define LEDROT BIT0
#define LEDGRUEN BIT6

enum state { start=0, startblinken, zufallwarten, messsetup, messen, zulangsamblinken, inderzeit};

// Schieberegister
  #define SR_DATA BIT5 
  #define SR_SCK  BIT6
  #define SR_RCK  BIT7

// Init - Schieberegister
void init_addon(void){
  P1OUT &= ~(SR_DATA + SR_SCK + SR_RCK);
  P1DIR |= SR_DATA + SR_SCK + SR_RCK;
}

// LED-Bar - Anzeige
void led_bar(int zahl){
  int rest[8], i; 

  for (i=0;i<8;i++)
  {
  rest[i]= zahl%2;
  zahl /= 2;
  }
 
  // Daten seriell rausschieben
  for (i=7; i>=0; i--){
   
    if (rest[i]){
      P1OUT &= ~SR_DATA;     
    }else{
      P1OUT |= SR_DATA;     
    }
   
    P1OUT &= ~SR_SCK;   
    P1OUT |= SR_SCK;
  }   
   
    // Daten 'Freigeben'
    P1OUT &= ~SR_RCK;   
    P1OUT |= SR_RCK;
}
   
volatile uint8_t state=0;

int main( void )
{
  // Stop watchdog timer to prevent time out reset
  WDTCTL = WDTPW + WDTHOLD;
  init_addon();
  P1DIR |= LEDROT+LEDGRUEN;
  P1OUT &=~(LEDROT+LEDGRUEN);
 
  P1REN |= TASTER;
  P1IE |= TASTER;

  BCSCTL2 = DIVS_3;
  TA0CTL=TASSEL_2+ID_3+MC_1+TACLR;
  TA0CCR0 = 7000;
 
  _BIS_SR(LPM0_bits+GIE);
  return 0;
}


#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer0_A0(void)
{static int i=0;
static uint16_t lsfr=0x23AF;

  switch(state) {
    case startblinken: i++; if(i<8) P1OUT^=LEDROT; else {P1OUT&=~LEDROT; state=zufallwarten;i=0;TACCR0=1;} break;
    case zufallwarten:
           P1OUT|=LEDROT;
           TACTL|=TACLR;
           lsfr=(((((lsfr>>5)^(lsfr>>3)^(lsfr>>2)^(lsfr)^(lsfr>>15))&1)<<15)|(lsfr>>1));  //Pseudozufallszahl mit lsfr erzeugen
           if(lsfr<21845) TACCR0=10000;
           if(lsfr>=21845 && lsfr<43690) TACCR0=20000;
           //if(lsfr>=43690 && lsfr<=0xFFFF) TACCR0=30000;
           if(lsfr>=43690) TACCR0=30000;
          
           state=messsetup; break;
    case messsetup: P1OUT&=~LEDROT; TACCR0=10000; TACTL|=TACLR; state=messen; break;
    case messen: P1OUT^=LEDROT; state=zulangsamblinken; TACCR0=2000;break;
    case zulangsamblinken: P1OUT^=LEDROT; break;

    default:break;
  }


  }

#pragma vector=PORT1_VECTOR
__interrupt void p1vector(void)
{
  if(!(P1IN&TASTER)) {
      switch(state) {
        case start: led_bar(0);state=startblinken;TACTL|=TACLR; TA0CCR0 = 7000;TA0CCTL0=CCIE; break;
        case messen:
          TA0CCTL0&=~CCIE;
          //P1OUT|=LEDGRUEN;
          led_bar(TAR>>7);
          state=inderzeit;
          break;
        case inderzeit:
          TACTL|=TACLR; P1OUT&=~(LEDROT+LEDGRUEN);
          state=0; break;
        case zulangsamblinken:
          TACTL|=TACLR; P1OUT&=~(LEDROT+LEDGRUEN);
          state=0; break;
        default:break;
      }
  }
 P1IFG=0;
}

No comments:

Post a Comment