Hi. I'm trying to use the on board op amps as well as UART serial communication. Since the TIA and UART use the same pins (P1.6 and P1.7), the solution I came up with was to initialize the amps, send the data to the ADC, and then initialize the UART and send the data to the PC. This loops while the program runs and allows for P1.6 and P1.7 to be used for both UART and the TIA. However this doesn't work. The code only works if I disable the TIA and only use the SACOA, but for my application I need both amps. Is it possible to use both the TIA and UART? Is there any modification to my code that would fix the problem, or is there a different approach that can be used?
//******************************************************************************
// MSP430FR2311 - TRI0+SAC0, TRI0 as buffer, SAC0 as GP op-amp, use ADC to sample SAC0 output
//******************************************************************************
#include <msp430.h>
#include <stdio.h>
unsigned int adcResult;
unsigned int i;
void init_uart();
void init_amps();
void read_amps();
void uart_sendData();
int main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
PM5CTL0 &= ~LOCKLPM5; // Disable the GPIO default high-impedance mode, activate previously configured port settings
// Configure reference
PMMCTL0_H = PMMPW_H; // Unlock the PMM registers
PMMCTL2 |= INTREFEN; // Enable internal reference
__delay_cycles(400); // Delay for reference settling
// Configure ADC10
ADCCTL0 = ADCSHT_2 | ADCON; // ADCON, S&H=16 ADC clocks
ADCCTL1 = ADCSHP; // ADCCLK = MODOSC; sampling timer
ADCCTL2 = ADCRES; // 10-bit conversion results
ADCIE = ADCIE0; // Enable ADC conv complete interrupt
ADCMCTL0 = ADCINCH_3 | ADCSREF_0; // A3 ADC input select = OA output, Vref = DVCC
while(1) // Initialize each function every loop in order to use pins for more than 1 function
{
init_amps(); // Initialize pins for op-amp use
read_amps(); // Read op-amp values with ADC
init_uart(); // Initialize pins for UART use
uart_sendData(); // Send data to PC with UART
}
}
void init_uart()
{
P1SEL0 |= BIT6 | BIT7; // Configure UART pins set 2-UART pin as second function
// Configure UART
UCA0CTLW0 |= UCSWRST; //Sets software reset enable
UCA0CTLW0 |= UCSSEL__SMCLK; // Set SMCLK as BRCLK to be used for baud rate of 115200
// Baud Rate set to 115200
UCA0BR0 = 8; // 1000000/115200 = 8.68 INT(N) = 8
UCA0MCTLW = 0xD600; // 1000000/115200 - INT(1000000/115200)=0.68
UCA0BR1 = 0x00; // UCBRSx value = 0xD6
UCA0CTLW0 &= ~UCSWRST; // Initialize eUSCI
}
void init_amps()
{
P1SEL0 |= BIT2 + BIT3 + BIT4; // Select P1.2 P1.3 P1.4 as SAC function, P1.5 P1.6 P1.7 as TRI function
P1SEL1 |= BIT2 + BIT3 + BIT4;
// Configure TIA as buffer
TRI0CTL = TRIPM + TRIEN; // Enable TIA, Select low speed and low power mode
// Configure SACOA as GP op-amp
SAC0OA |= PSEL1; //TIA output = SACOA input
SAC0OA |= NMUXEN + PMUXEN; // Enable negative and positive input
SAC0OA |= OAPM; // Select low speed and low power mode
SAC0OA |= SACEN + OAEN; // Enable SAC and OA
}
void read_amps()
{
ADCCTL0 |= ADCENC | ADCSC; // Sampling and conversion start
__bis_SR_register(LPM0_bits | GIE); // Enter LPM0, ADC_ISR will force exit
__no_operation(); // For debug only
}
void uart_sendData()
{
while (!(UCA0IFG & UCTXIFG)); // Wait for USCI_A0 TX buffer to ready
char ADC_Char[16]; // Create a char array to store the ADC_Result as the serial only reads in ASCII
sprintf(ADC_Char, "%d", adcResult); // Convert ADC Result int value into a char array
for (i=0; i<strlen(ADC_Char); i++) { // Read the char array, one bit at a time
UCA0TXBUF = ADC_Char[i]; // If serial is not buffered, pause to send character
}
UCA0TXBUF = 0xA; // Newline character
__delay_cycles(5000); // For debug
}
// ADC interrupt service routine
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=ADC_VECTOR
__interrupt void ADC_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(ADC_VECTOR))) ADC_ISR (void)
#else
#error Compiler not supported!
#endif
{
switch(__even_in_range(ADCIV, ADCIV_ADCIFG))
{
case ADCIV_NONE:
break;
case ADCIV_ADCOVIFG:
break;
case ADCIV_ADCTOVIFG:
break;
case ADCIV_ADCHIIFG:
break;
case ADCIV_ADCLOIFG:
break;
case ADCIV_ADCINIFG:
break;
case ADCIV_ADCIFG:
adcResult = ADCMEM0; // Read ADC memory
__bic_SR_register_on_exit(LPM0_bits); // Exit from LPM
break;
default:
break;
}
}