Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Help me with code for establishing communication between ADE7753 and ATmega32

Status
Not open for further replies.

kbbhushan

Junior Member level 1
Joined
Mar 29, 2008
Messages
16
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,411
Hi,
I am doing a project using ade7753 and atmega32.
I am not able to establish communication between two.
Can someone please help me.

This is spi code.
int main(void)
{

// initialize our libraries
// initialize the UART (serial port)
uartInit();
// set the baud rate of the UART for our debug/reporting output
uartSetBaudRate(9600);
// initialize the timer system
timerInit();

// initialize rprintf system
// - use uartSendByte as the output for all rprintf statements
// this will cause all rprintf library functions to direct their
// output to the uart
// - rprintf can be made to output to any device which takes characters.
// You must write a function which takes an unsigned char as an argument
// and then pass this to rprintfInit like this: rprintfInit(YOUR_FUNCTION);
rprintfInit(uartSendByte);

// initialize vt100 library
vt100Init();

// clear the terminal screen
vt100ClearScreen();
sbi(DDRD,1);
cbi(DDRD,0);

char result;
spi_init();
ade7753_write_to_reg(0x13,0x02);
result = ade7753_read_from_reg(0x13);
rprintf("Result is %d\r\n",(uint8_t)result);


// spi_tx();
// spi_rx();


//}

}

void ade7753_write_to_reg( char addr, char value ){
rprintf("In ade7753_write_to_reg\r\n");
spi_start();
//write address to communication register first
addr = (addr+0x80);
rprintf("This address is being written %d\r\n",addr);
spi_tx(addr);//address of the reigster to write
_delay_us(0.05);
spi_tx(value);//value to be written to register
spi_end();
}

unsigned char ade7753_read_from_reg( char addr)
{
unsigned char regval;
rprintf("In ade7753_read_from_reg\r\n");
spi_start();
//write the address of reading register to communication register first
addr = (addr+0x80);
rprintf("This is the reading register address %d",addr);
_delay_us(4) ; //t9=4uswait till after address is loaded

regval= spi_rx();
return regval;
}

void spi_init(void)
{
/*set MOSI out ; SCK out ; SS out ;*/
DDR_SPI = DDR_SPI | (1 << MOSI) | (1 << SCK) | (1 << SS);
/*Set MISO in */
DDR_SPI = DDR_SPI & ~(1 << MISO);
/*Enable SPI; set Master mode; SPI Mode = 3; f' = f/128 */
SPCR = (1 << SPE) | (0 << DORD) | (1 << MSTR) | ( 0 << CPOL) | ( 1 << CPHA) | (0 << SPR1) | (1 << SPR0);

return;
}

void spi_tx(unsigned char data)
{
/* Start transmission */
SPDR = data;
rprintf("This is in spi_tx data is %d",data);
/* Wait for transmission complete */
while(!(SPSR & (1<<SPIF)));

return;
}

unsigned char spi_rx(void)
{
/*Send a dummy character */
SPDR = DUMMY;
/* Wait for reception complete */
while(!(SPSR & (1<<SPIF)));
/* Return data register */
rprintf("This is in spi_tx data is %d",SPDR);
return SPDR;
}

void spi_start(void)
{
/*End, if any, previous session */
spi_end();
/*Set SS low - start a new session */
PORT_SPI = PORT_SPI & ~(1 << SS);

return;
}

void spi_end(void)
{
/*Set SS high */
PORT_SPI = PORT_SPI | (1 << SS);

return;
}
 

ade7753

Sorry, I'm not familiar with the ATMEGA32 but I have had a look in the datasheet and the only thing that might
be wrong is here:

/*Enable SPI; set Master mode; SPI Mode = 3; f' = f/128 */
SPCR = (1 << SPE) | (0 << DORD) | (1 << MSTR) | ( 0 << CPOL) | ( 1 << CPHA) | (0 << SPR1) | (1 << SPR0);

For f/128 the datasheet states that both SPR1 and SPR0 are set to 1.

/Ram
 

ade7753 vrms calculation

