|
|
View previous topic :: View next topic |
Author |
Message |
Sutton
Joined: 15 Feb 2007 Posts: 2
|
Please Help, Unable to collect valid data from power source |
Posted: Thu Feb 15, 2007 1:25 pm |
|
|
Hi all,
I am currently creating a energy meter using a PIC16F876 and Analog Devices ADE7753 while using the CCS Compiler.
I've been trying to master capturing values from the ADE7753 and sending it through the PIC to PC via RS232. Currently the code I have produced is able to transmit data collected from the ADE7753, but the problem I have is that the data is clearly not valid as its always 0.
Ive tried a few changes to possible areas which may cause this error but I have came to the conclusion that calibration of the ADE7753 maybe the area to look at. Looking at the datasheet:
http://www.analog.com/UploadedFiles/Data_Sheets/ADE7753.pdf
Ive tried to go about using this to calibrate the ade7753 but to no avail, The datasheet is quite complicated compared to the usual datasheets I work with
Anyway I would just like to ask if anyone has used a similar device in the ADE77xx family and can offer me any advice on how to tackle calibrating these type of IC
Here is my current code simply used to transmit values received from the ADE7753 to a PC:
Quote: | /***************************************************************************
* PREPROCESSOR STUFF - this gets everything setup just so
***************************************************************************/
#case // tells compiler to be case sensitive!
#include <16F876.h> // this tells the compiler what kind of PIC we are using
#include <math.h>
#fuses XT,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT, NOLVP //see page 18 in CCS manual for details of fuses
#use DELAY(clock = 4000000) //clock speed is 4 MHz
#use RS232 (BAUD=9600, XMIT=PIN_C6, RCV=PIN_C7, PARITY=N, BITS=8) //Setup the serial port on Pins C6 and C7,at 9600 Baud
// set up Port registers - basically, we are giving names to memory addresses. Memory address 0x85, for example, we will call PORT_A_DDR
#BYTE PORT_A_DDR = 0x85 //this is the 'Direction Register', or the register that holds in input/output state of the pins of Port A
#BYTE PORT_B_DDR = 0x86 //Direction Register for Port B
#BYTE PORT_C_DDR = 0x87 //Direction Register for Portn C
#BYTE PORT_A = 0x05 //this is Port A, the register that holds the high/low state of the pins of Port A
#BYTE PORT_B = 0x06 //Port B
#BYTE PORT_C = 0x07 //Port C
// constants for bus communications (don't change these)
#use fast_io(A) //this tells the compiler NOT to check the I/O state of the pin before writing or reading to it, making things work faster
#use fast_io(B)
//// Driver routines for the ADE7753 chip
#define ADE_CS PIN_C2
#define ADE_RESET PIN_C1
#define ADE_DOUT PIN_C4
#define ADE_DIN PIN_C5
#define ADE_CLK PIN_C3
void write_ade_byte(BYTE data);
ade_init()
{
output_low(ADE_RESET);
output_high(ADE_CLK);
output_high(ADE_CS); //Set low to AD7753 chip select low pin
output_high(ADE_RESET); //Set high to AD7753 reset low pin
delay_ms(3000);
setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_CLK_DIV_4);
write_ade_byte( 0x12 ); //Communications Register
write_ade_byte( 0x62 ); //Setup Register info here
}
void write_ade_byte(BYTE data) {
BYTE i; //The 8 bytes writing to
output_low(ADE_CS);
for(i=1;i<=8;++i) {
output_low(ADE_CLK);
output_bit(ADE_DOUT, shift_left(&data,1,0));
output_high(ADE_CLK);
}
output_high(ADE_CS);
}
long int read_ade_word() {
BYTE i;
long data;
output_low(ADE_CS);
for(i=1;i<=16;++i) {
output_low(ADE_CLK);
output_high(ADE_CLK);
shift_left(&data,2,input(ADE_DIN));
}
output_high(ADE_CS);
return data;
}
long int read_ade_value() {
long int value;
write_ade_byte(0x3a);
value=read_ade_word();
return value;
}
/************************************************************************
* MAIN PROGRAM
************************************************************************/
void main() {
int value;
ade_init();
printf("Sampling:\r\n");
while (TRUE) {
value = read_ade_value();
printf("\r\nInput = %u V", value);
}
} |
Thank you for your Time and I hope you can help
Sutton. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Feb 15, 2007 1:36 pm |
|
|
I didn't look at your code closely, but I noticed these things:
1. You're doing software SPI. All your routines use "bit banging"
to perform the SPI operations. But, then you're setting up the
hardware SPI module with the setup_spi() statement:
Quote: | setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_CLK_DIV_4); |
You're not using hardware SPI. Delete that line.
2. You have this routine which returns a 16-bit unsigned integer:
Quote: | long int read_ade_word() { |
But then in your main() code, you're putting the returned value of
that routine into an 8-bit unsigned integer. You're throwing away
the MSB. Is that what you want to do ?
Quote: | int value;
value = read_ade_value();
printf("\r\nInput = %u V", value); |
If you want it be 16-bit, then declare 'value' as a 'long' or 'int16'.
Also, use "%lx" in printf, to print a 16-bit value.
CCS data types are different than ANSI. All data types are unsigned
by default. An 'int' is only 8-bits. A 'short' is 1 bit. A 'long' is 16 bits. |
|
|
SherpaDoug
Joined: 07 Sep 2003 Posts: 1640 Location: Cape Cod Mass USA
|
|
Posted: Thu Feb 15, 2007 1:41 pm |
|
|
Can you read a register that needs no calibration, like the mode register 0x09 or the die revision register 0x3f? You should be able to write and then read the mode register. _________________ The search for better is endless. Instead simply find very good and get the job done. |
|
|
Sutton
Joined: 15 Feb 2007 Posts: 2
|
|
Posted: Thu Feb 15, 2007 7:22 pm |
|
|
cheers ill have a go at changing things with these ideas. And post on the forums the outcomes.
Cheers for the help
Sutton |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|