Forum: Mikrocontroller und Digitale Elektronik while{1} bei MSP430F2013


von Franz Peter Zantis (Gast)


Lesenswert?

Wenn ich den Interrupt für den 16-Bit-ADU setze wird der Code der in der 
while-Schleife steht nicht mehr ausgeführt. Kennt jemand dafür die 
Ursache?

//using the MSP430F2013 as ADU
//December 2012
//data transfer works with blocks of 16 16-Bit-Words (INT16)
#include "msp430x20x3.h"
unsigned int numtotransfer = 16;
unsigned int values[32];   //space for 32 values
unsigned int counter = 0;
unsigned int i=0;         //for-next-counter
unsigned int j=0;         //upper or lower 16 values
unsigned int dataready = 0;   //indicates if a packages of 16 values is 
ready


int main( void )
{
  WDTCTL = WDTPW + WDTHOLD;     //Stop watchdog timer to prevent time 
out reset

  //prepare for using an external oscillator
  _BIS_SR(SCG0);                //switch of DCO
  __bic_SR_register(OSCOFF);    //switch of internal oscillator LFXT1
  BCSCTL3 &= ~BIT2;             //minimize crystal capacity
  BCSCTL3 &= ~BIT3;             //minimize crystal capacity
  BCSCTL3 |= BIT4;              //switch XIN for external clock
  BCSCTL3 |= BIT5;              //switch XIN for external clock
  BCSCTL2 &= ~BIT1;             //divider for SMCLK = 1
  BCSCTL2 &= ~BIT2;             //divider for SMCLK = 1
  BCSCTL2 |= BIT3;              //select SMCLK = LFXT1CLK or VLOCLK
  BCSCTL2 &= ~BIT4;             //divider for MCLK = 1
  BCSCTL2 &= ~BIT5;             //divider for MCLK = 1
  BCSCTL2 |= BIT6;              //select MCLK = LFXT1CLK or VLOCLK
  BCSCTL2 |= BIT7;              //select MCLK = LFXT1CLK or VLOCLK

  //init Ports
  P1DIR = BIT4;                         //P1.4 to output direction
  P1SEL = BIT4;                         //SMCLK to P1.4

  P1DIR |= BIT2;                        //P1.2 to output direction (a 
set of 16-Bit-Words is ready)

  P1DIR |= BIT3;                        //P1.3 to output direction
  P1SEL |= BIT3;                        //Uref to P1.3

  P2SEL &= ~BIT7;                       //P2.7 for normal input/output 
use
  P2DIR |= BIT7;                        //P2.7 to output direction 
(handshake signal DRDY)
  P1OUT |= BIT7;                        //P2.7 default to high 
(DRDY=high)

  //init USI-SPI
  USICTL0 &= ~USISWRST;                 //USI released for operation
  USICTL1 &= ~USII2C;                   //clear the I²C-Bit to switch 
USI to SPI-Mode
  USICTL0 &= ~USIMST;                   //reset Masterbit to be 
SPI-Slave
  USICTL0 |= USIPE5;                    //SPI-clock via P1.5 (from 
Warrior56)
  USICTL0 |= USIPE6;                    //SDO-Port enabled; Pin8, P1.6
  USICTL0 |= USIPE7;                    //SDI-Port enabled; Pin9, P1.7
  USICTL0 &= ~USILSB;                   //MSB first
  USICKCTL &= ~USICKPL;                 //clock is low when idle
  USICTL1 &= ~USICKPH;                  //get data on the first edge
  USICTL0 |= USIOE;                     //activate output (data goes 
from MSP to Warrior56)
  USICNT |= USI16B;                     //SPI-Register USISR for 
16-Bit-data

  //init ADC SD16
  SD16CTL = SD16REFON;                  //activate reference 1,2V
  SD16CTL |= SD16SSEL_1;                //clock for ADU is SMCLK
  SD16CTL |= SD16XDIV_2;                //divider through 16
  SD16CTL |= SD16DIV_2;                 //divider through 4; both 
divider results for 250kHz for the ADU
  SD16INCTL0 = SD16INCH_4;              //input via A4, P1.1, Pin3
  SD16CCTL0 = SD16UNI;                  //16-Bit unsigned
  SD16CCTL0 |= SD16IE;                  //interrupt enabled for ADU
  SD16CCTL0 &= ~SD16XOSR;
  SD16CCTL0 |= SD16OSR_512;             //parameter of the 
low-pass-filter 250kHz/512=488Hz Samplerate
  SD16CCTL0 |= SD16SC;                  //start conversion

  _BIS_SR(GIE);     //enable all interrupts


  while(1)
  {
    P2OUT |= BIT7;    //stop data transfer via handshake
    if (dataready > 0)
    {
      P2OUT &= ~BIT7;   //handshake: data can be shift
      for(i=0; i < numtotransfer; i++)
      {
        USISR=values[i+j];       //write current value into the 
SPI-Register
        USICNT |= 16;            //load counter and start transmission 
with 16 Bit-Word
        while(!(USIIFG & USICTL1));  //wait until data are transfered
      }
      P2OUT |= BIT7;   //handshake: stop datashift
      dataready=0;
    }
  }
}







#pragma vector = SD16_VECTOR
  __interrupt void SD16ISR(void)
  {
    values[counter] = SD16MEM0;
    counter++;
    P2OUT |= BIT7; //no data transfer allowed: handshake is high

    if (counter == numtotransfer)
    {
      P1OUT &= ~BIT2;   //P1.2 to low if the lower set of 16-Bit-Words 
is ready
      j=0;
      dataready = 1;
    }

    if (counter == (numtotransfer * 2))
    {
      counter = 0;
      P1OUT |= BIT2;    //P1.2 to high if the upper set of 16-Bit-Words 
is ready
      j = numtotransfer;
      dataready = 1;
    }
 }

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Wenn der Code in main() nicht mehr ausgeführt wird, ist anzunehmen, daß 
die Interruptroutine ständig aufgerufen wird, also sofort wieder, wenn 
sie verlassen wird.

Du solltest die Interruptbedingung zurücksetzen.

von BL (Gast)


Lesenswert?

Genau. Einfach am Ende der Interrupt routine das interrupt flag löschen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.