View previous topic :: View next topic |
Author |
Message |
123bally
Joined: 20 Jan 2013 Posts: 21
|
MCP4921 SPI D-A issues - Please help |
Posted: Thu May 09, 2013 7:41 am |
|
|
Hello all
I have had a really good go at this but now I have reached the point of posting. I cannot see why this won't work for me, maybe you guys can point me in the right direction:
I have an 18F4431 and using Port C SPI to control 2 chips.
The first is an MCP41010 8 bit SPI pot - this works fine and I use it as my proof that the SPI works in mode 1-1
The second chip is the MCP4921 (8 pin DIP) and it simply won't respond to my commands - output voltage is 0V.
My code appends command and data values together and then uses an SPI write to send out the upper 8bits followed by the lower 8 bits in a function called Set_pot().
I am setting the command value to 0x3000 in a 16 bit variable called VOutOn(0x3000 = Write to DAC,Unbuffered,Gain=1,Active) and appending my required DAC value
I have checked the values on the LCD and in the simulator and all look good - so I am totally confused as to why won't this work???
Code: | #include <18F4431.H>
#fuses hs, NOWDT, NOBROWNOUT, PUT, NOLVP,NOMCLR,SSP_RC// USE SSP_RD WHEN ON PORT D SPI
#use delay(clock = 4000000)
//#USE rs232(bAUD=9600,XMIT=PIN_C6, RCV=pin_c7, BITS=8,errors)
//This code powers up and displays messages on the LCD
//It also increments the Vout signal to a maximum and repeats
//In additrion it cycles each relay on and off in turn
// Use the trim POT to set contrast levels - estimated 1.0V on Pin 3
#include "flex_lcd.c"
//**********************FUNCTION DEFINITIONS************************
void set_pot(void);///function variables
//********************Varaibles and Definitions ******************
#byte LATA = 0xF89 //define register address
#byte LATB = 0xF8A //define register address
#byte LATC = 0xF8B //define register address
#byte LATD = 0xF8C //define register address
#byte LATE = 0xF8D //define register address
#define SPI_MODE_0_0 (SPI_L_TO_H | SPI_XMIT_L_TO_H) //SPI Mode 0
#define SPI_MODE_0_1 (SPI_L_TO_H) //SPI Mode 1
#define SPI_MODE_1_0 (SPI_H_TO_L) //SPI Mode 2
#define SPI_MODE_1_1 (SPI_H_TO_L | SPI_XMIT_L_TO_H) //SPI Mode 3
#define CS PIN_c0 //chip select for SPI POT
#define CS2 Pin_c1 //chip select for SPI D-A
#define PtCycCon PIN_E0
#define PtmInhibit PIN_E1
#define EtCycleCon PIN_E2
long inc=0,VoutOn=0x3000,VoutOff=0x0000,SPI16=0;
int SpiValUpper=0,SpiValLower=0,SPITest=0;
char c;
void main()
{
set_tris_b(0x03); // B0 - B1 as inputs
set_tris_a(0x3C); // RA2,Ra3,RA4 as input
set_tris_d(0x00);
set_tris_c(0x00); //C port as output
set_tris_E(0x03); // E Port as output
setup_spi(SPI_MASTER | SPI_MODE_1_1 | SPI_CLK_DIV_16 | SPI_SS_DISABLED); // mode 1-1 or 0-0 will work - DO NOT FORGET TO ADD THE PORT USED FOR SPI (FUSES: SSP_RD)
//with MCP 41010 - the important variable seems to be xmit_l_to_h, alSo note ss is disabled as we have one way
output_high(CS);
output_high(CS2); //spi comunication - thus it is not needed. **MPLAB SIM cannot simulate SPI functions - it WILL HANG!!
lcd_init(); // Always call this first
delay_ms(100);
printf(lcd_putc,"\f Hello World\n"); //LCD Alive
SPI16=VoutOn|inc;
SpiValUpper=make8(SPI16,1);
SpiValLower=make8(SPI16,0);
printf(lcd_putc,"SPI = %6lu",SPI16);
inc=0;
delay_ms(2000);
while(true)
{
SPI16=VoutOn|inc; //construct SPI String(Command + Data) Note: VoutOn initialised to command value 0x3000
set_pot(); //Send Command and upper 4 bits of data
inc=INC+10; //Increment set value
SPITest++;
printf(lcd_putc,"\fSPI = %6lu\n",SPI16); //Display SPI value to be sent in 16bit format
printf(lcd_putc,"MSB %u LSB %u",SpiValUpper,SpiValLower); //display Values to be written to spi (command+upperdata) and (lowerdata)
delay_ms(100);
if(inc==4095) //display and hold maximum output
{
printf(lcd_putc,"\f Max Output\n");
delay_ms(2000);
//RS232 kbhit request
inc=0;
}
}
}
//**********************************Functions************************************************
void set_pot ()
{
SpiValUpper=make8(SPI16,1);
SpiValLower=make8(SPI16,0);
//write to MCP 4921
output_low(CS2);
SPI_WRITE(SpiValUpper);
SPI_WRITE(SPIValLower);
output_high(cs2);
//Write to MCP41010
output_low(CS);
SPI_WRITE(0x11);
SPI_WRITE(SPITest);
output_high(CS);
} |
Note hardware connections checked and look ok. I have connected Vref to VDD and LDAC to VSS. I am using a PICDem2 board to test this. |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Thu May 09, 2013 7:54 am |
|
|
If you are manully setting TRIS - then you need to declare
#use fastio.......
also the handling of INC
inc=0
then
inc=INC+10;
then
if(inc==4095)
see a problem there ??
as to the 4921
if you never toggle LDAC - you will never update the output
see figure 1-1 of the data sheet !!!
( or did you tie it for auto NOT/cs ops ? no schematic makes this unclear)
anyway this seems to be
a fundamental problem which should not work in "simulation" or the real world ......
of course you have no output , cuz thats how you programmed it to be
|
|
|
123bally
Joined: 20 Jan 2013 Posts: 21
|
|
Posted: Thu May 09, 2013 8:28 am |
|
|
Hi
Thanks for the reply, Yes I spotted the mistake on the if statement just after posting.
Now changed to if (INC>=4095) - So now I ensure that I dont corrupt my command instruction - but still its won't solve the lack of output voltage...
Also (as you suspected) I have connected LDAC to gnd so the register should get updated on the CS rising edge. (see bottom of my original post)
Quote: |
of course you have no output , cuz thats how you programmed it to be |
really?? I still can't see it?
Andy. |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Thu May 09, 2013 8:44 am |
|
|
in the end , it comes down to
1- programming,
or
2- circuit hookup
or
3 - bad part ?
perhaps you have no ref voltage on the DAC??
so
posting a link to the schematic of your circuit - showing all connections-
would be the next logical step 4 U 2 take.......
and BTW
(INC>4090)
will do just as well for your purposes
lastly -
we have word length ....
are you sure of the command bits ?? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19496
|
|
Posted: Thu May 09, 2013 9:00 am |
|
|
As a comment, you don't want:
| SPI_SS_DISABLED
This is for _slave_ configurations only. Turns off slave select. On a master it can cause incorrect configuration. If you look at the data sheet for your chip, it sets SSPM0. Fortunately it makes no difference with the clock set for /16. However, if you were trying to select Fosc/4, it'd change the selection to Fosc/16, while if you were trying to select Fosc/16, it'd change the clock to use timer2....
Best Wishes |
|
|
123bally
Joined: 20 Jan 2013 Posts: 21
|
|
Posted: Thu May 09, 2013 10:05 am |
|
|
Looking in more detail now and still finding nothing wrong. What is going on??
So I have hooked up a dig scope and checked signals. CS is being pulled low before and after spi write- so happy on that.
I took an image of signals showing the first 4 bits (command) being clocked in as 0011 on rising edge of clock (spi mode 0-0), this means:
bit 15: 0 - Write to DAC
bit 14: 0 - Unbuffered
bit 13: 1 - Gain = 1
bit 12: 1 - Active mode Vout on
Whats the best way for me to attach an image and a circuit diagram for you guys to see?
The remaining data bits look ok too, I get 16 clocks in total so length is good and playing with fixed spi write values shows it seems to be working. The fact that the MCP41010 is also working fine within the same code points me to software being good.
So again I checked the hardware but cant see a problem -
VDD and Vref at 5v
VSS and LDAC at 0V
Vout into a 10K resistor
CS - C1
SPI - SD0
SCK - SCK
I am wondering about trying to clock the LDAC just to see what happens - regardless of the datasheet indicating it can be grounded.
Telmah - thanks for your suggestion, I have amended the code.
Asmboy - I am starting to think about your suggestion of bad part - so have ordered new ones just in case...
Thanks Andy.. |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Thu May 09, 2013 10:49 am |
|
|
verify wiring of pic to the part carefully - test with vtvm |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu May 09, 2013 11:05 am |
|
|
Quote: | Whats the best way for me to attach an image and a circuit diagram for you guys to see? |
Upload it to a free image hosting website such as http://www.imageshack.us and then post a link to it. |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Thu May 09, 2013 11:27 am |
|
|
about trying to clock the LDAC
EXCELLENT IDEA!! |
|
|
123bally
Joined: 20 Jan 2013 Posts: 21
|
|
Posted: Thu May 09, 2013 11:41 am |
|
|
Here's the picture / Circuit...
Circuit:
Scope of bits 15-8 showing command bits 0x30 (0011 0000)
Thanks Guys....
Last edited by 123bally on Thu May 09, 2013 12:30 pm; edited 1 time in total |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Thu May 09, 2013 11:44 am |
|
|
and NOT/CS enable ,
is also scoped as being a-ok ?? |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Thu May 09, 2013 11:44 am |
|
|
asmboy wrote: |
good screen capture !!!
U R sure NOT/CS enable ,
is also scoped as being a-ok ?? |
|
|
|
123bally
Joined: 20 Jan 2013 Posts: 21
|
|
Posted: Thu May 09, 2013 11:51 am |
|
|
HI Asmboy, just to confirm:
CS signal and clock showing cs high to low before and low to high after clocking 2 x 8 bit cycles
Cheers Andy |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu May 09, 2013 12:28 pm |
|
|
Why is the mcp4921's Vout pin connected to the +5v power rail ?
Is it connected that way in your actual hardware circuit ? Or was it ever ? |
|
|
123bally
Joined: 20 Jan 2013 Posts: 21
|
|
Posted: Thu May 09, 2013 12:33 pm |
|
|
PCM you spotted it before I could update the picture, that was an error in the schematic only. Hardware was OK. I have changed the link to a correct version schematic. Showing V ref to +5V
Well spotted though...10 out of 10!!
Andy |
|
|
|