Thanks for your reply.
Actually I am using sck as f/16. I forgot to change the comments there.
If every thing is fine, I don't know where am I going wrong.
Can you please tell me if not in the code where I am going wrong probably.
 

ade7753 register setting

Oops, I don't see that you write the address to ADE7753 here:

unsigned char ade7753_read_from_reg( char addr)
{
unsigned char regval;
rprintf("In ade7753_read_from_reg\r\n");
spi_start();
//write the address of reading register to communication register first
addr = (addr+0x80);
rprintf("This is the reading register address %d",addr);
_delay_us(4) ; //t9=4uswait till after address is loaded

regval= spi_rx();
return regval;
}

You just calculate it and after the delay you call spi_rx.

And also the read address should not have the highest bit set - that is, no +0x80.

/Ram
 

    kbbhushan

    Points: 2
    Helpful Answer Positive Rating
calibrating the ade7753

Thanks very much.
I thought every thing is fine. That simple statement mistake was not noticable.Now I will correct it and run the program when go to lab and let u know.

And you said that address should not have +0x80.
The reason to add 0x80 is that in command byte(read/write) which tells ade7753 whether I am performing read or write operation. In the write operation MSB of command bye should be 1. Then how to set 1 in the MSBit.

Thanks very much again.
 

ade7753 & vrms

You can see here that when reading from the ADE7753 you first send the command byte (the address) with the two highest bits 0.
After that you start sending dummy bytes to read the data bytes.

 

    kbbhushan

    Points: 2
    Helpful Answer Positive Rating
ade7753 code for spi atmega32

Hi,
Thanks. Its working now.
One more doubt is that some of the registers in ade7753 are signed and some are unsigned.
My functions are declared as unsigned.
Can you please tell me how to handle signed numbers.

Thanks.
 

ade7753 sclk hz

When you read the data from the ADE7753 you can use unsigned variables and then store them into properly declared variables.

8 and 16 bit values are simple as they map onto chars and integers directly - some examples:

For the signed 8-bit register TEMP (0x26) declare the variable -
char TEMP;
- and then just store the data byte from SPI -
TEMP = spi_rx();

For the unsigned 8-bit register GAIN (0x0F) declare the variable -
unsigned char GAIN;
- and then store the data byte from SPI -
GAIN = spi_rx();

For the signed 16-bit register APOS (0x11) declare the variable -
int APOS;
- and then store the integer from a union like the one we defined in the other thread -
APOS = value.Int;

For the unsigned 16-bit register LINECYC (0x1C) declare the variable -
unsigned int LINECYC;
- and then -
LINECYC = value.Int;

For the unsigned 24-bit register IRMS (0x16) declare the 32-bit variable -
unsigned long IRMS;
- and then -
IRMS = value.Long;


Now, storing the signed 24-bit in a long is a little trickier as you need to extend the sign bit, bit 23.
For the signed 24-bit register WAVEFORM (0x01) declare the 32-bit variable -
long WAVEFORM;
- and then check if the read value is negative (sign bit = 1) and set the upper 8 bits 24-31 -
if (value.Char[1] & 0x80) value.Char[0] = 0xFF;
WAVEFORM = value.Long;



Some signed values are 12 bit so we have to do a similar thing with them.
For the signed 12-bit register VAGAIN (0x1A) declare the 16-bit variable -
int VAGAIN;
- and then check if the read value is negative (sign bit 11 = 1) and set the upper 4 bits 12-15 -
if (value.Char[0] & 0x08) value.Char[0] = value.Char[0] | 0xF0;
VAGAIN = value.Int;


It looks a little messy but I hope you get the general idea.

/Ram
 

    kbbhushan

    Points: 2
    Helpful Answer Positive Rating
ade7753 atmega32 source

hi,
Thanks for all your help. Its working.

I don't have current transformer and voltage transformer. Do you have any idea how can I test whether whole circuit is working or not.

Thanks in advance.
 

ade7753 spi mode

Good job!

The ADE7753 datasheet says that the measurement inputs can take ±0.5 V so I guess you could
connect that voltage directly to the inputs. If you check figure 29 on page 14 you could apply the
"voltage" signal to pin 7 (V2P) and the "current" to pin 4 (V1P). You also need to ground pin 5 (V1N)
by connecting the 100 ohm resistor on that pin to ground. I think that should work.

