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; } }
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.