Hello, I've been trying to implement an analogue dual axis joystick using the ADC module for the MSP430FR4133, I've begun by just attaching two potentiometers to test. I've followed the example code from the slac625h library "msp430fr413x_adc10_10.c" example. Only thing I've changed is changing from 8-bit conversion to 10-bit conversion and of int format, ADCSREF_0 to AVCC,AVSS.
Code:
#include <msp430.h>
unsigned int ADC_Result[3]; // 8-bit ADC conversion result array
unsigned int i;
int main(void)
{
WDTCTL = WDTPW | WDTHOLD; // Stop WDT
// Configure ADC A0~2 pins
SYSCFG2 |= ADCPCTL0 | ADCPCTL1 | ADCPCTL2;
// Disable the GPIO power-on default high-impedance mode to activate
// previously configured port settings
PM5CTL0 &= ~LOCKLPM5;
// Configure ADC
ADCCTL0 |= ADCSHT_2 | ADCON; // 16ADCclks, ADC ON
ADCCTL1 |= ADCSHP | ADCSSEL_1 | ADCSHS_2 | ADCCONSEQ_3; // ADC clock MODCLK, sampling timer, TA1.1B trig.,repeat sequence
ADCCTL2 |= ADCRES; // 10-bit conversion results
ADCMCTL0 |= ADCINCH_2 | ADCSREF_0; // A0~2(EoS); Vref=Vcc
ADCIE |= ADCIE0; // Enable ADC conv complete interrupt
// Configure reference
PMMCTL0_H = PMMPW_H; // Unlock the PMM registers
PMMCTL2 |= INTREFEN; // Enable internal reference
__delay_cycles(400); // Delay for reference settling
__no_operation();
// Configure TA1.1B as ADC trigger signal
// Note: The TA1.1B is configured for 200us 50% PWM, which will trigger ADC
// sample-and-conversion every 200us. The period of TA1.1B trigger event
// should be more than the time period taken for ADC sample-and-conversion
// and ADC interrupt service routine of each channel, which is about 57us in this code
TA1CCR0 = 200-1; // PWM Period, 200us
TA1CCTL1 = OUTMOD_7; // CCR1 reset/set
TA1CCR1 = 100; // CCR1 PWM duty cycle, 50%
TA1CTL = TASSEL__SMCLK | MC__UP | TACLR; // SMCLK, up mode, clear TAR
while(1)
{
i = 2;
ADCCTL0 |= ADCENC; // Enable ADC
TA1CTL |= TACLR; // Clear TAR to start the ADC sample-and-conversion
__bis_SR_register(LPM0_bits | GIE); // Enter LPM0 w/ interrupts
__no_operation(); // Only for debugger
}
}
// 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:
ADC_Result[i] = ADCMEM0;
if(i == 0)
{
__no_operation(); // Only for debugger
i = 2;
}
else
{
i--;
}
break;
default:
break;
}
}
I've been at this for the past couple of days but I can't quite seem to wrap my head around as to why the A0 reading seems to not be reading from the potentiometer correctly. But A1 reading seems to be perfect. A2 is just the P1.2 button (works fine; displays 0 when pressed).
Here is my wiring diagram:
(Apologies for the poor diagram)

I've also noticed another anomolie, if I trim the pot too far (10k) on A0, IAR gives me the following error and my program just hangs during debugging:

I've tried using alternative pots but same error.
Your much is very much appreciated!
Aaron


