UART - Developing Circuit Test Device - Interfaced w/VisualB

Hello all!

Here’s the rundown:

I’m using an MSP430F169 on an Olimex MSP430P169 Dev. Board to monitor a circuit board that we developed.

One part of this task is to monitor two resistors. Basically, I want to see if they ‘power on’ in a specified amount of time. I also need to know which order they ‘turn on’ in.

I’ve used Visual Basic to establish a program to test the circuit boards so any of our line technicians can perform the tests.

Here is my problem:

Visual Basic is setup to communicate with the UART of the MSP430. It sends a character to set off a receive interrupt. The interrupt should then transmit back the state of the resistors. Here are the five states I need:

‘A’ - Nothing Is On

‘B’ - Only R1 Is On

‘C’ - Only R2 Is On

‘D’ - R1 Came On Then R2

‘E’ - R2 Came On Then R1

I’m using the ADC to monitor two pins which will, in the end, be monitoring the resistors. Right now, they are tied to 3.3V and 0.0V.

Using IAR 4.10 to create my project and TeraTerm to monitor UART/PC communication, I’ve found no problems when using this ‘test’ code:

#pragma vector=USART0RX_VECTOR

__interrupt void usart0_rx (void)

{

while (!(IFG1 & UTXIFG0)); //USART0 TX Buffer Ready?

//Test - For Program Verification Only!

if (ADC12MEM2 > 0x00F)

TXBUF0 = ‘H’;

else

TXBUF0 = ‘L’;

}

It sends an ‘H’ or ‘L’, which says P6.2 is high or low (2.5V or 0.0V).

The ultimate goal is to have an if statement to determine which one of the above states (A - E) has occurred, but nothing is working for me.

I could make a global character variable, ‘static char state’, inside the ADC Initialize routine and setup an if statement to set that variable ‘state’ inside the ADC interrupt. Then I could make TXBUF0 = state inside the UART interrupt, and my problem would be solved, right? Wrong. TXBUF0 won’t take that variable.

Am I doing something wrong? Wrong variable? Wrong declaration?

Even worse, I can’t think of a scheme to implement if statements to find which state the board is in!

Any ideas? Code would be nice, but all ideas are appreciated. I have no problem writing out the code for someone’s idea.

I know there are a lot of bright minds running around in here, so, I thank you all in advance.

-Mark

What exactly do you mean by “TXBUF0 won’t take that variable”? Do you get a compile error (and if so, WHAT error), or does the wrong value get sent at runtime, or does nothing happen at all?

Also, what do you mean by “I could make a global character variable, ‘static char state’, inside the ADC Initialize routine”? If you declare a variable within a routine, then it is NOT a global variable, and it cannot be accessed from any other routine.

In my ADC_Init.c rountine, I declare my variable like this:

static unsigned char state;


Here is my ADC ISR:

#pragma vector=ADC12_VECTOR

__interrupt void ADC12ISR (void)

{

if( ADC12MEM2 > 0x0F )

state = ‘a’;

else

state = ‘b’;

//Calculate Voltage

//Value = (2500*Value)/4095;

Voltage = (int)(((long)ADC12MEM2*250)/4095);

}

The voltage is in there to ‘Watch’ and make sure the interrupt is handling (And it Is!).


Here is a test UART ISR using the ‘state’ variable:

#pragma vector=USART0RX_VECTOR

__interrupt void usart0_rx (void)

{

while (!(IFG1 & UTXIFG0)); // USART0 TX buffer ready?

TXBUF0 = state;

}


Now, I think the ‘state’ variable should be set in the ADC ISR, then it will get thrown back to the PC by the UART, but that isn’t happening. In the watch window by ‘state’ IAR says, “Error (col 1): Unknown or ambiguous symbol.state” However, ‘ADC12MEM2’ and ‘Voltage’ are working fine.

I’ve stepped through the program, and it steps into my if statements in the ADC ISR. If I ‘RUN’ in IAR Debug with a breakpoint at TXBUF0 = state, and then I send a character from Teraterm, the program will land on the ‘TXBUF0 = state’, but nothing gets sent back to Teraterm…

I know my Comms are working because I’ve tested them by just setting TXBUF0 = ‘x’ or any character for that matter. For some reason, the variable ‘state’ isn’t setting it.

You said "In my ADC_Init.c routine, I declare my variable like this:

static unsigned char state;"

Thus "in"side that routine, “state” is declared. But outside of it, “state” is not declared and cannot be accessed. (This is referred as “scope”.)

You need to declare “state” in a way that all parties know what it is. “static” only means it will keep its value when you exits and enters that routine. But others still may not be allowed to access it.

I apologize for not being very clear. I do have variable ‘state’ defined with file scope. It is in the file ADC_Init.c before the main section - ‘void ADC_Init(void)’ :

#include <msp430x16x.h>

static signed int Voltage;

static char state;

void ADC_Init(void)

{…}

It is also defined in the file UART_Init.c :

#include <msp430x16x.h>

static char state;

void UART_Init(void)

{…}

If I declare it with file scope in the ADC_Init, but do not declare it in UART_Init, then I get a compile error:

Error[Pe020]: identifier “state” is undefined (in UART_Init)

So, that is why I have it in UART_Init.c, but I thought the whole reason for declaring it with file scope in ADC_Init was so I don’t need to do it in UART_Init.c

A ‘static’ variable in file scope is local to that file. You’ve actually got two entirely separate variables named ‘state’, one from each file. What you want is just “char state;” in one file to create a variable with global scope, and “extern char state;” in the other file to reference the same variable.

That’s great! It works now! Now, if I can create the if statements to decide what state I’m in…

Would a switch statement be better than ifs for my application?

Also, any ideas as to how I can figure out which resistor turns on first?

Thanks for your help!

Well, I’ve created if statements for the following conditions:

R1 and R2 are both off

R1 is on

R2 is on

R1 and R2 are both on

However, I still don’t know how to create a statement that can tell me which one came on first…