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.

[SOLVED] AD5060 interfacing with 18F2620

Status
Not open for further replies.

hemnath

Advanced Member level 3
Joined
Jun 24, 2012
Messages
702
Helped
61
Reputation
120
Reaction score
57
Trophy points
1,308
Location
Chennai
Activity points
6,588
Code:
#include "18F2620.h"
#include "f2420_regs.h"
#fuses INTRC_IO, NOWDT,BROWNOUT,PUT 
#use delay(clock=4000000)

#define RS PIN_A2
#define EN PIN_A1

#define CS PIN_C0

void main()
{

 TRISB=0;                   // PORTB is configured as an output port
 TRISC=0;                   // PORTC is configured as an output port
 PORTC=0;
 PORTB=0;

   delay_ms(100);
   SSPSTAT=0xC0;              //Status Register SSPSTAT=11000000
   SSPCON1 = 0b00100000;

   output_high(CS);
   delay_ms(1000);
   
   while(1)
   {   
      output_low(CS);
      SSPBUF=100;                      // sending the lower 8 bits serially  
      while(!BF);                // wait until the lower 8 bits are sent

      SSPBUF=100;                      // sending the lower 8 bits serially  
      while(!BF);                // wait until the lower 8 bits are sent

      output_high(CS);
      delay_ms(100);
   }
}

Output voltage is always zero. Please help
 

According to PIC datasheet, SSPBUF must be read to clear BF.

Also AD5060 expects 24 bit data rather than 16.
 

Code:
   while(1)
   {   
      output_low(CS);
      SSPBUF=0x00;                      // sending the upper 8 bits serially  
      while(!BF);                // wait until the upper 8 bits are sent

      SSPBUF=100;                      // sending the lower 8 bits serially  
      while(!BF);                // wait until the lower 8 bits are sent

      SSPBUF=100;                      // sending the lower 8 bits serially  
      while(!BF);                // wait until the lower 8 bits are sent

      output_high(CS);
      delay_ms(100);
   }
Can be done like this?
According to PIC datasheet, SSPBUF must be read to clear BF.
How to read? Please help
 

Hi ,
spi is serial communication , there internal buffers are connected in ring topology to clear SSPBUF you need to read that buffer i.e. you can write simple function like

//in main function

data = WriteSPI2(0x01);

int WriteSPI2( int data)
{
SSPBUF = data; // write to buffer for TX
while( !BF); // wait transfer completion
return SSPBUF; // read the received value
}
 

I have bought some sample DAC from LT and Analog Devices.
code for LTC1655 - 16 bit DAC
Code:
#include "18F2620.h"
#include "f2420_regs.h"
#fuses INTRC_IO, NOWDT,BROWNOUT,PUT
#use delay(clock=4000000)

#define RS PIN_A2
#define EN PIN_A1

#define CS PIN_C0

unsigned int dac(unsigned int16 data);
unsigned int16 value;
unsigned int8 high_value = 0;
unsigned int8 low_value = 0;
unsigned int8 data;

void main()
{
   
    TRISB=0;                   // PORTB is configured as an output port
    TRISC=0;                   // PORTC is configured as an output port
    PORTC=0;
    PORTB=0;

   delay_ms(1000);
//   SSPSTAT=0x80;              //Status Register SSPSTAT=10000000
   SSPSTAT=0xC0;              //Status Register SSPSTAT=11000000
//   SSPCON1=0x20;             //Enables serial port pins & set the SPI clock as clock = FOSC/4
   SSPCON1 = 0b00100001;

   output_high(CS);
   delay_ms(1000);

   value = 0;
   
   while(1)
   {   
      value = 32768;
      data = dac(value);
      delay_ms(100);
   }
}

unsigned int dac(unsigned int16 data)
{
	high_value = ((data >> 8) & (0xFF));
	low_value = ((data >> 0) & (0xFF));
	
	output_low(CS);
	SSPBUF=high_value;                      // sending the upper 8 bits serially 
	while(!BF);                // wait until the upper 8 bits are sent
	SSPBUF=low_value;                      // sending the lower 8 bits serially 
	while(!BF);                // wait until the lower 8 bits are sent
	output_high(CS);   
	
	return (SSPBUF);
}
Output is zero. Why is it so?

- - - Updated - - -

When i power ON, output increases to some voltage for a fraction of second and drops to zero and stays at zero volt.
 

Hi
sorry get it you have SSPCON1 register which wil set I/o in proper direction automatically just read datasheet
 

