[Help] Đọc nhiều kênh ADC

lee_trieu

Gà con
Chào mọi người !
Em đanng tìm cách đọc nhiều kênh ADC cùng lúc nhưng chưa chạy, em viết code đọc 2 kênh A1(P1.1) và A2(P1.2) nhưng ADC không chạy, giá trị ADC10MEM = 0.:-s
mọi người xem giúp em với ạ::5cool_sweat:
PHP:
#include "msp430g2553.h"
#include "conf_lcd.c"
#define aMode 1
#define bMode 2
void conf_adc();
void conf_io();
int a,b,selectMode;
void main( void )
{
  // Stop watchdog timer to prevent time out reset
  WDTCTL = WDTPW + WDTHOLD;
  conf_adc();
  conf_io();
  conf_lcd(0);
  _BIS_SR( GIE);                 // Enable interrupt
  selectMode = aMode;
  
  while(1)
{
switch (selectMode)
{
case aMode :
P1OUT |= BIT0;
a = ADC10MEM;
selectMode = bMode;
break;
 
case bMode:
P1OUT |= BIT6;
b = ADC10MEM;
selectMode = aMode;
break;
}
lcd_gotoxy(0,0);
lcd_puts("A1 = ");
lcd_gotoxy(5,0);
lcd_number(a,0,0);
lcd_gotoxy(0,1);
lcd_puts("A2 = ");
lcd_gotoxy(5,1);
lcd_number(a,0,0);
 }
 
}
#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR(void)
{
//__bic_SR_register_on_exit(CPUOFF);        // Clear CPUOFF bit from 0(SR)
ADC10CTL0 &= ~ENC;                      // ADC10 disable
switch (selectMode) 
{
case aMode:
  ADC10CTL1 = INCH_1;
  break;
case bMode:
  ADC10CTL1 = INCH_2;
  break;
}
ADC10CTL0 |= ENC;                        //
}
void conf_adc()
{
ADC10CTL1 = INCH_1 + CONSEQ_1;
    ADC10CTL0 = ADC10SHT_2 + MSC + ADC10ON + ADC10IE;
    ADC10DTC1 = 2;//Doc 2 kenh ADC
    ADC10AE0 |= 0x06;// A1 va A2
}
void conf_io()
{
  P1DIR &=~(BIT1+BIT2);
  P1DIR |= BIT0+BIT6;
  P2DIR |= 0xff;
  P1SEL &= ~(BIT1+BIT2);
}
em cảm ơn ạ !!:)
 

nhokviet

Trứng gà
Cùng đang tìm hiểu về vấn đề này, haiz post lên pif mà chẳng thấy ai reply, chán.
Mình tìm thấy code chạy ở P1.0 và P1.3 đã test và ok. tuy ko hiểu hoàn toàn.
Có cái này ko hiểu ai giải thích dùm (Mình không phải dân điện tử nên đọc chuyên sâu quá ko hiểu đc)
ADC10DTC1 = 4; //Cái này là cái gì
INCH_3 //Ý nghĩa cái này là gì nữa

Code ở dưới là chạy rồi.

Code:
/******************************************************************************
MSP430G2553 Project Creator
 
GE 423  - Dan Block
        Spring(2012)
 
        Written(by) : Steve(Keres)
College of Engineering Control Systems Lab
University of Illinois at Urbana-Champaign
*******************************************************************************/
 
#include "msp430g2553.h"
#include "UART.h"
 
char newprint = 0;
unsigned long timecnt = 0;
 
unsigned int ADC[4];  // Array to hold ADC values
int A0value = 0;
int A3value = 0;
char newADC = 0;
 
void main(void) {
 
    WDTCTL = WDTPW + WDTHOLD;                // Stop WDT
 
    if (CALBC1_16MHZ ==0xFF || CALDCO_16MHZ == 0xFF) while(1);
 
    DCOCTL = CALDCO_16MHZ;    // Set uC to run at approximately 16 Mhz
    BCSCTL1 = CALBC1_16MHZ;
 
    // Initialize Port 1
    P1SEL &= ~0x09;  // See page 42 and 43 of the G2553's datasheet, It shows that when both P1SEL and P1SEL2 bits are zero
    P1SEL2 &= ~0x09; // the corresponding pin is set as a I/O pin.  Datasheet: http://coecsl.ece.illinois.edu/ge423/datasheets/MSP430Ref_Guides/msp430g2553datasheet.pdf
    P1REN = 0x0;  // No resistors enabled for Port 1
    P1DIR &= ~0x9; // Set P1.0 P1.3 to intput to drive LED on LaunchPad board.  Make sure shunt jumper is in place at LaunchPad's Red LED
 
    P1SEL &= ~0x10;
    P1SEL2 &= ~0x10;
    P1REN = 0x0;  // No resistors enabled for Port 1
    P1DIR |= 0x10; // Set P1.4 output
    P1OUT |= 0x10;
 
 
    // Timer A Config
    TACCTL0 = CCIE;              // Enable Periodic interrupt
    TACCR0 = 16000;                // period = 1ms 
    TACTL = TASSEL_2 + MC_1; // source SMCLK, up mode
 
    ADC10CTL1 = INCH_3 + ADC10SSEL_3 + CONSEQ_1; //INCH_3: Enable A3 first, Use SMCLK, Sequence of Channels
    ADC10CTL0 = ADC10ON + MSC + ADC10IE;  // Turn on ADC,  Put in Multiple Sample and Conversion mode,  Enable Interrupt
 
    ADC10AE0 |= 0x09;                  // Enable A0 and A3 which are P1.0,P1.3
 
    ADC10DTC1 = 4;                  // Four conversions.
    ADC10SA = (short)&ADC[0];          // ADC10 data transfer starting address.
 
 
    Init_UART(9600,1);    // Initialize UART for 9600 baud serial communication
 
    _BIS_SR(GIE);        // Enable global interrupt
 
 
    while(1) {
 
        if(newmsg) {
            newmsg = 0;
        }
 
        if (newprint)  {
 
            P1OUT ^= 0x10;        // Blink LED
 
            newprint = 0;
        }
        if (newADC == 1) {
 
            UART_printf("0:%d 3:%d\n\r",A0value,A3value);  // Print to UART
 
            newADC = 0;
 
        }
    }
}
 
 
// Timer A0 interrupt service routine
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_A (void)
{
    timecnt++; // Keep track of time for main while loop.
 
    if ((timecnt%500) == 0) {
        ADC10CTL0 |= ENC + ADC10SC;            // Enable Sampling and start conversion.
    }
 
    if ((timecnt%500) == 0) {
    newprint = 1;  // flag main while loop that .5 seconds have gone by. 
    }
 
}
 
 
 
