|
|
View previous topic :: View next topic |
Author |
Message |
iso9001
Joined: 02 Dec 2003 Posts: 262
|
Need help with SPI Digital Pot... |
Posted: Mon Dec 29, 2003 6:07 pm |
|
|
Just got some MCP41010s in and I'm having a problem getting them to work with SPI...
It seems they powerup just fine, the wiper goes to halfway and then... nothing, thats all it does. I can write to it all day, it doesnt move. I've used I2C before, but not SPI (which I hear is easier).
I'm using a 16F872 with PIN_C1 set to the CS pin on the pot. I've got the SCK in on the pot hooked to RC3/SCK/SCL and SI hooked up to RC5/SDO. These are all run directly to each other, I dont THINK i need pullups or anything like that right? Ofcourse VSS is grounded on the pot and VDD is hooked upto 5V.
This is what I have for code... I did a really long search on SPI stuff and it seems to get the pot to listen I need to draw its CS pin low, then high to get it to execute the command. Anyhow... Tada:
Code: |
#include <16F872.h>
#fuses RC,LVP,NOWDT,NOPROTECT, PUT, NOBROWNOUT
#use delay(clock=1000000)
void main() {
setup_spi(spi_master | spi_l_to_h | spi_clk_div_16 );
delay_us(20);
output_low(PIN_C1);
spi_write(128);
output_high(PIN_C1);
while(1){
} //eow
} //eom
|
Anyone have any ideas ???
Thank You Much,
Kyle |
|
|
iso9001
Joined: 02 Dec 2003 Posts: 262
|
|
Posted: Mon Dec 29, 2003 6:39 pm |
|
|
It must be obvious day at stupid camp...
The microchip SPI digital pots require me to send a command byte in first. THEN the data.
Woo that was fun! |
|
|
iso9001
Joined: 02 Dec 2003 Posts: 262
|
|
Posted: Mon Dec 29, 2003 7:20 pm |
|
|
Oh, Nope... Hang on, that didnt work at all.
Arg.
Ok, here is my new code:
Code: |
setup_spi(spi_master | spi_l_to_h | spi_clk_div_16 );
delay_us(20);
output_low(PIN_C1);
spi_write(17);
spi_write(128);
output_high(PIN_C1);
//17 = 00 01 00 01 == XX command XX which pot to command
|
Thats all I got... anyone have advice?[/code] |
|
|
Peter Guest
|
|
Posted: Mon Dec 29, 2003 9:32 pm |
|
|
Ohhh.
as I remember, those pots usually have 256 steps. Sooo, if you write 128 to it, would.nt that be half way?? |
|
|
iso9001
Joined: 02 Dec 2003 Posts: 262
|
|
Posted: Mon Dec 29, 2003 9:35 pm |
|
|
Yea, but I tried a VAST range of numbers. Same result.
I see that it is a REALLY bad idea to try and test it sending in half since that is the default state.... Ha...
Thanks Though,
New Code:
Code: | setup_spi(spi_master | spi_l_to_h | spi_clk_div_16 );
delay_us(20);
output_low(PIN_C1);
spi_write(17);
spi_write(63);
output_high(PIN_C1);
|
|
|
|
Peter Guest
|
|
Posted: Mon Dec 29, 2003 10:38 pm |
|
|
hmmm...
I just looked at the MCO41XXX/42XXX datashaeet and it looks like you are doin things right.
OTH, there is always a scope and look at som wiggly signals triggered by CS.
Sorry, but that's all I can up right now - good luck |
|
|
Peter Guest
|
|
Posted: Mon Dec 29, 2003 10:39 pm |
|
|
forgot one thing. Is your Reset Pin active by any chance???? |
|
|
iso9001
Joined: 02 Dec 2003 Posts: 262
|
|
Posted: Tue Dec 30, 2003 12:08 am |
|
|
I dont have access to a scope
I dont think I have a reset pin either. I have
Power / Ground / CS / Clock / Data-In / A / B / W
Thats all 8. I bet the 420x has a reset pin though. I dont think SPI needs pullups or anything. And I know the Pot works cause its going to 4.400k when powered up...
I'm stumped. Is the code ok ? |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Tue Dec 30, 2003 12:43 am |
|
|
Try this out.
Code: |
#include <16F872.h>
#fuses RC,NOLVP,NOWDT,NOPROTECT, PUT, NOBROWNOUT
#use delay(clock=1000000)
#define SPI_CS PIN_C1
#define SPI_CLOCK PIN_C3
#define SPI_DO PIN_C5
void write_spi(byte* data)
{
byte i;
// Select the device
output_low(SPI_CS);
for(i=1;i<=16;++i)
{
output_low(SPI_CLOCK);
if((*(data+1) & 0x80)==0)
output_low(SPI_DO);
else
output_high(SPI_DO);
output_high(SPI_CLOCK);
shift_left(data,2,0);
}
output_high(SPI_CS);
}
void main()
{
byte test[2];
output_high(SPI_CLOCK);
output_high(SPI_CS);
// load the command
test[1] = 0x11;
// load the data
test[0] = 63;
// write to the pot
write_spi(test);
while(1)
{
}
}
|
|
|
|
iso9001
Joined: 02 Dec 2003 Posts: 262
|
|
Posted: Tue Dec 30, 2003 12:55 am |
|
|
Mark,
A little complex there.... Why would I rewrite the CCS SPI Write function? (for what looks to be 16bit) Does the CCS one not work or somthing?
And why would this work over the CCS/hardware SPI ?
I dont really follow the bit shifting parts of your code, that stuff never really made sense to me. |
|
|
Ttelmah Guest
|
|
Posted: Tue Dec 30, 2003 6:41 am |
|
|
iso9001 wrote: | Oh, Nope... Hang on, that didnt work at all.
Arg.
Ok, here is my new code:
Code: |
setup_spi(spi_master | spi_l_to_h | spi_clk_div_16 );
delay_us(20);
output_low(PIN_C1);
spi_write(17);
spi_write(128);
output_high(PIN_C1);
//17 = 00 01 00 01 == XX command XX which pot to command
|
Thats all I got... anyone have advice?[/code] |
One obvious 'thought', is that the chip may not be responding, because it is allready selected, and thinks it has got a transaction partially completed. Hence try:
Code: |
setup_spi(spi_master | spi_l_to_h | spi_clk_div_16 );
output_high(PIN_C1);
//ensure that the CS line starts high
delay_us(20);
output_low(PIN_C1);
spi_write(17);
spi_write(128);
output_high(PIN_C1);
//17 = 00 01 00 01 == XX command XX which pot to command
|
Best Wishes |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Tue Dec 30, 2003 7:59 am |
|
|
Quote: |
A little complex there.... Why would I rewrite the CCS SPI Write function? (for what looks to be 16bit) Does the CCS one not work or somthing?
And why would this work over the CCS/hardware SPI ?
I dont really follow the bit shifting parts of your code, that stuff never really made sense to me.
|
Actually, it is pretty simple. Why rewrite them? Because you can't get it to work. Did you try it? It should be a pretty simple test. I am pretty sure it should work. If it doesn't, then there is probably something else wrong besides the code. |
|
|
Chas Guest
|
SPI Setup |
Posted: Tue Dec 30, 2003 8:02 am |
|
|
In checking the MCP41010 data sheet, it looks like they require SPI in modes 0,0 and 1,1. There is an old post which I cannot find on setting up the spi for these modes. Unfortunately, in the change from version 2.xxx to version 3.xxx of the compiler, CCS broke the spi setup functions. In the current version (3.xxx) the simple parameters spi_l_to_h and spi_h_to_l, setup the spi in either 0,1 or 1,0 which will not work. You will need to add the other parameter which is spi_xmit_l_to_h. If I am not mistaken, mode 0,0 needs spi_l_to_h and spi_xmit_l_to_h. Mode 1,1 needs spi_h_to_l and spi_xmit_l_to_h.
To make my life simpler, I created an spi_setup.h file that contains the following definitions:
#define SPI_MODE_0_0 0x4000
#define SPI_MODE_0_1 0x0000
#define SPI_MODE_1_0 0x0010
#define SPI_MODE_1_1 0x4010
Then I use the simple versions above to set up the spi:
setup_spi(spi_master | SPI_MODE_0_0 | spi_clk_div_16);
Try this and let us know if it works. |
|
|
iso9001
Joined: 02 Dec 2003 Posts: 262
|
|
Posted: Tue Dec 30, 2003 1:01 pm |
|
|
Well, I thought for certain the 0,0 would have been 'it'.
But I ran this:
Code: |
setup_spi(spi_master | 0x4000 | spi_clk_div_16 );
delay_us(20);
output_low(PIN_C1);
spi_write(17);
spi_write(21);
output_high(PIN_C1);
delay_ms(5);
|
I can verifiy that in the end, C1 is high. But thats about all. I noticed that something has changed though, the wiper is not going to half way like it should (i THINK it should anyway). If I DMM the B and W or B and A i get 8.75k everytime, A and W yield 89ohm, this is all whether PIC is present or not.
Ideas ? (shouldn'y the normal resistance be 5k and not 8.75k ???)
mark: No, I havn't tried it yet, first thing after lunch. I cant image that CCS works for everyone but me or for all SPI exept microchip stuff. |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Tue Dec 30, 2003 3:04 pm |
|
|
Maybe this will make more sense to ya. The other code was just CCS's modified 74595 driver.
Code: |
#include <16F872.h>
#fuses RC,NOLVP,NOWDT,NOPROTECT, PUT, NOBROWNOUT
#use delay(clock=1000000)
#define SPI_CS PIN_C1
#define SPI_CLOCK PIN_C3
#define SPI_DO PIN_C5
void write_spi(byte data)
{
byte i;
for(i=0; i<8; i++)
{
output_low(SPI_CLOCK);
if (bit_test(data,7))
output_high(SPI_DO);
else
output_low(SPI_DO);
output_high(SPI_CLOCK);
data <<= 1;
}
}
void main()
{
// Make sure these 2 lines start out high
output_high(SPI_CLOCK);
output_high(SPI_CS);
output_low(SPI_CS);
// write the command
write_spi(17);
// write the data
write_spi(63);
output_high(SPI_CS);
while(1)
{
}
}
|
Note these 2 lines:
Code: |
// Make sure these 2 lines start out high
output_high(SPI_CLOCK);
output_high(SPI_CS);
|
You should make sure that these 2 outputs start out as high. RJ already suggested the CS line but it doesn't look like in your last example that you are doing this. It is very important that it starts out high. Otherwise, the pot may see more than 16 clocks when it is selected which will abort the command (actually it just needs some multiple of 16 since they can be chained together). |
|
|
|
|
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
|