This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Hello,
I'm using the MPS430 with eZ430-RF2500. For the moment, I'm only using the USB connection and the MSP430 (not the wireless link with the RF2500). I use the MSP430 in order to communicate with both an ADC and DAC. I communicate with an SPI 3 wires interface. My code seems to wrok all right and I get the SCLK, SIMO and SOMI but when I want to use an stdio function such as printf, the output signals disapear...I don't have them anymore. The problem is, I would like to store the digitized values from my ADC in a file on my PC but it doesn't work since it also uses stdio functiuns...
Is someone able to help me?
Thank you!
Julie
Here is my code:
//******************************************************************************
// MSP430F2274, USCI_B0, SPI Interface to AD7856 16-Bit ADC and AD5392 14-BIT DAC
//
// ACLK = n/a, MCLK = SMCLK = DCO ~12MHz, BRCLK = SMCLK/2
// //* VCC must be at least 3v for AD7856 *//
//
// MSP430F2274
// -----------------
// /|\| |
// AD7856 | | | AD5392
// ------------- | | -------------
// | | | | | |
// | DATAIN|<---|P3.1/UCB0SIMO |--->|DATAIN |
// | DATAOUT|--->|P3.2/UCB0SOMI |<---|DATAOUT |
// ~>|AIN+ I/O CLK|<---|P3.3/UCB0CLK |--->|I/O CLK |
// | SYNC|<---|P4.5/CS1 | | |
// | | |P4.6/CS2 |--->|SYNC |
//
// J. Dethier
// Imec
// April 2010
// Built with IAR Embedded Workbench Version: 4.21
//******************************************************************************
#include "msp430x22x4.h"
#include <stdio.h>
FILE *f;
const unsigned char channel_selectionADC[] = // 8 channels
{
0xE1, // channel 1
0xE5, // channel 2
0xE9, // channel 3
0xED, // channel 4
0xF1, // channel 5
0xF5, // channel 6
0xF9, // channel 7
0xFD // channel 8
};
const unsigned char channel_selectionDAC[] = // 8 channels
{
0x00, // channel 1
0x01, // channel 2
0x02, // channel 3
0x03, // channel 4
0x04, // channel 5
0x05, // channel 6
0x06, // channel 7
0x07 // channel 8
};
//To store values of the amplified signal
unsigned int channel_value[] = // 8 channels
{
0x0000, // channel 1
0x0000, // channel 2
0x0000, // channel 3
0x0000, // channel 4
0x0000, // channel 5
0x0000, // channel 6
0x0000, // channel 7
0x0000 // channel 8
};
//To store values of the gain
unsigned int gain_value[] = // 8 channels
{
0x0000, // channel 1
0x0000, // channel 2
0x0000, // channel 3
0x0000, // channel 4
0x0000, // channel 5
0x0000, // channel 6
0x0000, // channel 7
0x0000 // channel 8
};
const unsigned char gainmax[] =
{0x25,
0x1E
};
const unsigned char gainmin[] =
{0x01,
0x48
};
// convert an interger into two char
char MSB(int n)
{
unsigned char valueMSB;
n = n >> 8; // shift bits in LSB
valueMSB = (char)n; // casting
return valueMSB;
}
char LSB(int n)
{
unsigned char valueLSB;
valueLSB = (char)n; // casting
return valueLSB;
}
// convert two char into an interger
int integer(char m, char l)
{
unsigned int in;
in = (int)m <<8; // shift bits in MSB
in |= (int)l;
return in;
}
// Print value on the screen
void read_value(int n)
{
int value;
value=n; //read CPU i
printf("%X \n", value); //Display i in hex on PC terminal
}
void main(void)
{
unsigned int data1, data2, data3,i, j;
unsigned char l[] =
{
0x02,
0x02,
0x02,
0x02,
0x02,
0x02,
0x02,
0x02
};
volatile unsigned char Din[] = // 16 bits CONTROL REGISTER
{
0xE1, // ADDR1 = ADDR1 = 1 for CONTROL REGISTER
// SGL/DIFF = 1 for input channels in single-ended mode
// CH2, CH1, CH0
// PMGT1 = 0, PMGT0 = 1 for Normal Operation
0x10 // RDSLT1 = RDSLT0 = 0 for ADC OUTPUT DATA REGISTER
// 2/3 MODE = 0 for Interface Mode 2
// CONVST = 1 to start a single conversion
// CALMD = CALSLT1 = CALSLT0 = 0 for Full Internal Calibration
// STCAL = 0
};
volatile unsigned char SDA[] = // 24 bits Serial Input Register
{
0x00, // A/B = 0 for A register
// R/W = 0 for write
// 000
// A2 to A0 address the input channel
0xC0, // REG1 = REG1 = 1 for Input data register
0x00 // DB13 to DB0 : input data-word
};
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
//Basic Clock Module
BCSCTL1 = CALBC1_12MHZ; // Set DCO to 12MHz
DCOCTL = CALDCO_12MHZ;
// Digital Input/output
P1DIR |= 0x03; // P1.0,1 output
// RED and Yelow
P2DIR |= 0x02; // P2.1 output direction
P2SEL |= 0x02; // P2.1 = SMCLK
P3DIR |= 0x0A; // P3.1,3 output direction
P3DIR &= ~0x04; // P3.2 input direction
P3SEL |= 0x0E; // P3.1,2,3 USCI_B0 option select
// SIMO, SOMI, CLK
P4DIR |= 0x60; // P4.5,6 output direction
// SS1, SS2
//USCI
UCB0CTL0 |= UCMSB + UCMST + UCSYNC; // 3-pin, 8-bit SPI mstr, MSB 1st
UCB0CTL1 |= UCSWRST; // Enable SW reset
UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset
UCB0BR0 = 0x02; // Prescaler value
UCB0BR1 = 0;
UCB0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
// Initialisation with maximum gain
for(j = 0; j<8; j++)
//DAC
{
SDA[0] = channel_selectionDAC[j]; // Update of the channel
SDA[1] = gainmax[0] + 0xC0;
SDA[2] = gainmax[1];
gain_value[j] = integer(gainmax[0], gainmax[1]);
P4OUT &= ~0x40; // Enable AD5392, /CS reset
UCB0TXBUF = SDA[0]; // Write TX buffer
UCB0TXBUF = SDA[1];
while (!(IFG2 & UCB0RXIFG)); // USCI_B0 RX buffer ready?
data1 = UCB0RXBUF; // R15 = 00|MSB
data1 = data1 << 8;
UCB0TXBUF = SDA[2];
while (!(IFG2 & UCB0RXIFG)) // USCI_B0 RX buffer ready?
data2 = UCB0RXBUF;
data2 = data2 << 8;
while (!(IFG2 & UCB0RXIFG)) // USCI_B0 RX buffer ready?
data3 = UCB0RXBUF;
data2 = data2 + data3; // R14 = 00|LSB
P4OUT |= 0x40; // Disable AD5392, /CS set
P1OUT &= ~0x01; // P1.0 = 0
if (data1 > 0x7FE0) // Test for correct character RX'd
P1OUT |= 0x01; // P1.0 = 1
}
while(1)
{
unsigned char gainm, gainl;
for(j = 0; j<8; j++)
{
//ADC
for( i = 0; i<8; i++)
{
Din[0]= channel_selectionADC[i]; // Update of the channel
P4OUT &= ~0x20; // Enable AD7856, /CS reset
UCB0TXBUF = Din[0]; // Write TX buffer
UCB0TXBUF = Din[1];
while (!(IFG2 & UCB0RXIFG)); // USCI_B0 RX buffer ready?
data1 = UCB0RXBUF; // R15 = 00|MSB
data1 = data1 << 8;
while (!(IFG2 & UCB0RXIFG)); // USCI_B0 RX buffer ready?
data2 = UCB0RXBUF;
channel_value[i] = data1 + data2; // R14 = 00|LSB
channel_value[i] &= 0x3FFF; // Eliminate the first 2 bits
// Write in file
f = fopen ("valueandgain.txt", "w"); //Open file
fputc (i , f); // Write channel
fputc (channel_value[i] , f); // Write value
fputc (gain_value[i] , f); // Write gain
fclose (f);
P4OUT |= 0x20; // Disable AD7856, /CS set
P1OUT &= ~0x01; // P1.0 = 0
if (data1 > 0x7FE0) // Test for correct character RX'd
P1OUT |= 0x01; // P1.0 = 1
}
//DAC
SDA[0] = channel_selectionDAC[j]; // Update of the channel
// Check to diminish the gain
if (channel_value[j] == 0x3FFF || channel_value[j] == 0x0000)
{
gain_value[j] = gain_value[j]>>1; // Divide gain by 2
}
// To have a more accurate gain
// Maximum of 0.5V and 4.5V
if ((channel_value[j] <= 0x399A && channel_value[j] >= 0x0667) && (l[j] <= 0xFE))
{
// Add gain divided by l
gain_value[j] = gain_value[j] + gain_value[j]/l[j];
l[j]++;
}
// Check for gain in the available range
if (gain_value[j] <= integer(gainmin[0], gainmin[1]))
{
gain_value[j] = integer(gainmin[0], gainmin[1]);
}
if (gain_value[j] >= integer(gainmax[0], gainmax[1]))
{
gain_value[j] = integer(gainmax[0], gainmax[1]);
}
gainm = MSB(gain_value[j]); // Update gain
gainl = LSB(gain_value[j]);
gain_value[j] = integer(gainm, gainl);
SDA[1] = gainm + 0xC0;
SDA[2] = gainl;
P4OUT &= ~0x40; // Enable AD5392, /CS reset
UCB0TXBUF = SDA[0]; // Write TX buffer
UCB0TXBUF = SDA[1];
while (!(IFG2 & UCB0RXIFG)); // USCI_B0 RX buffer ready?
data1 = UCB0RXBUF; // R15 = 00|MSB
data1 = data1 << 8;
UCB0TXBUF = SDA[2];
while (!(IFG2 & UCB0RXIFG)) // USCI_B0 RX buffer ready?
data2 = UCB0RXBUF;
data2 = data2 << 8;
while (!(IFG2 & UCB0RXIFG)) // USCI_B0 RX buffer ready?
data3 = UCB0RXBUF;
data2 = data2 + data3; // R14 = 00|LSB
P4OUT |= 0x40; // Disable AD5392, /CS set
P1OUT &= ~0x01; // P1.0 = 0
if (data1 > 0x7FE0) // Test for correct character RX'd
P1OUT |= 0x01; // P1.0 = 1
}
}
}
Hello again, I don't know if I made myself clear enough.
Should I use the UART to read from the MSP430 or is it enough to use the UART from the debugging interface?
Thank you!
Hi,
you will have to use the so-called 'Backchannel UART' from the tool which is connected to the MSP430 UART.
Have look ath the TI MSP430 wiki side here: http://wiki.msp430.com/index.php/EZ430_Backchannel_UART_Configuration
At the end of the page is a link to the 'MSP430 chat' (http://wiki.msp430.com/index.php/EZ430_Chat) a cool SW for demonstrating the eZ430-RF2500 capabilitys when using the Backchannel UART.
Rgds
aBUGSworstnightmare
Thank you very much. It's actually what I ended up to do. But I don't understand, when I have send a char through the UCA0TX buffer how I can store it on my computer in a file or even how I can display it on the screen....
What kind of function should I use? I find this answer nowhere.
Thank you!
Julie
Hi Julie,
have a look at this 'how to' from the wiki http://wiki.msp430.com/images/3/31/Printf_in_CCE.pdf .
Regarding 'storing into a file on your PC' ... well, there's no direct way for doing this. Some people posted this question to the forum already, and - as far as I remember - the most common recommendation was: send the data to a terminal program (i.e. Hyperterminal) and - when your finished - save them to a file. You can now import them into Excel for example for processing.
Rgds
aBUGSworstnightmare
HyperTerm also has a 'log to file' function that can even append across sessions.
I suggest downloading the latest version of HyperTerm (from 2002) as it has some bugs removed (mostly with the scrollback buffer). The version that ships with Windows is from the stone age and more buggy than useful.
**Attention** This is a public forum