Pumpkin, Inc.

Pumpkin User Forums

ADC12 two external inputs and INCH_10

For issues specific to TI's MSP430 line of ultra-low-power microcontrollers, including compilers (e.g. Quadravox AQ430), IDEs (e.g. IAR Embedded Workbench) and development tools (e.g. TI MSP-FET430 Flash Emulation Tool).

ADC12 two external inputs and INCH_10

Postby piratemurray » Wed Aug 30, 2006 7:25 am

hello i've been messing around with all sorts of combinations and reading and re-reading the manual over and over again but cant get my head around my current problem.

it is the problem of reading two external inputs on INCH_0 (A0) and INCH_1 (A1) as well as reading the thermister (INCH_10) at the same time.

i can get the three inputs to read separately but not at the same time. what i mean by that is that i know my codes are working when there is just one task to read either A0, A1 or the thermister. but when i try and combine them in the same main.c file it goes crazy.

most of the time it will read one input correctly and the other two wrongly. most of the time it reads -275 C as the temperature which is quite offensive to a physics student.


here's my main.c file

code:

#include <msp430x16x.h>
#include <salvo.h>
#include <main.h>
#include <__cross_studio_io.h>

_OSLabel(temptest1) //Context switiching variables
_OSLabel(TimerA1)
_OSLabel(A0sense1)
_OSLabel(A1sense1)

unsigned int ADCresult, A1result, A0result; //Variables
unsigned long int DegC, A1volta, A0volta;
float delaytime, delaysysticks;

#define Task1_P OSTCBP(1) //Task Control Block Poiinters
#define Task2_P OSTCBP(2)
#define Task3_P OSTCBP(3)
#define Task4_P OSTCBP(4)

