Jump to content

ahgan84

Members
  • Content Count

    68
  • Joined

  • Last visited

Everything posted by ahgan84

  1. void main(void) { unsigned int i,j; WDTCTL = WDTPW+WDTHOLD; // Hold WDT REFCTL0 &= ~REFMSTR; P1OUT &= ~BIT0; // P1.0 clear P1DIR |= BIT0; // P1.0 output P5SEL |= BIT7; // P5.7/TB1 option select P5DIR |= BIT7; // Output direction P6SEL |= 0xFF; P7SEL |= 0x0F; P5SEL |= 0x03; // Setup ADC12 ADC12CTL0 &= ~ADC12ENC; ADC12CTL0 = ADC12SHT0_6+ADC12SHT1_6+ADC12MSC+ADC12ON+ADC12REF2_5V+ADC12REFON; ADC12CTL1 = ADC12SHP+ADC12CONSEQ_3;//ADC12SHS_3+ADC12CONSEQ_3; ADC12CTL2 = ADC12RES_2;//+ADC12REFOUT; ADC12MCTL0 = ADC12SREF_1+ADC12INCH_0; ADC12MCTL1 = ADC12SREF_1+ADC12INCH_1; ADC12MCTL2 = ADC12SREF_1+ADC12INCH_2; ADC12MCTL3 = ADC12SREF_1+ADC12INCH_3; ADC12MCTL4 = ADC12SREF_1+ADC12INCH_4; ADC12MCTL5 = ADC12SREF_1+ADC12INCH_5; ADC12MCTL6 = ADC12SREF_1+ADC12INCH_6; ADC12MCTL7 = ADC12SREF_1+ADC12INCH_7; // ADC12MCTL8 = ADC12SREF_1+ADC12INCH_8; ADC12MCTL9 = ADC12SREF_1+ADC12INCH_9; ADC12MCTL12 = ADC12SREF_1+ADC12INCH_12; ADC12MCTL13 = ADC12SREF_1+ADC12INCH_13; ADC12MCTL14 = ADC12SREF_1+ADC12INCH_14; ADC12MCTL15 = ADC12SREF_1+ADC12INCH_15+ADC12EOS; // Setup DMA0 DMACTL0 = DMA0TSEL_24; // ADC12IFGx triggered DMACTL4 = DMARMWDIS; // Read-modify-write disable DMA0CTL = DMADT_4+DMAEN+DMASRCINCR_3+DMADSTINCR_3+DMAIE; // Rpt single tranfer, inc dst, Int DMA0SZ = 32; // DMA0 size = 1 __data16_write_addr((unsigned short) &DMA0SA,(unsigned long) &ADC12MEM0); // Source block address __data16_write_addr((unsigned short) &DMA0DA,(unsigned long) &DMA_DST[0]); ADC12CTL0 |= ADC12ENC + ADC12SC; // start sampling and conversion // __bis_SR_register(GIE);//(LPM0_bits + GIE); // LPM0 w/ interrupts // __no_operation(); // used for debugging __enable_interrupt(); while (1) { // Channel 0 ///////////////////////////////////////////////////////////////////////////// j = 0; RAWvalue += DMA_DST[j++]; RAWvalue1 += DMA_DST[j++]; RAWvalue2 += DMA_DST[j++]; RAWvalue3 += DMA_DST[j++]; RAWvalue4 += DMA_DST[j++]; RAWvalue5 += DMA_DST[j++]; RAWvalue6 += DMA_DST[j++]; RAWvalue7 += DMA_DST[j+2]; // RAWvalue8 += DMA_DST[j++]; RAWvalue9 += DMA_DST[j+3]; RAWvalue12 += DMA_DST[j++]; RAWvalue13 += DMA_DST[j++]; RAWvalue14 += DMA_DST[j++]; RAWvalue15 += DMA_DST[j++]; } #pragma vector=DMA_VECTOR __interrupt void DMA_ISR(void) { switch(__even_in_range(DMAIV,16)) { case 0: break; case 2: // DMA0IFG = DMA Channel 0 break; case 4: break; // DMA1IFG = DMA Channel 1 case 6: break; // DMA2IFG = DMA Channel 2 case 8: break; // DMA3IFG = DMA Channel 3 case 10: break; // DMA4IFG = DMA Channel 4 case 12: break; // DMA5IFG = DMA Channel 5 case 14: break; // DMA6IFG = DMA Channel 6 case 16: break; // DMA7IFG = DMA Channel 7 default: break; } } I've modified my code to the above coding and it worked. I've list out all the ADC12MCTL0...ADC12MCTL15 and channel 15 is the last channel by putting ADC12EOS on it. My problem is, do I need to set it to increment my DMA source address DMASRCINCR_3? I've tested it with DMASRCINCR_3 on and it can get ADC value from DMA_DST[0] to DMA_DST[15] accurately, but after that from DMA_DST[16], DMA_DST[17], DMA_DST[18].... it get wrong data. Seems like it did not repeat by putting channel 0 data to DMA_DST[16], channel 1 data to DMA_DST[17] and so on... How do we solve this? Is there anything I miss? Your code just show me how you init your ADC10. How bout init DMA? How bout the ISR? Is it the same with single channel sampling? We configure that the ADC stop converting in the repeat single channel setting in ISR for DMA. Then how bout for repeat sequence channel? DO we need to stop the ADC from converting too? Channel 10 is for Temperature Diode and Channel 11 is for (AVCC
  2. Is it that I only need to declare just one line of ADC12MCTL15 or I need to declare ADC12MCTL 0 to ADC12MCTL15 to sample channel 0 - 15? Then if it is just one line, is it I have to put ADC12MCTL0 = ADC12SREF_1+ADC12INCH_15 or ADC12MCTL15 = ADC12SREF_1+ADC12INCH_15? Here is my code for the initialization. I collect one sample from each ADC channel in sequence. But seems like it won't run. The program stuck at 'while (ADC12CTL1 & BUSY)'. Do you know what's wrong? ADC12CTL0 &= ~ADC12ENC; ADC12CTL0 = ADC12SHT0_6+ADC12SHT1_6+ADC12MSC+ADC12ON+ADC12REF2_5V+ADC12REFON;// Sampling time, MSC, ADC12 on ADC12CTL1 = ADC12SHP+ADC12CONSEQ_3;//ADC12SHS_3+ADC12CONSEQ_2; // Use sampling timer; ADC12MEM0 // Sample-and-hold source = CCI0B = // TBCCR1 output // Repeated-single-channel ADC12CTL2 = ADC12RES_2+ADC12REFOUT; // ADC12CTL0 |= ADC12ENC; // Setup DMA0 DMACTL0 = DMA0TSEL_24; // ADC12IFGx triggered DMACTL4 = DMARMWDIS; // Read-modify-write disable // DMA0CTL &= ~DMAIFG; DMA0CTL = DMADT_4+DMAEN+DMADSTINCR_3+DMAIE; // Rpt single tranfer, inc dst, Int DMA0SZ = 16; // DMA0 size = 1 __data16_write_addr((unsigned short) &DMA0SA,(unsigned long) &ADC12MEM0); // Source block address __data16_write_addr((unsigned short) &DMA0DA,(unsigned long) &DMA_DST[0]); while (ADC12CTL1 & BUSY); // wait for adc10 to be ready ADC12MCTL0 = ADC12SREF_1+ADC12INCH_15; // V+=AVcc V-=AVss, A0 - A15 channel ADC12CTL0 |= ADC12ENC + ADC12SC; // start sampling and conversion j = 0; RAWvalue += DMA_DST[j++]; RAWvalue1 += DMA_DST[j++]; RAWvalue2 += DMA_DST[j++]; RAWvalue3 += DMA_DST[j++]; RAWvalue4 += DMA_DST[j++]; RAWvalue5 += DMA_DST[j++]; RAWvalue6 += DMA_DST[j++]; RAWvalue7 += DMA_DST[j+2]; // RAWvalue8 += DMA_DST[j++]; RAWvalue9 += DMA_DST[j+3]; RAWvalue12 += DMA_DST[j++]; RAWvalue13 += DMA_DST[j++]; RAWvalue14 += DMA_DST[j++]; RAWvalue15 += DMA_DST[j++]; } #pragma vector=DMA_VECTOR __interrupt void DMA_ISR(void) { switch(__even_in_range(DMAIV,16)) { case 0: break; case 2: // DMA0IFG = DMA Channel 0 // P1OUT ^= BIT0; // Toggle P1.0 - PLACE BREAKPOINT HERE AND CHECK DMA_DST VARIABLE ADC12CTL0 &= ~ADC12ENC; // disable adc10 to re-select channel after exit // LPM0_EXIT; break; case 4: break; // DMA1IFG = DMA Channel 1 case 6: break; // DMA2IFG = DMA Channel 2 case 8: break; // DMA3IFG = DMA Channel 3 case 10: break; // DMA4IFG = DMA Channel 4 case 12: break; // DMA5IFG = DMA Channel 5 case 14: break; // DMA6IFG = DMA Channel 6 case 16: break; // DMA7IFG = DMA Channel 7 default: break; } } I found out another thing, we won't need to configure the PxSEL register for the ADC12 to work right? I've try putting PxSEL = 0 and I still can get the ADC value. Then how are we going to use those pin (A0 - A15) as I/O?
  3. From my method, each DMA_DST[0] to DMA_DST[255] is equals to a channel. But from your method, DMA_DST[0] is for channel 0, DMA_DST[1] is for channel 1, DMA_DST[2] is for channel 2, DMA_DST[3] is for channel 3, ....., DMA_DST[15] is for channel 15. Then DMA_DST[16] is for channel 0 again, DMA_DST[17] is for channel 1 again... and then repeat again. Am I right? Then is it that my ADC12MCTL0 = ADC12SREF_1+ADC12INCH_15? right_cal = 0; for (r=ADCRIGHT; r < MAXADC; r+=6) { right_cal += ADCdata[r]; } right_cal /= SAMPLES; For your above for loop, what is ADCRIGHT? Is it I will need to increase ADCRIGHT too? Like for example if r=0, then right_cal = ADCdata[0] + ADCdata[6] + ADCdata[12] + ADCdata[18] + ADCdata[24].....If r=1, then right_cal = ADCdata[1] + ADCdata[7] + ADCdata[13] + ADCdata[19]+..... Am I right? Then if 15 channel then my maximum r is also 15 right? Seems like we are doing 15 times of your above for loop. Am I right? I haven't try this code yet but sounds the same with my method because you also use a for loop to sum up the ADC data... It really will speed up the conversion?
  4. for(i=0;i<256;i++) { RAWvalue += DMA_DST[i]; // Summing up 256 raw values } I found out that it is the above for loop which run 256 times to sum up the raw value for each channel that increase my time. Is there any other way that I can write to reduce the time?
  5. Yup. I had downloaded it. I think that you just have change to ADC10MCTL0 = ADC10INCH_15 and then DMA0SZ = 0x0F to scan all 15 channels right? But now I want to collect 256 conversion from each channel and I want to do all channels and it's roughly in total 256x14=3586 (14 channels for my F5325) conversion each time. Below is my code in main(): void main(void) { unsigned int i; WDTCTL = WDTPW+WDTHOLD; // Hold WDT REFCTL0 &= ~REFMSTR; P1OUT &= ~BIT0; // P1.0 clear P1DIR |= BIT0; // P1.0 output P5SEL |= BIT7; // P5.7/TB1 option select P5DIR |= BIT7; // Output direction P6SEL |= 0xFF; P7SEL |= 0x0F; P5SEL |= 0x03; // Setup ADC12 ADC12CTL0 &= ~ADC12ENC; ADC12CTL0 = ADC12SHT0_6+ADC12MSC+ADC12ON+ADC12REF2_5V+ADC12REFON;// Sampling time, MSC, ADC12 on ADC12CTL1 = ADC12SHP+ADC12CONSEQ_2;//ADC12SHS_3+ADC12CONSEQ_2; // Use sampling timer; ADC12MEM0 // Sample-and-hold source = CCI0B = // TBCCR1 output // Repeated-single-channel ADC12CTL2 = ADC12RES_2+ADC12REFOUT; // Setup DMA0 DMACTL0 = DMA0TSEL_24; // ADC12IFGx triggered DMACTL4 = DMARMWDIS; // Read-modify-write disable DMA0CTL = DMADT_4+DMAEN+DMADSTINCR_3+DMAIE; // Rpt single tranfer, inc dst, Int DMA0SZ = 256; // DMA0 size __data16_write_addr((unsigned short) &DMA0SA,(unsigned long) &ADC12MEM0); // Source block address __data16_write_addr((unsigned short) &DMA0DA,(unsigned long) &DMA_DST[0]); // Destination single address __enable_interrupt(); while (1) { // Channel 0 ///////////////////////////////////////////////////////////////////////////// while (ADC12CTL1 & BUSY); // wait for adc10 to be ready ADC12MCTL0 = ADC12SREF_1+ADC12INCH_0; // V+=AVcc V-=AVss, A0 channel ADC12CTL0 |= ADC12ENC + ADC12SC; // start sampling and conversion for(i=0;i<256;i++) { RAWvalue += DMA_DST[i]; // Summing up 256 raw values } OVSresult0[AVGpnt] = RAWvalue >> 4; // Shift right 4 bits, oversampling. RAWvalue = 0; if (AVGpnt == MOVWIN-1) OVSvalue0 -= OVSresult0[0]; // Moving average with MOVWIN window size else OVSvalue0 -= OVSresult0[AVGpnt+1]; OVSvalue0 += OVSresult0[AVGpnt]; Dampvalue0 = OVSvalue0 / MOVWIN; // Divide by MOVWIN to get the average AVGpnt++; /* // Channel 1 ///////////////////////////////////////////////////////////////////////////// while (ADC12CTL1 & BUSY); // wait for adc10 to be ready ADC12MCTL0 = ADC12SREF_1+ADC12INCH_1; // V+=AVcc V-=AVss, A0 channel ADC12CTL0 |= ADC12ENC + ADC12SC; // start sampling and conversion // LPM0; // sleep until conversions are transferred by dma for(i=0;i<256;i++) { RAWvalue1 += DMA_DST[i]; // Summing up 256 raw values } OVSresult1[AVGpnt1] = RAWvalue1 >> 4; // Shift right 4 bits, oversampling. RAWvalue1 = 0; if (AVGpnt1 == MOVWIN-1) OVSvalue1 -= OVSresult1[0]; // Moving average with MOVWIN window size else OVSvalue1 -= OVSresult1[AVGpnt1+1]; OVSvalue1 += OVSresult1[AVGpnt1]; Damp1value0 = OVSvalue1 / MOVWIN; // Divide by MOVWIN to get the average // Channel 2 ///////////////////////////////////////////////////////////////////////////// while (ADC12CTL1 & BUSY); // wait for adc10 to be ready ADC12MCTL0 = ADC12SREF_1+ADC12INCH_2; // V+=AVcc V-=AVss, A0 channel ADC12CTL0 |= ADC12ENC + ADC12SC; // start sampling and conversion // LPM0; // sleep until conversions are transferred by dma for(i=0;i<256;i++) { RAWvalue2 += DMA_DST[i]; // Summing up 256 raw values } OVSresult2[AVGpnt2] = RAWvalue2 >> 4; // Shift right 4 bits, oversampling. RAWvalue2 = 0; if (AVGpnt2 == MOVWIN-1) OVSvalue2 -= OVSresult2[0]; // Moving average with MOVWIN window size else OVSvalue2 -= OVSresult2[AVGpnt2+1]; OVSvalue2 += OVSresult2[AVGpnt2]; Damp2value0 = OVSvalue2 / MOVWIN; // Divide by MOVWIN to get the average // Channel 3 ///////////////////////////////////////////////////////////////////////////// while (ADC12CTL1 & BUSY); // wait for adc10 to be ready ADC12MCTL0 = ADC12SREF_1+ADC12INCH_3; // V+=AVcc V-=AVss, A0 channel ADC12CTL0 |= ADC12ENC + ADC12SC; // start sampling and conversion // LPM0; // sleep until conversions are transferred by dma for(i=0;i<256;i++) { RAWvalue3 += DMA_DST[i]; // Summing up 256 raw values } OVSresult3[AVGpnt3] = RAWvalue3 >> 4; // Shift right 4 bits, oversampling. RAWvalue3 = 0; if (AVGpnt3 == MOVWIN-1) OVSvalue3 -= OVSresult3[0]; // Moving average with MOVWIN window size else OVSvalue3 -= OVSresult3[AVGpnt3+1]; OVSvalue3 += OVSresult3[AVGpnt3]; Damp3value0 = OVSvalue3 / MOVWIN; // Divide by MOVWIN to get the average // Channel 4 ///////////////////////////////////////////////////////////////////////////// while (ADC12CTL1 & BUSY); // wait for adc10 to be ready ADC12MCTL0 = ADC12SREF_1+ADC12INCH_4; // V+=AVcc V-=AVss, A0 channel ADC12CTL0 |= ADC12ENC + ADC12SC; // start sampling and conversion // LPM0; // sleep until conversions are transferred by dma for(i=0;i<256;i++) { RAWvalue4 += DMA_DST[i]; // Summing up 256 raw values } OVSresult4[AVGpnt4] = RAWvalue4 >> 4; // Shift right 4 bits, oversampling. RAWvalue4 = 0; if (AVGpnt4 == MOVWIN-1) OVSvalue4 -= OVSresult4[0]; // Moving average with MOVWIN window size else OVSvalue4 -= OVSresult4[AVGpnt4+1]; OVSvalue4 += OVSresult4[AVGpnt4]; Damp4value0 = OVSvalue4 / MOVWIN; // Divide by MOVWIN to get the average // Channel 5 ///////////////////////////////////////////////////////////////////////////// while (ADC12CTL1 & BUSY); // wait for adc10 to be ready ADC12MCTL0 = ADC12SREF_1+ADC12INCH_5; // V+=AVcc V-=AVss, A0 channel ADC12CTL0 |= ADC12ENC + ADC12SC; // start sampling and conversion // LPM0; // sleep until conversions are transferred by dma for(i=0;i<256;i++) { RAWvalue5 += DMA_DST[i]; // Summing up 256 raw values } OVSresult5[AVGpnt5] = RAWvalue5 >> 4; // Shift right 4 bits, oversampling. RAWvalue5 = 0; if (AVGpnt5 == MOVWIN-1) OVSvalue5 -= OVSresult5[0]; // Moving average with MOVWIN window size else OVSvalue5 -= OVSresult5[AVGpnt5+1]; OVSvalue5 += OVSresult5[AVGpnt5]; Damp5value0 = OVSvalue5 / MOVWIN; // Divide by MOVWIN to get the average // Channel 6 ///////////////////////////////////////////////////////////////////////////// while (ADC12CTL1 & BUSY); // wait for adc10 to be ready ADC12MCTL0 = ADC12SREF_1+ADC12INCH_6; // V+=AVcc V-=AVss, A0 channel ADC12CTL0 |= ADC12ENC + ADC12SC; // start sampling and conversion // LPM0; // sleep until conversions are transferred by dma for(i=0;i<256;i++) { RAWvalue6 += DMA_DST[i]; // Summing up 256 raw values } OVSresult6[AVGpnt6] = RAWvalue6 >> 4; // Shift right 4 bits, oversampling. RAWvalue6 = 0; if (AVGpnt6 == MOVWIN-1) OVSvalue6 -= OVSresult6[0]; // Moving average with MOVWIN window size else OVSvalue6 -= OVSresult6[AVGpnt6+1]; OVSvalue6 += OVSresult6[AVGpnt6]; Damp6value0 = OVSvalue6 / MOVWIN; // Divide by MOVWIN to get the average // Channel 7 ///////////////////////////////////////////////////////////////////////////// while (ADC12CTL1 & BUSY); // wait for adc10 to be ready ADC12MCTL0 = ADC12SREF_1+ADC12INCH_7; // V+=AVcc V-=AVss, A0 channel ADC12CTL0 |= ADC12ENC + ADC12SC; // start sampling and conversion // LPM0; // sleep until conversions are transferred by dma for(i=0;i<256;i++) { RAWvalue7 += DMA_DST[i]; // Summing up 256 raw values } OVSresult7[AVGpnt7] = RAWvalue7 >> 4; // Shift right 4 bits, oversampling. RAWvalue7 = 0; if (AVGpnt7 == MOVWIN-1) OVSvalue7 -= OVSresult7[0]; // Moving average with MOVWIN window size else OVSvalue7 -= OVSresult7[AVGpnt7+1]; OVSvalue7 += OVSresult7[AVGpnt7]; Damp7value0 = OVSvalue7 / MOVWIN; // Divide by MOVWIN to get the average /* // Channel 8 ///////////////////////////////////////////////////////////////////////////// while (ADC12CTL1 & BUSY); // wait for adc10 to be ready ADC12MCTL0 = ADC12SREF_1+ADC12INCH_8; // V+=AVcc V-=AVss, A0 channel ADC12CTL0 |= ADC12ENC + ADC12SC; // start sampling and conversion // LPM0; // sleep until conversions are transferred by dma for(i=0;i<256;i++) { RAWvalue8 += DMA_DST[i]; // Summing up 256 raw values } OVSresult8[AVGpnt8] = RAWvalue8 >> 4; // Shift right 4 bits, oversampling. RAWvalue8 = 0; if (AVGpnt8 == MOVWIN-1) OVSvalue8 -= OVSresult8[0]; // Moving average with MOVWIN window size else OVSvalue8 -= OVSresult8[AVGpnt8+1]; OVSvalue8 += OVSresult8[AVGpnt8]; Damp8value0 = OVSvalue8 / MOVWIN; // Divide by MOVWIN to get the average // Channel 9 ///////////////////////////////////////////////////////////////////////////// while (ADC12CTL1 & BUSY); // wait for adc10 to be ready ADC12MCTL0 = ADC12SREF_1+ADC12INCH_9; // V+=AVcc V-=AVss, A0 channel ADC12CTL0 |= ADC12ENC + ADC12SC; // start sampling and conversion // LPM0; // sleep until conversions are transferred by dma for(i=0;i<256;i++) { RAWvalue9 += DMA_DST[i]; // Summing up 256 raw values } OVSresult9[AVGpnt9] = RAWvalue9 >> 4; // Shift right 4 bits, oversampling. RAWvalue9 = 0; if (AVGpnt9 == MOVWIN-1) OVSvalue9 -= OVSresult9[0]; // Moving average with MOVWIN window size else OVSvalue9 -= OVSresult9[AVGpnt9+1]; OVSvalue9 += OVSresult9[AVGpnt9]; Damp9value0 = OVSvalue9 / MOVWIN; // Divide by MOVWIN to get the average // Channel 12 ///////////////////////////////////////////////////////////////////////////// while (ADC12CTL1 & BUSY); // wait for adc10 to be ready ADC12MCTL0 = ADC12SREF_1+ADC12INCH_12; // V+=AVcc V-=AVss, A0 channel ADC12CTL0 |= ADC12ENC + ADC12SC; // start sampling and conversion // LPM0; // sleep until conversions are transferred by dma for(i=0;i<256;i++) { RAWvalue12 += DMA_DST[i]; // Summing up 256 raw values } OVSresult12[AVGpnt12] = RAWvalue12 >> 4; // Shift right 4 bits, oversampling. RAWvalue12 = 0; if (AVGpnt12 == MOVWIN-1) OVSvalue12 -= OVSresult12[0]; // Moving average with MOVWIN window size else OVSvalue12 -= OVSresult12[AVGpnt12+1]; OVSvalue12 += OVSresult12[AVGpnt12]; Damp12value0 = OVSvalue12 / MOVWIN; // Divide by MOVWIN to get the average // Channel 13 ///////////////////////////////////////////////////////////////////////////// while (ADC12CTL1 & BUSY); // wait for adc10 to be ready ADC12MCTL0 = ADC12SREF_1+ADC12INCH_13; // V+=AVcc V-=AVss, A0 channel ADC12CTL0 |= ADC12ENC + ADC12SC; // start sampling and conversion // LPM0; // sleep until conversions are transferred by dma for(i=0;i<256;i++) { RAWvalue13 += DMA_DST[i]; // Summing up 256 raw values } OVSresult13[AVGpnt13] = RAWvalue13 >> 4; // Shift right 4 bits, oversampling. RAWvalue13 = 0; if (AVGpnt13 == MOVWIN-1) OVSvalue13 -= OVSresult13[0]; // Moving average with MOVWIN window size else OVSvalue13 -= OVSresult13[AVGpnt13+1]; OVSvalue13 += OVSresult13[AVGpnt13]; Damp13value0 = OVSvalue13 / MOVWIN; // Divide by MOVWIN to get the average // Channel 14 ///////////////////////////////////////////////////////////////////////////// while (ADC12CTL1 & BUSY); // wait for adc10 to be ready ADC12MCTL0 = ADC12SREF_1+ADC12INCH_14; // V+=AVcc V-=AVss, A0 channel ADC12CTL0 |= ADC12ENC + ADC12SC; // start sampling and conversion // LPM0; // sleep until conversions are transferred by dma for(i=0;i<256;i++) { RAWvalue14 += DMA_DST[i]; // Summing up 256 raw values } OVSresult14[AVGpnt14] = RAWvalue14 >> 4; // Shift right 4 bits, oversampling. RAWvalue14 = 0; if (AVGpnt14 == MOVWIN-1) OVSvalue14 -= OVSresult14[0]; // Moving average with MOVWIN window size else OVSvalue14 -= OVSresult14[AVGpnt14+1]; OVSvalue14 += OVSresult14[AVGpnt14]; Damp14value0 = OVSvalue14 / MOVWIN; // Divide by MOVWIN to get the average // Channel 15 ///////////////////////////////////////////////////////////////////////////// while (ADC12CTL1 & BUSY); // wait for adc10 to be ready ADC12MCTL0 = ADC12SREF_1+ADC12INCH_15; // V+=AVcc V-=AVss, A0 channel ADC12CTL0 |= ADC12ENC + ADC12SC; // start sampling and conversion // LPM0; // sleep until conversions are transferred by dma for(i=0;i<256;i++) { RAWvalue15 += DMA_DST[i]; // Summing up 256 raw values } OVSresult15[AVGpnt15] = RAWvalue15 >> 4; // Shift right 4 bits, oversampling. RAWvalue15 = 0; if (AVGpnt15 == MOVWIN-1) OVSvalue15 -= OVSresult15[0]; // Moving average with MOVWIN window size else OVSvalue15 -= OVSresult15[AVGpnt15+1]; OVSvalue15 += OVSresult15[AVGpnt15]; Damp15value0 = OVSvalue15 / MOVWIN; // Divide by MOVWIN to get the average } } To reduce the noise, I'm doing an oversampling and after that moving average for each channels of the results. My moving average is around 64 data each time. So, I need to collect 64 oversampled data first to get a stable result. Because each channel need to collect 64 oversampled data and 1 oversampled data is equals to 256 conversion. So, total data is 256x64x15=245760 samples. From the spec, the ADC is 200000 sample per second. So, from theory, to collect all 15 channels I only need around 1 second. But I found out that my code really need over 10 seconds only can reach channel 15. Is there any problem with this code? Is there a way to speed up some more? Is there any way or settings so that I can get the ADC to sample 200000 sample per second? Can I omit this line "while (ADC12CTL1 & BUSY)" to make it faster? And by he way, yes... I'm the same ahgan84 from the TI forum. Usually I ask my questions to this two forum.
  6. I'm planning to ON all channels from channel 0 to 15 for my ADC12 for a user to use. Just that I thought of maybe a user won't know the sequence which one is channel 0 or which one is channel 15. Then if he put his device on channel 15, then he'll have to wait a long time only can get a result. I mean like, can't I get the ADC conversion from channel 0 to channel 15 all at the same time? Is there a configuration for this? Because of you add an extra step which is the DMA transfer in the code, I felt like the conversion time with using DMA is slower compare to without using DMA. Am I right, or I'm just imagining? If I am right, is there any way to reduce the conversion time?
  7. So it is mean that using the coding you showed, doesn't matter I use multiple channels like for example from channel 0 to 2 or channel 0 to 15, the conversion will always store in ADC10MEM0? I notice the coding will still use the ADC10CTL1 = ADC10CONSEQ_2 for repeat single channel instead of ADC10CTL1 = ADC10CONSEQ_3 for repeat sequence of channel? Why? I thought we are using multiple channels? So, the ADC conversion is in sequence from channel 0, 1, 2, 3, .... to finally channel 15. Then if my device input is at the last channel, which is channel 15, doesn't we have to wait a long time only get the conversion result? Cause it need to convert all other channels first before getting to channel 15. Then, it will be like my ADC response time is very slow. Is there any solutions to this?
  8. void adc_DMA_init(void) { DMACTL0 = DMA0TSEL__ADC10IFG; // select adc10 trigger __data16_write_addr( (unsigned short)&DMA0SA, (unsigned long)&ADC10MEM0 ); // dma single source address __data16_write_addr( (unsigned short)&DMA0DA, (unsigned long)&ADCdata[0] ); // destination array DMA0SZ = 64; // 64 conversions each channel, channels 12-14 selected in main routine after isr exit // repeat; increment dest address; enable dma; enable interrupt; high level DMA0CTL = DMADT_4 + DMADSTINCR_3 + DMAEN + DMAIE + DMALEVEL; } According to the code on your sample code (above), I have a few question: 1. Is it that this ADC conversion always get from ADC10MEM0? If I wan to use multiple channels, how does it get the value from it's memory for example ADC10MEM1 or ADC10MEM2? 2. Is it it store on ADCdata[0] array too if I use ADC10MEM1 or ADC10MEM2? Or I need to create another array like ADCdata1[0] or ADCdata[2]?
  9. I've found the below circuit which can measure resistance using ADC12. But what I don't understand is what is the 1M resistor in the middle for? We must put it or can we omit it?
  10. My voltage is a stable one. I measured already, I don't experience voltage drop. Yup. You are right. I've change the upper resistor to 30k Ohm and it give me a correct voltage value. But do you know why we should use a larger value for the upper resistor?
  11. I see. I've also saw the word software control from the internet. What exactly it is? Could you explain to me how do we use software control to trigger the DMA? Is the time we set for CCR registers (long or short) effecting the ADC accuracy? I've read the MSP430x5xxx family datasheet on ADC12 and DMA already. But I still have a lot don't understand. That's why I posted my questions here hoping somebody to explain to me.
  12. Anybody willing to help me with the above question?
  13. Do you guys know why i face the above problem?
  14. I know but with 2.08V, the resistance I should get after my calculation is 4.95k ohm. But when i measure the thermistor using my multimeter, I still get 10k resistance. Besides, 4.95k ohm of temperature is around 40 degree C. That's impossible... I'm in a 25 degree C room.
  15. I still don't understand, why is it there is two TBCCR (TBCCR0 and TBCCR1) values from my code but from your sample code, there is only one TA0CCR0 value? The timer counts to TBCCR0 = 0xFFFE or counts to TBCCR1 = 0x8000? That's why I ask why is it there is two TBCCR. And by the way, how do you determine the values of TBCCR? Is it that we must use a timer to trigger ADC12? Can't we use the default ADC12SC bit? What is the difference of using a timer and the ADC12SC bit? Which is better? I see. Thanks for the explanation. But what I want to know is the block address. Back to my below coding: __data16_write_addr((unsigned short) &DMA0SA,(unsigned long) &ADC12MEM0); // Source block address __data16_write_addr((unsigned short) &DMA0DA,(unsigned long) &DMA_DST); // Destination single address Why is it stated comment there the ADC12MEM0 is block address? I thought ADC12MEM0 is a single address? Or is it just a typing error? How do you determine for a variable which is block address or single address?
  16. I have set up a NTC thermistor to interface with my ADC12 for measurement. I'm using a voltage divider settings. But I have encounter some problem. I've uploaded a picture for my settings. Sorry I just want to be quick so instead of using schematic software, I just use hand drawing. The top one is a voltage divider using a resistance box. As you can see, the voltage values that I measure using multimeter for 1k resistor and the 10k resistance box is the same with when I use calculation using voltage divider formula. So, the values are correct. But as for the bottom settings which I use a Thermistor the values started to get weird. The resistance for the Thermistor is also 10k like the resistance box but the voltage I get is 2.08V instead of 2.28V. I get 0.42V for the 1k resistor instead of 0.22V. Why is it this happening? Is there a problem with my thermistor?
  17. 4. May I know how does the coding flows? Is it from main() straightaway stay in the ADC12ISR in a forever loop? Or it occasionally got return to main() for a short while then back to ADC12ISR again?
  18. But I thought I got the ADC12SHT0_15 to control my sample and hold time and by default, it is from MODCLK right? Then why still use TimerB? I still don't understand why there's two value for TBCCR (TBCCR0 = 0xFFFE;TBCCR1 = 0x8000). Could you explain please? I thought of using DMA, the transferring of data will be faster because it doesn't involve the CPU. So, I want to study how to use DMA but I got a lot don't understand. Is it that when we want to transfer data using DMA, we have to use the two __data16_write_addr function? One is for source address and one is for destination address? From the above coding's comment regarding this, the first one (ADC12MEM0) stated it is 'Source block address' and the second one (DMA_DST) stated it is 'Destination single address'. How to differentiate between block address and single address? I can't find a register that determine which is block address or single address from the datasheet. Actually what do you mean by block address? I know single address is just one address from the memory. Does block address means multiple address together? Why is it in this coding, ADC12MEM0 is block address? Thanks for the coding. Do you have any other coding that's using DMA transferring on ADC12? My coding here is just for one channel of the ADC12. I'm planning to use DMA to transfer all 14 channels of the ADC12. The ADC side I know how to configure to 14 channels. But the DMA side I don't know how to write. Can you please help me?
  19. Hi guys, The below coding is what I modified from the sample coding of MSP430F5325 on TI website. It put the ADC12 conversion in the ISR. #include #include #define MOVWIN 64 void initADC12(void); void initIO(void); unsigned long OVSresult0[MOVWIN]; unsigned long ActValue[100] = {0}; unsigned long ADCresult0 = 0; unsigned long OVSvalue0 = 0; unsigned long Dampvalue0 = 0; static unsigned long RAWvalue = 0; static unsigned int AVGpnt2 = 0; static unsigned int AVGpnt3 = 0; bool Flag = 0; void main(void) { WDTCTL = WDTPW+WDTHOLD; // Stop watchdog timer initIO(); initADC12(); __bis_SR_register(LPM4_bits + GIE); // Enter LPM4, Enable interrupts __no_operation(); // For debugger } void initIO(void) { unsigned char i; P1OUT &= ~BIT0; // P1.0 clear P1DIR |= BIT0; // P1.0 output P6SEL |= 0x01; P5SEL |= 0x01; // Enable A/D channel A0 for (i=0;i} void initADC12(void) { REFCTL0 &= ~REFMSTR; // Reset REFMSTR to hand over control to // ADC12_A ref control registers ADC12CTL0 = ADC12ON+ADC12SHT0_0+ADC12MSC+ADC12REF2_5V+ADC12REFON; // Turn on ADC12, set sampling time, on reference 2.5V // set multiple sample conversion ADC12CTL1 = ADC12SHP+ADC12CONSEQ_2; // Use sampling timer, set mode ADC12CTL2 = ADC12RES_2+ADC12REFOUT; ADC12MCTL0 = ADC12SREF_1+ADC12INCH_0; // ref+=+Vref, channel = A0 ADC12IE = 0x01; // Enable ADC12IFG.0 ADC12CTL0 |= ADC12ENC; // Enable conversions ADC12CTL0 |= ADC12SC; // Start conversion } #pragma vector=ADC12_VECTOR __interrupt void ADC12ISR (void) { static unsigned int AVGpnt = 0; switch(__even_in_range(ADC12IV,34)) { case 0: break; // Vector 0: No interrupt case 2: break; // Vector 2: ADC overflow case 4: break; // Vector 4: ADC timing overflow case 6: // Vector 6: ADC12IFG0 RAWvalue += ADC12MEM0; // Summing up 256 raw values AVGpnt++; if (AVGpnt == 256) { AVGpnt = 0; OVSresult0[AVGpnt2] = RAWvalue >> 4; // Shift right 4 bits, oversampling. RAWvalue = 0; if (AVGpnt2 == MOVWIN-1) OVSvalue0 -= OVSresult0[0]; // Moving average with MOVWIN window size else OVSvalue0 -= OVSresult0[AVGpnt2+1]; OVSvalue0 += OVSresult0[AVGpnt2]; Dampvalue0 = OVSvalue0 / MOVWIN; // Divide by MOVWIN to get the average ActValue[AVGpnt3] = Dampvalue0; AVGpnt3++; if (AVGpnt3 == 100) // Get 100 average value. { AVGpnt3 = 0; } AVGpnt2++; if (AVGpnt2 == MOVWIN) { AVGpnt2 = 0; } } case 10: break; // Vector 10: ADC12IFG2 case 12: break; // Vector 12: ADC12IFG3 case 14: break; // Vector 14: ADC12IFG4 case 16: break; // Vector 16: ADC12IFG5 case 18: break; // Vector 18: ADC12IFG6 case 20: break; // Vector 20: ADC12IFG7 case 22: break; // Vector 22: ADC12IFG8 case 24: break; // Vector 24: ADC12IFG9 case 26: break; // Vector 26: ADC12IFG10 case 28: break; // Vector 28: ADC12IFG11 case 30: break; // Vector 30: ADC12IFG12 case 32: break; // Vector 32: ADC12IFG13 case 34: break; // Vector 34: ADC12IFG14 default: break; } } I already test it on my MSP430F5325 cpu and I can get the result from ActValue. But what I want to know is: 1. Even though I can get the result, is the coding correct? Is it practical? I mean getting the ADC12 conversion from the ISR. 2. Can the ISR be this long? Cos I heard that you shouldn't stay too long in ISR. I am thinking of doing all 14 channels of ADC12, so I think that the ISR will become longer if I put all 14 channels. 3. Or should I put the oversampling calculation and moving average calculation in the main() routine?
  20. I see. So, can I say DMA0TSEL_24 is fixed for ADC12? Does that means other DMA0TSEL_xx is for other purposes / function? I got a few questions again regarding the above coding: 1. I thought it uses the DMA0IFG to trigger the ADC12 transfer? Why is it Timer_B is used and why is it there is two value for TBCCR (TBCCR0 = 0xFFFE;TBCCR1 = 0x8000)? Is it that we must always use a timer to trigger ADC12 transfer?2. How do we know what is the source address DMA0SA and destination address DMA0DA for this coding? Is it default address that start from 0? 3. Does __data16_write_addr function stand for write a specific data from a specific address? I don't get what this two lines means __data16_write_addr((unsigned short) &DMA0SA,(unsigned long) &ADC12MEM0); __data16_write_addr((unsigned short) &DMA0DA,(unsigned long) &DMA_DST); . Does it mean by writing like this, we can transfer the data from ADC12MEM0 to DMA_DST? Can't we just declare DMA_DST = ADC12MEM0? That will be more easier for me to understand... 4. What is the relationship of the channels for DMA and channels for ADC12? I mean, does DMA Channel 0 uses to transfer ADC12 Channel 0 only? What if I want to use DMA to transfer all 14 Channels from ADC12?
  21. Hi guys, These days I've been studying some sample coding from TI on DMA for my ADC12. For your information I'm using MSP430F5325 and I have the below coding: //****************************************************************************** // MSP430F532x Demo - DMA0, Single transfer using ADC12 triggered by TimerB // // Description: This software uses TBCCR1 as a sample and convert input into // the A0 of ADC12. ADC12IFG is used to trigger a DMA transfer and DMA // interrupt triggers when DMA transfer is done. TB1 is set as an output and // P1.0 is toggled when DMA ISR is serviced. // ACLK = REFO = 32kHz, MCLK = SMCLK = default DCO 1048576Hz // // MSP430F532x // ----------------- // /|\| XIN|- // | | | 32kHz // --|RST XOUT|- // | | // | P1.0|-->LED // | P5.7|-->TB1 output // | | // | P6.0|<--A0 // // Bhargavi Nisarga // Texas Instruments Inc. // April 2009 // Built with CCSv4 and IAR Embedded Workbench Version: 4.21 //****************************************************************************** #include unsigned int DMA_DST; // ADC conversion result is stored in this variable void main(void) { WDTCTL = WDTPW+WDTHOLD; // Hold WDT P1OUT &= ~BIT0; // P1.0 clear P1DIR |= BIT0; // P1.0 output P5SEL |= BIT7; // P5.7/TB1 option select P5DIR |= BIT7; // Output direction P6SEL |= BIT0; // Enable A/D channel A0 //Setup Timer B0 TBCCR0 = 0xFFFE; TBCCR1 = 0x8000; TBCCTL1 = OUTMOD_3; // CCR1 set/reset mode TBCTL = TBSSEL_2+MC_1+TBCLR; // SMCLK, Up-Mode // Setup ADC12 ADC12CTL0 = ADC12SHT0_15+ADC12MSC+ADC12ON;// Sampling time, MSC, ADC12 on ADC12CTL1 = ADC12SHS_3+ADC12CONSEQ_2; // Use sampling timer; ADC12MEM0 // Sample-and-hold source = CCI0B = // TBCCR1 output // Repeated-single-channel ADC12MCTL0 = ADC12SREF_0+ADC12INCH_0; // V+=AVcc V-=AVss, A0 channel ADC12CTL0 |= ADC12ENC; // Setup DMA0 DMACTL0 = DMA0TSEL_24; // ADC12IFGx triggered DMACTL4 = DMARMWDIS; // Read-modify-write disable DMA0CTL &= ~DMAIFG; DMA0CTL = DMADT_4+DMAEN+DMADSTINCR_3+DMAIE; // Rpt single tranfer, inc dst, Int DMA0SZ = 1; // DMA0 size = 1 __data16_write_addr((unsigned short) &DMA0SA,(unsigned long) &ADC12MEM0); // Source block address __data16_write_addr((unsigned short) &DMA0DA,(unsigned long) &DMA_DST); // Destination single address __bis_SR_register(LPM0_bits + GIE); // LPM0 w/ interrupts __no_operation(); // used for debugging } //------------------------------------------------------------------------------ // DMA Interrupt Service Routine //------------------------------------------------------------------------------ #pragma vector=DMA_VECTOR __interrupt void DMA_ISR(void) { switch(__even_in_range(DMAIV,16)) { case 0: break; case 2: // DMA0IFG = DMA Channel 0 P1OUT ^= BIT0; // Toggle P1.0 - PLACE BREAKPOINT HERE AND CHECK DMA_DST VARIABLE break; case 4: break; // DMA1IFG = DMA Channel 1 case 6: break; // DMA2IFG = DMA Channel 2 case 8: break; // DMA3IFG = DMA Channel 3 case 10: break; // DMA4IFG = DMA Channel 4 case 12: break; // DMA5IFG = DMA Channel 5 case 14: break; // DMA6IFG = DMA Channel 6 case 16: break; // DMA7IFG = DMA Channel 7 default: break; } } Lets's discuss this coding for this topic. I already have a few question here. 1. The description says it uses TBCCR1 as a sample, I don't understand. What is the timer_B for? 2. From the datasheet, there is DMACTL0 to DMACTL3. Why is it each DMACTLx has two DMA trigger select for example DMACTL0 has DMA1TSELx and DMA0TSELx? 3. How do we choose the DMA trigger select as this coding is using DMACTL0 = DMA0TSEL_24? Why 24?
  22. Hi guys, I'm using the MSP430F5325 and I'm just wondering how do you make the ADC reference voltage of 2.5V to be available at external pin? From the datasheet the pin is +Vref at A8. I've been studying the datasheet awhile and I've set the below configuration: REFCTL0 &= ~REFMSTR; ADC12CTL2 = ADC12REFOUT; Is this two setting enough to make the reference voltage available on external pin?
  23. Hi guys, I'm using the MSP430F5325 mcu and I am wondering whether I can simultaneously convert two channel from the ADC12? As far as I'm studying the data sheet, the ADC12 conversion is doing one channel at a time from A0 to A15. Because I'm trying to reduce the conversion time to half of it, so can it convert two channel in one time like for example convert A0 and A1 simultaneously at one time?
  24. Hi guys, Recently I begin to study on I2C communication for my MSP430F5325. I've found some I2C sample coding in the below link: http://www.ti.com/litv/zip/slac503 But all it got its one way only. Either its receive only or transmit only. I want to do transmit and receive. Is there any combine coding for transmit and receive?
×
×
  • Create New...