//ADC10 interrupt Service Routine
#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR (void) {
 
    A0value = ADC[3];  // Notice the reverse in index
    A3value = ADC[0];  // ADC[0] has A3 value and ADC[3] has A0's value
 
    ADC10CTL0 &= ~ADC10IFG;  // clear interrupt flag
 
    ADC10SA = (short)&ADC[0]; // ADC10 data transfer starting address.
 
    newADC = 1;
 
}
 
 
// USCI Transmit ISR - Called when TXBUF is empty (ready to accept another character)
#pragma vector=USCIAB0TX_VECTOR
__interrupt void USCI0TX_ISR(void) {
 
    if(IFG2&UCA0TXIFG) {        // USCI_A0 requested TX interrupt
        if(printf_flag) {
            if (currentindex == txcount) {
                senddone = 1;
                printf_flag = 0;
                IFG2 &= ~UCA0TXIFG;
            } else {
                UCA0TXBUF = printbuff[currentindex];
                currentindex++;
            }
        } else if(UART_flag) {
            if(!donesending) {
                UCA0TXBUF = txbuff[txindex];
                if(txbuff[txindex] == 255) {
                    donesending = 1;
                    txindex = 0;
                }
                else txindex++;
            }
        } else {  // interrupt after sendchar call so just set senddone flag since only one char is sent
            senddone = 1;
        }
 
        IFG2 &= ~UCA0TXIFG;
    }
 
    if(IFG2&UCB0TXIFG) {    // USCI_B0 requested TX interrupt (UCB0TXBUF is empty)
 
        IFG2 &= ~UCB0TXIFG;  // clear IFG
    }
}
 
 
// USCI Receive ISR - Called when shift register has been transferred to RXBUF
// Indicates completion of TX/RX operation
#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR(void) {
 
    if(IFG2&UCB0RXIFG) {  // USCI_B0 requested RX interrupt (UCB0RXBUF is full)
 
        IFG2 &= ~UCB0RXIFG;  // clear IFG
    }
 
    if(IFG2&UCA0RXIFG) {  // USCI_A0 requested RX interrupt (UCA0RXBUF is full)
 
//    Uncomment this block of code if you would like to use this COM protocol that uses 253 as STARTCHAR and 255 as STOPCHAR
/*        if(!started) {    // Haven't started a message yet
            if(UCA0RXBUF == 253) {
                started = 1;
                newmsg = 0;
            }
        }
        else {    // In process of receiving a message       
            if((UCA0RXBUF != 255) && (msgindex < (MAX_NUM_FLOATS*5))) {
                rxbuff[msgindex] = UCA0RXBUF;
 
                msgindex++;
            } else {    // Stop char received or too much data received
                if(UCA0RXBUF == 255) {    // Message completed
                    newmsg = 1;
                    rxbuff[msgindex] = 255;    // "Null"-terminate the array
                }
                started = 0;
                msgindex = 0;
            }
        }
*/
 
        IFG2 &= ~UCA0RXIFG;
    }
 
}
 

lee_trieu

Gà con
Cùng đang tìm hiểu về vấn đề này, haiz post lên pif mà chẳng thấy ai reply, chán.
Mình tìm thấy code chạy ở P1.0 và P1.3 đã test và ok. tuy ko hiểu hoàn toàn.
Có cái này ko hiểu ai giải thích dùm (Mình không phải dân điện tử nên đọc chuyên sâu quá ko hiểu đc)
ADC10DTC1 = 4; //Cái này là cái gì
INCH_3 //Ý nghĩa cái này là gì nữa
Mấy lệnh này xem user guide sẻ thấy bạn nhé:-(

ADC10DTC1 = 4; //Số kênh ADC cần chuyển đổi(trường hợp này là 4).
INCH_3 //Chọn kênh ADC(Nếu chuyển đổi nhiều kênh thì chọn kênh cao nhất)
Cảm ơn và chúc bạn thành công !:)
 

nhokviet

Trứng gà
ADC10DTC1 = 4;
vậy sao nó lại là = 4 mà ko fải = 2, vì đây chỉ có xài 2kênh
 

lee_trieu

Gà con
ADC10DTC1 = 4;
vậy sao nó lại là = 4 mà ko fải = 2, vì đây chỉ có xài 2kênh
Cái này mình cũng không biết ý đồ code của tác giả là gì nữa:)Nhưng chức năng của ADC10DTC1 theo datasheet là vậy mà !:5cool_sweat:
 
Top