Code:
	SSPBUF=high_value;                      // sending the upper 8 bits serially [1]
	while(!BF);                // wait until the upper 8 bits are sent                 [2]
	SSPBUF=low_value;                      // sending the lower 8 bits serially  [3]
	while(!BF);                // wait until the lower 8 bits are sent                 [4]
        output_high(CS);                                                                           [5]
}
You have been told this before but you are still not reading SPIBUF after each exchange. I have added a number to the statements i the above code for reference.
What will be happening is this:Statement [1] will be starting an exchange and begin sending the value to the other device - this is good.
Statement [2] will wait until the BF bit is set which indicates that the exchange has completed - again, this is good.
Statement[3] will then start a second exchange, but the BF flag is still set from the first exchange
Statement [4] is supposed to wait until the 2nd exchange completes but because the BF bit will still be set it will never loop
Therefore Statement [5] will execute that tells the slave device that the exchange is complete. As the 2nd exchange has not completed, the slave will abort whatever it is doing.
To correct this, you need a statement between statements [2] and [3] to read the SSPBUF (you can throw away the value if you don't need it) which will clear the BF bit and then make statement [4] wait for the 2nd exchange to complete.
Susan
 

Thanks . I want to send 16 bit value to LTC1655. I dont want to read, if its there is a need, I shall throw away the value, never mind..

Code:
#include "18F2620.h"
#include "f2420_regs.h"
#fuses INTRC_IO, NOWDT,BROWNOUT,PUT
#use delay(clock=4000000)

#define RS PIN_A2
#define EN PIN_A1

#define CS PIN_C0

unsigned int dac(unsigned int16 data);
unsigned int dac1(unsigned int16 data);
unsigned int16 value;
unsigned int8 high_value = 0;
unsigned int8 low_value = 0;
unsigned int8 temp;

void main()
{
   
    TRISB=0;                   // PORTB is configured as an output port
    TRISC=0;                   // PORTC is configured as an output port
    PORTC=0;
    PORTB=0;

   delay_ms(1000);
//   SSPSTAT=0x80;              //Status Register SSPSTAT=10000000
//   SSPSTAT=0xC0;              //Status Register SSPSTAT=11000000
	SSPSTAT=0x40;              //Status Register SSPSTAT=11000000
//   SSPCON1=0x20;             //Enables serial port pins & set the SPI clock as clock = FOSC/4
   SSPCON1 = 0b00100001;

   output_high(CS);
   delay_ms(1000);

   value = 0;
   
	while(1)
	{   
		value = 32768;
		temp = dac(value);
		temp = dac1(value);
		delay_ms(100);
	}
}

unsigned int dac(unsigned int16 data)
{
	high_value = ((data >> 8) & (0xFF));

//	high_value = 100;
//	low_value = 100;
	
	output_low(CS);
	SSPBUF=high_value;                      // sending the upper 8 bits serially 
	while(!BF);                // wait until the upper 8 bits are sent
	
	return(SSPBUF);
} 

unsigned int dac1(unsigned int16 data)
{
	low_value = ((data >> 0) & (0xFF));

	SSPBUF=low_value;                      // sending the lower 8 bits serially 
	while(!BF);                // wait until the lower 8 bits are sent
	output_high(CS);  

	return(SSPBUF);
}

now Output is 2.0486V(measured with keithley 8.5 digit multimeter). But suddenly the value changes to some random value for a fraction of second and restores back again and it happens continuously. Why this changes happening?
 

Hi
from the code I can see your returning value to the same variable, also check for below two factors
1) check the proper delay required for the chip to get selected -> high to low pulse which you are applying for chip select.
2) check if any sources of noise is there, i.e some high transition i/o operations or some other noise in circuit
 

I think you are over-complicating the whole process.
Firstly, it does not matter if you are reading or writing - with SPI you do both at the same time: ALWAYS.
You don't need two separate functions. Something like this would do:
Code:
unsigned int performSPIExchange( unsigned int value)
{
    SSPBUF = value;    // Start the exchange
    while( !BF);           // Wait for the exchange to complete
    // Put in error handling here
    return SSPBUF;     // Side effect - clears the BF bit
}
And where you want to send a value...
Code:
    output_low(CS);      // Select the slave
    performSPIExchange( value >>8);   // Send the high byte - ignore received value
    performSPIExchange( value);         // Send the low byte - ignore the received value
    output_high(CS);    // Deselect the slave
As for your using a multimeter to check the value, this is not the best tool as they respond too slowly - an oscilloscope is what you need.
Susan
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top