Probably you don't need an AC signal so try it with a ≤0,5 V DC voltage.
I presume that the measured result will be product of the two voltages, like P=V*I, so you
can adjust one of them and see how "P" varies.

/Ram
 

    kbbhushan

    Points: 2
    Helpful Answer Positive Rating
mode register in ade7753

Thanks.

Don't we need to set any phase offset ,etc such kind of things.
 

ade7753 calculate amps

If you use a DC or an AC voltage, from a signal generator, the phase matching is perfect as the signal comes
from the same source.
Phase matching only comes in play in a real application, with transformers and stuff and then you need to calibrate
the measurement.

I guess you have seen this application note where phase matching and calibration is discussed:
**broken link removed**

/Ram
 

    kbbhushan

    Points: 2
    Helpful Answer Positive Rating
ade7753 volts/lsb

Hi,

I will go through the document.

Thanks again.
 

ade7753 irms register

Hi,

In table 6 of datasheet on page 16 it is said that LSB size is 1.61mV/LSB. What does this exactly mean? and somewhere it is also said that 2.2ms/LSB. what does this mean?

Thanks.
 

ade7753 pdf

The offset correction register has 6 bits - 1 for the sign and 5 for the magnitude.

It says in the text that a maximum of 0x1F = 31 voltage steps are used for correction and as the the
correction span is ±50 mV (for Gain = 1) you get 50/31 = 1.61 mV in each step.
Changing the register value by an LSB (Least Significant Bit) - by either increasing or decreasing it by 1 - will
in this case result in a voltage step of 1.61 mV/LSB.

As you can see from the table the voltage step varies according to the maximum span.

/Ram
 

    kbbhushan

    Points: 2
    Helpful Answer Positive Rating
ade7753 & waveform

Hi,

Thanks for explaining me.

AENERGY register is signed by two's complement method. How should I read the value from register? If I am reading using unsigned variable, how to convert it so that I can get the right value.
 

spi ade7753

The way to tell the compiler that you want to handle an unsigned value as signed is called type casting and is used like this:

Code:
long value;
unsigned long aenergy;

value = (long) aenergy;

/Ram
 

    kbbhushan

    Points: 2
    Helpful Answer Positive Rating
Re: help with ade7753

Hi,

Thanks.

I am trying to read IRMS and VRMS registers. I am getting large hex values. datasheet says that it should be converted into amps/LSB constant. But I don't have any idea how to do that. I have gone through the calibrating pdf. Please help me.
 

Re: help with ade7753

With the specified full-scale ac analog input signal of 0.5 V, the output from the LPF1 swings between 0x2518 and 0xDAE8 at 60 Hz—see the Channel 2 ADC section. The equivalent rms value of this full-scale ac signal is approximately 1,561,400 (0z17D338) in the VRMS register.

What they mean is that you have to multiply the value you read from VRMS with a coefficient that will give you a result of 0.5 V:

0.5 = cv*VRMS

That is cv = 0.5/VRMS and if the (approximate) full-scale value is 1561400 then cv = 3.2022544E-7.

Now, as you eventually will have a transformer and other components to scale down the mains voltage you will
need to calibrate the coefficient cv in your system.
You do that by applying a precise known AC voltage e.g. 230 Vrms and then read the VRMS value.
Calculate cv from 230 = cv*VRMS and insert it into your algorithm. You need to declare your voltage variable as float
not to drop the decimals.

Code:
#define cv 230/1500000       // Assuming VRMS read 1500000 when calibrating.

float voltsrms;

voltsrms = cv*VRMS;

The same goes for the current - measure a precise current, read the IRMS value and calculate a current coefficient.

/Ram
 

    kbbhushan

    Points: 2
    Helpful Answer Positive Rating
Re: help with ade7753

when I read the active power signal from waveform reg(i've set 13,14 bit of mode reg 0) it is giving the value ZERO even though I have applied i/p to both channels (from a dc source). Is there any other thing which I have to do other than configuring Mode reg? I got stuck in this part...Please help me out from this
--varun
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top