static void
writeTextFile(const char *filename)
{
DEBUG_FILE *stream;
stream = debug_fopen(filename, "wt");
if (stream)
{
int i;
for (i = 0; i < 10; ++i)
debug_fprintf(stream, "Hello World %d
", i);
debug_fclose(stream);
}
else
debug_printf("cannot open %s
", filename);
}

static void
readTextFile(const char *filename)
{
DEBUG_FILE *stream;
stream = debug_fopen(filename, "rt");
if (stream)
{
char buffer[32];
while (debug_fgets(buffer, sizeof(buffer), stream))
debug_printf("read: %s", buffer);
debug_fclose(stream);
}
else
debug_printf("cannot open %s
", filename);
}


void
TaskBlink(void)
{
InitPORT1(); //Makes the LED port an output port

for (;;) {
PORT1 ^= 0x01; //Turn port ON

OS_Delay(9, TaskBlink1);
}
}

void
A0sense(void)
{
/* ADC startup settings */
ADC12CTL0 = ADC12ON+SHT0_6; //switch ADC ON, turn reference to 2.5V and select 128 clock cycles in sampling period
//ADC12CTL1 = SHP; //SAMPCON signal is sourced from sample timer, conversion starts with A0

/* Select ADC to read A0 */
InitPORT6();
ADC12MCTL0 = INCH_0+SREF_3; //select analoughe input channel 0 to memory 0
ADC12CTL0 |= ENC; //enable conversions

for (;;)
{
/* Start conversions */
ADC12CTL0 |= ADC12SC; // start conversion
OS_Delay(delaysysticks, label); // wait for a time defind by 'delaytime'

/* Input sensing */
A0result = ADC12MEM0; //read result
A0volta = (A0result/4095);
debug_printf("%d, ", A0volta); //input values from A0

/* Context swith out */
//ADC12CTL0 |= ~ADC12SC; //stop conversion
OS_Yield(A0sense1);
}
}

void
A1sense(void)
{
/* ADC startup settings */
ADC12CTL0 = ADC12ON; //switch ADC ON, turn reference to 2.5V and select 128 clock cycles in sampling period
//ADC12CTL1 = SHP; //SAMPCON signal is sourced from sample timer, conversion starts with A1

/* Select ADC to read A1 */
InitPORT6();
ADC12MCTL1 = INCH_1+SREF_3; //select analouge input channel 1 to memory 1
ADC12CTL0 |= ENC; //enable conversions

for (;;)
{
/* Start conversions */
ADC12CTL0 |= ADC12SC; // start conversion
OS_Delay(delaysysticks, label); // wait for a time defind by 'delaytime'

/* Input sensing */
//debug_printf("i am waiting 10 ms
");
A1result = ADC12MEM1; //read result
A1volta = (A1result/4095);
debug_printf("%d
", A1volta); //input value from A1

/* Context swith out */
OS_Yield(A1sense1);
}
}

void
temptest(void)
{
/* ADC startup settings */
ADC12CTL0 = ADC12ON+REFON+SHT0_6; //switch ADC ON, turn reference to 2.5V and select 128 clock cycles in sampling period
ADC12CTL1 = SHP; //SAMPCON signal is sourced from sample timer, conversion starts with thermister

/* Select ADC to read thermistor etc */
ADC12MCTL2 = INCH_10+SREF_1; //select thermistor to memory 2
ADC12CTL0 |= ENC; //enable conversions
OS_Delay(200, label); //wait 2s for reference startup
debug_printf("i am waiting 2s
");

for (;;)
{
/* Start conversions */
ADC12CTL0 |= ADC12SC; // start conversion
OS_Delay(delaysysticks, label); // wait for a time defind by 'delaytime'
debug_printf("i am waiting %0.2f
", delaytime);

/* Temperature sensing */
ADCresult = ADC12MEM2; // read result
DegC = ((((long)ADCresult-1615)*704)/4095); // calc. DegC
debug_printf("the temp is: %d C
", DegC); //this is the temperature

/* Context swith out */
OS_Delay(200, temptest1);
}
}


void
main(void)
{ /* Set delay time for sampling here */
delaysysticks = 20; //number of system ticks to be delayed for
delaytime = delaysysticks/100; //delay time in seconds

/* Diagnostic lines */
debug_printf("world says hello
");
debug_printf("hello world
");

/* All other initialise states in main.h */
Init();

/* Initialise Savlo */
OSInit();

/* Create 2 tasks */
OSCreateTask(temptest, Task1_P, 7); //Measure temperature
OSCreateTask(TaskBlink, Task2_P, 1); //Blinks a LED
//OSCreateTask(A0sense, Task3_P, 7); //Senses first analouge input
// OSCreateTask(A1sense, Task4_P, 7); //Senses second analouge input


/* Enable interrupts */
OSEi();

/* Start Salvo*/
for (;;)
{
// debug_printf("new task
");
OSSched();
}
//
//const char *filename = "debugio_example.txt";
// writeTextFile(filename);
// readTextFile(filename);
// debug_exit(0);
//

// /* Output to a file */
// const char *filename = "debugio_example.txt";
// writeTextFile(filename);
// debug_exit(0);
}


thanks in advance.

if you need my main.h or salvocfg.h file to look at then i'd be happy to share.

piratemurray
 
Posts: 16
Joined: Mon Jul 03, 2006 11:00 pm
Location: london

Re: ADC12 two external inputs and INCH_10

Postby aek » Wed Aug 30, 2006 8:05 am

quote:
most of the time it reads -275 C as the temperature which is quite offensive to a physics student.
Haven't you discovered a source of cheap energy?

The problem is one of concurrency -- basically, you have three concurrent processes, all accessing (reading and writing) registers in the ADC, on three different inputs. You might be half way through A1 when the A2 task comes along and messes up all the setup for A1, etc. This is a no-no.

There are two ways to solve this.

1) The simplest way is probably to setup the ADC to simply scan all the inputs at a regular rate (the ADC has a mode to do this, though I've never used it) -- say in an TaskADCSample(), and then extract the three values you want from the ADC results on a periodic basis. I suspect this will be the smallest-code version, with a penalty in speed. Read the MSP430's ADC12 chapter.

2) Use the concept of a resource (you can see this in the CSK demo code in prod1) where a resource that represents the entire ADC is initialized to one, and any task wishing to work with the ADC must first acquire the ADC by waiting the event, and when done (just prior to the delay between successive samples) releases the ADC by signaling the event. Note that in this case, the entire code (including the setup) needs to be repeated each time, immediately after having acquired the resource. More info on this technique e.g. on pages 42-43 of http://www.pumpkininc.com/content/doc/press/Pumpkin_MSP430ATC2005.pdf.

------------------

[This message has been edited by aek (edited August 30, 2006).]

-------
aek
aek
 
Posts: 1888
Joined: Sat Aug 26, 2000 11:00 pm


Return to TI's MSP430

Who is online

Users browsing this forum: No registered users and 1 guest

cron