CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Wrong ADC Value Getting in MAXQ3180

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
kranthikiran.a



Joined: 19 Aug 2010
Posts: 2

View user's profile Send private message

Wrong ADC Value Getting in MAXQ3180
PostPosted: Thu Aug 19, 2010 11:57 pm     Reply with quote

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

View user's profile Send private message

Forgot To Place SPI Initialisation Code
PostPosted: Fri Aug 20, 2010 1:00 am     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Oct 11, 2010 4:04 pm     Reply with quote

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

View user's profile Send private message

about maxq3180
PostPosted: Thu Oct 14, 2010 5:36 am     Reply with quote

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

View user's profile Send private message

Re: about maxq3180
PostPosted: Thu Oct 14, 2010 7:30 am     Reply with quote

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

View user's profile Send private message

MAXQ3180
PostPosted: Mon Apr 25, 2011 11:21 pm     Reply with quote

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

View user's profile Send private message Send e-mail

Cannot read data from maxq3180
PostPosted: Mon Jun 06, 2011 12:00 am     Reply with quote

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: 9245
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Mon Jun 06, 2011 9:08 am     Reply with quote

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: 9245
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Mon Jun 06, 2011 9:11 am     Reply with quote

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.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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