|
|
View previous topic :: View next topic |
Author |
Message |
kranthikiran.a
Joined: 19 Aug 2010 Posts: 2
|
Wrong ADC Value Getting in MAXQ3180 |
Posted: Thu Aug 19, 2010 11:57 pm |
|
|
Hi Guys,
This is kranthi kiran.
I am working on MAXQ3180 Energy meter IC with PIC18F4520. This IC has SPI communication. I am able to communicate with the MAXQ3180 IC. SPI communication code is perfectly working. But my problem is voltage ADC value in the MAXQ3180 IC is not increasing if I increased the input voltage at voltage channel pin. Here I am placing my code. I am using PIC18F4520 MCU.
Code: |
#define VOLT_CC 0x014
#define AMP_CC 0x016
#define PWR_CC 0x018
#define ENR_CC 0x01A
#define A_VRMS 0x1C8
#define A_IRMS 0x1CC
#define B_VRMS 0x2B4
#define B_IRMS 0x2B8
#define C_VRMS 0x3A0
#define C_IRMS 0x3A4
[[color=red]b]<SPI Code Starts Here>[/b][/color]
#define SPI_SS PIN_A5 //This pin is active low pin.
//SPI_SS should be Low to work SPI Communication
#define SPI_SCLK PIN_C3
#define SPI_SDO PIN_C5
#define SPI_SDI PIN_C4
#define SPI_Enable(); output_low(SPI_SS);
#define SPI_Reset(); output_high(SPI_SS); \
delay_ms(10); \
output_low(SPI_SS); \
delay_cycles(5); //This will Reset the SPI Communication
#define SPI_Disable(); output_high(SPI_SS); //This will Disable the SPI Communication
//ASIC_Add[1] Contains MSB of ASIC Address
//ASIC_Add[0] Contains LSB of ASIC Address
unsigned int8 ASIC_Bytes=0, ASIC_Data[8], ASIC_Add[2], ASIC_Cmd=0, ASIC_Temp=0;
unsigned int16 ASIC_Address=0;
void ASIC_Read(void);
void ASIC_Write(void);
void SPI_TX(unsigned char);
unsigned char Reverse_Bits(unsigned char);
void ASIC_Read(void)
{
/* Refer MAXQ3183 Data Sheet FOR Complete Details About SPI Communication Flow Chart*/
/* ASIC has two Command Bytes.
ASIC Command Byte1 Bits:
Command Code
7:6
0 0 - Read
0 1 - Reserved
1 0 - Write
1 1 - Reserved
Data Length
5:4
0 0 - 1 Byte
0 1 - 2 Bytes
1 0 - 4 Bytes
1 1 - 8 Bytes
3:0 MSB Portion of Data Address*/
unsigned char i = 0;
Read:
ASIC_Add[0] = (unsigned int8)(ASIC_Address & 0x00FF);
//Extract The LSB portion from ASIC_Address 16Bit Register.
ASIC_Add[1] = (unsigned int8)((ASIC_Address & 0x0F00)>>0x08);
//Extract The MSB portion from ASIC_Address 16Bit Register.
//Consider Lower Nibble in that extracted part,Because ASIC has only 12Bit Address.
ASIC_Cmd &= 0x3F; //7th nd 6th bits in Command Byte1 REGISTER Should be zero for ASIC Read REGISTER Operation
switch (ASIC_Bytes)
{
case 1:bit_clear(ASIC_Cmd,4); //This case is FOR 1 Byte Data Length
bit_clear(ASIC_Cmd,5);
break;
case 2:bit_set(ASIC_Cmd,4); //This case is FOR 2 Bytes Data Length
bit_clear(ASIC_Cmd,5);
break;
case 4:bit_clear(ASIC_Cmd,4); //This case is FOR 4 Bytes Data Length
bit_set(ASIC_Cmd,5);
break;
case 8:bit_set(ASIC_Cmd,5); //This case is FOR 8 Bytes Data Length
bit_set(ASIC_Cmd,4);
break;
default:bit_clear(ASIC_Cmd,4); //This Default case is FOR 1 Byte Length
bit_clear(ASIC_Cmd,5);
break;
}
ASIC_Add[1] &= 0x0F; //ASIC_Add[1] Contains MSB of ASIC Address.Higher Nibble in the MSB Should be Zero,
//Because ASIC has only 12Bit Address.So MSB contains data only in Lower Nibble
ASIC_Cmd |= ASIC_Add[1];
spi_write(ASIC_Cmd); //Write SPI Command Byte1
ASIC_Temp = spi_read(); //Read SPI Data Received. ASIC will send 0xC1 as acknoledge;
if(ASIC_Temp==0xC1)
delay_us(60);
else
{
delay_ms(360);
goto Read;
}
ASIC_Cmd = ASIC_Add[0]; //Load ASIC Command Byte2 in ASIC_Cmd REGISTER,
spi_write(ASIC_Cmd); //ASIC_Add[0] Contains LSB of 12Bit Address
ASIC_Temp = spi_read();
if(ASIC_Temp==0xC2)
delay_us(60);
else
{
delay_ms(360); //Reset ASIC_Add Variable to zero and recall the function using GOTO,
ASIC_Cmd = 0; //Because this compiler is not supporting recursive functions
goto Read;
}
spi_write(00); //Send Dummy Byte To get the Data From Slave
ASIC_Temp = spi_read();
while(ASIC_Temp==0x4E)
{
delay_us(60);
spi_write(00); //Send Dummy Byte To get the Data From Slave
ASIC_Temp = spi_read();
}
if(ASIC_Temp==0x41)
{
do
{
delay_us(60);
spi_write(00);
ASIC_Data[i]=spi_read(); //ASIC Will send LSB First.So ASIC_Data[0] Contains LSB and ASIC_Data[n] Conatains MSB
i++;
}while(--ASIC_Bytes);
}
else
{
delay_ms(360);
ASIC_Cmd = 0;
goto Read;
}
}
void ASIC_Write(void)
{
/* Refer MAXQ3183 Data Sheet FOR Complete Details About SPI Communication Flow Chart*/
/* ASIC has two Command Bytes.
ASIC Command Byte1 Bits:
Command Code
7:6 00 - Read
01 - Reserved
10 - Write
11Reserved
Data Length
5:4 00 - 1 Byte
01 - 2 Bytes
10 - 4 Bytes
11 - 8 Bytes
3:0 MSB Portion of Data Address*/
unsigned char i=0;
Write:
//Extract The LSB portion from ASIC_Address 16Bit Register
ASIC_Add[0] = (unsigned int8)(ASIC_Address & 0x00FF);
/*Extract The MSB portion from ASIC_Address 16Bit Register.
Consider Lower Nibble in that extracted part,Because ASIC has only 12Bit Address.
ASIC_Add[1] Contains MSB of ASIC Address.Higher Nibble in the MSB Should be Zero,
Because ASIC has only 12Bit Address.So MSB has data only in Lower Nibble.*/
ASIC_Add[1] = (unsigned int8)((ASIC_Address & 0x0F00)>>0x08);
bit_set(ASIC_Cmd,7); //7th Bit in Command Byte1 REGISTER Should be set and
bit_clear(ASIC_Cmd,6); //6th Bit in Command Byte1 REGISTER should be clear for ASIC Write REGISTER Operation
switch (ASIC_Bytes)
{
case 1:bit_clear(ASIC_Cmd,4); //This case is FOR 1 Byte Data Length
bit_clear(ASIC_Cmd,5);
break;
case 2:bit_set(ASIC_Cmd,4); //This case is FOR 2 Bytes Data Length
bit_clear(ASIC_Cmd,5);
break;
case 4:bit_clear(ASIC_Cmd,4); //This case is FOR 4 Bytes Data Length
bit_set(ASIC_Cmd,5);
break;
case 8:bit_set(ASIC_Cmd,5); //This case is FOR 8 Bytes Data Length
bit_set(ASIC_Cmd,4);
break;
default:bit_clear(ASIC_Cmd,4); //This Default case is FOR 1 Byte Length
bit_clear(ASIC_Cmd,5);
break;
}
ASIC_Cmd |= ASIC_Add[1];
spi_write(ASIC_Cmd); //Write SPI Command Byte1
ASIC_Temp = spi_read(); //Read Received Data Byte. ASIC will send 0xC1;
if(ASIC_Temp==0xC1)
delay_us(60);
else
{
delay_ms (360);
goto Write;
}
ASIC_Cmd = ASIC_Add[0]; //Load ASIC Command Byte2 in ASIC_Cmd REGISTER, ASIC_Add[0] Contains LSB of 12Bit Address
spi_write(ASIC_Cmd); //Write SPI Command Byte2
ASIC_Temp = spi_read(); //Read Received Data Byte. ASIC will send 0xC2;
if(ASIC_Temp==0xC2)
{
do
{
delay_us(60);
spi_write(ASIC_Data[i]); //Write LSByte of Data Byte First.
ASIC_Temp = spi_read(); //Read Received Data Byte.ASIC will send 0x41;
if(ASIC_Temp != 0x41)
{
ASIC_Cmd = 0;
delay_ms (360);
goto Write;
}
i++;
}while(--ASIC_Bytes);
}
else
{
delay_ms(360); //Reset ASIC_Add Variable to zero and recall the function using goto only,
ASIC_Cmd = 0; //Because this compiler is not supporting recursive functions
goto Write;
}
do
{
delay_us(60);
spi_write(00);
ASIC_Temp = spi_read();
}while(ASIC_Temp==0x4E);
if(ASIC_Temp!=0x41)
{
delay_ms(360);
ASIC_Cmd = 0;
goto Write;
}
}
[[color=red]b]<SPI Code Ends Here>[/b][/color]
[[color=red]b]<Code in Infinite Loop Starts Here>[/b][/color]
while(TRUE)
{
//restart_wdt();
LCD_WriteCmd(0x80);
LCD_Display("VOLTS_CC:");
ASIC_Bytes = 2;
ASIC_Address = VOLT_CC;
ASIC_Read();
Long_Buff = make32(0x00,0x00,ASIC_Data[1],ASIC_Data[0]);
Disp_Long(Long_Buff);
LCD_WriteCmd(0xC0);
LCD_Display("R:");
ASIC_Bytes = 4;
ASIC_Address = A_VRMS;
ASIC_Read();
Long_Buff = make32(ASIC_Data[3],ASIC_Data[2],ASIC_Data[1],ASIC_Data[0]);
Disp_Long(Long_Buff);
LCD_WriteCmd(0x94);
LCD_Display("Y:");
ASIC_Bytes = 4;
ASIC_Address = B_VRMS;
ASIC_Read();
Long_Buff = make32(ASIC_Data[3],ASIC_Data[2],ASIC_Data[1],ASIC_Data[0]);
Disp_Long(Long_Buff);
LCD_WriteCmd(0xD4);
LCD_Display("B:");
ASIC_Bytes = 4;
ASIC_Address = C_VRMS;
ASIC_Read();
Long_Buff = make32(ASIC_Data[3],ASIC_Data[2],ASIC_Data[1],ASIC_Data[0]);
Disp_Long(Long_Buff);
delay_ms(3000);
LCD_WriteCmd(0x01);
LCD_WriteCmd(0x80);
LCD_Display("CURR_CC:");
ASIC_Bytes = 2;
ASIC_Address = AMP_CC;
ASIC_Read();
Long_Buff = make32(0x00,0x00,ASIC_Data[1],ASIC_Data[0]);
Disp_Long(Long_Buff);
LCD_WriteCmd(0xC0);
LCD_Display("R:");
ASIC_Bytes = 4;
ASIC_Address = A_IRMS;
ASIC_Read();
Long_Buff = make32(ASIC_Data[3], ASIC_Data[2], ASIC_Data[1], ASIC_Data[0]);
Disp_Long(Long_Buff);
LCD_WriteCmd(0x94);
LCD_Display("Y:");
ASIC_Bytes = 4;
ASIC_Address = B_IRMS;
ASIC_Read();
Long_Buff = make32(ASIC_Data[3], ASIC_Data[2], ASIC_Data[1], ASIC_Data[0]);
Disp_Long(Long_Buff);
LCD_WriteCmd(0xD4);
LCD_Display("B:");
ASIC_Bytes = 4;
ASIC_Address = C_IRMS;
ASIC_Read();
Long_Buff = make32(ASIC_Data[3], ASIC_Data[2], ASIC_Data[1], ASIC_Data[0]);
Disp_Long(Long_Buff);
delay_ms(3000);
}
[[color=red]b]<Code in Infinite Loop Starts Here>[/b][/color]
|
_________________ Thanks & Regards,
Kranthi Kiran.A
Last edited by kranthikiran.a on Fri Aug 20, 2010 10:12 pm; edited 2 times in total |
|
|
kranthikiran.a
Joined: 19 Aug 2010 Posts: 2
|
Forgot To Place SPI Initialisation Code |
Posted: Fri Aug 20, 2010 1:00 am |
|
|
Code: |
/*PIC SPI configured as Master.
--> Idle Clock state of PIC is Logic Low Level(CKP=0).
--> Data Out on Transition From Active to Idle State of SCLK.(CKE=1)
--> Data is sampled at middle of data O/P (Data is sampled at rising of SCLK)
MAQ3183(ASIC) Default SPI Configuration
--> Idle Clock Polarity is Logic Low State(CKP = 0).
--> ASIC will sample the data at active edge i.e
transition from idle state to active state
Corresponding Tris Bits have been configured
*/
setup_spi(SPI_MASTER | SPI_L_TO_H | SPI_CLK_DIV_16 ); |
_________________ Thanks & Regards,
Kranthi Kiran.A |
|
|
Fandango
Joined: 11 Oct 2010 Posts: 4 Location: Brazil
|
|
Posted: Mon Oct 11, 2010 4:04 pm |
|
|
Hi Kranthi Kiran,
I am working with an ATmega324P and I triyng to communicate with a MAXQ3181 (a subset of MAXQ3180) under SPI. I have also two FRAM in this SPI bus, both communicating perfectly.
Well I did start to write code to the MAXQ3181, but I have a lot of doubts regarding its commands under SPI and so one.
I did read your code but I didn't understand very well. I would like to ask you if you already have your system run, because I think we can help us (one to other) after my system run too (I mean, after my MAXQ3181 will talk with the MCU).
Regards. |
|
|
pad
Joined: 29 Nov 2007 Posts: 15
|
about maxq3180 |
Posted: Thu Oct 14, 2010 5:36 am |
|
|
Hi kranthi kiran, I'm also working on maxq 3180 AFE. I am able to communicate, read virtual registers correctly and can dispaly 3 phase V, I, PF, power and energy, but not able to work with harmonics registers as described in data sheet. Do you have any idea regarding it ? |
|
|
Fandango
Joined: 11 Oct 2010 Posts: 4 Location: Brazil
|
Re: about maxq3180 |
Posted: Thu Oct 14, 2010 7:30 am |
|
|
pad wrote: | Hi kranthi kiran, I'm also working on maxq 3180 AFE. I am able to communicate, read virtual registers correctly and can dispaly 3 phase V, I, PF, power and energy, but not able to work with harmonics registers as described in data sheet. Do you have any idea regarding it ? |
Hi PAD,
My system is not working yet because I don't know exactly how to communicate with the MAXQ3181 (a subset of your MAXQ3180).
Searching at Google, with the aim to find some C routines for this, I saw something regarding using a MAXQ3180 with harmonics. I will try to find it again, but I think you can search in Google with keywords "MAXQ3180 harmonics" (not so helpfull, I know).
I did a support request for help to Maxim, but nobody replies yet. I will appreciate so much if you could help me with at least a starting point. Do you mind to share yours MAXQ routines? I mean, can you send or post your MAXQ3180 firmware routines? I am from Brazil and my e-mail address is daniel.liontec_AT_hotmail.com
Thank you in advance. |
|
|
aaronik19
Joined: 25 Apr 2011 Posts: 297
|
MAXQ3180 |
Posted: Mon Apr 25, 2011 11:21 pm |
|
|
Hi kranthikiran.a,
for MAXQ3180, you built the circuit on the datasheet submitted by Maxim-IC? Can you please send me a photo of your project. From where you bought all the components to build this circuit? I contacted Digikey and many components are not available! Can you please help me.
Really thanks for your help in advance |
|
|
Ram Prasadh
Joined: 26 Apr 2011 Posts: 2 Location: India
|
Cannot read data from maxq3180 |
Posted: Mon Jun 06, 2011 12:00 am |
|
|
With PIC16F72 as the master I am having MAXQ3180 as my slave. I am able to get 0x41 as the ack from the MAX which means that if I send dummy bytes, I can get the data from the MAX. But I am able to get only 0xc1 and 0xc2 again for the dummy bytes which I send to get the data. I am only reading one register as soon as the MAX powers up. Should I have to write any register first before reading? |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9221 Location: Greensville,Ontario
|
|
Posted: Mon Jun 06, 2011 9:08 am |
|
|
You have to read, and re-read the Maxim datasheet and cut code for your own driver.
It's not that hard, really, Maxim supplies ALL the information required to use their chip and using SPI on a PIC (with builtin interace) is pretty easy.
Start off with a basic program to read the MAXQ3180 registers,compare with the defaults( from Maxim datasheet) to see if you're reading the correct data(wiring,pcb,voltage levels,etc.)
Then send some 'initialization' commands to the MAXQ, again, now confirm that you're actually 'talking' to the chip.
Once you're Ok with that, cut code as required to control the MAXQ for your project.
3 maybe 4 days of dedicated work should get you 'up and running'. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9221 Location: Greensville,Ontario
|
|
Posted: Mon Jun 06, 2011 9:11 am |
|
|
Just looked at the Maxim site and they have an Application Note( AN4246) that details how to use C code to use SPI for the MAXQ chip.
That should save 2-3 days for you. |
|
|
|
|
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
|