View previous topic :: View next topic |
Author |
Message |
hisham.i
Joined: 22 Aug 2010 Posts: 43
|
SPI_WRITE function problem |
Posted: Wed Nov 03, 2010 2:07 pm |
|
|
Hello
Am using max7219 to drive 7dig 7seg display.
My problem with spi_write function.
When i set the digit i want to send the data for, i tried to send data in 2 forms:
1- First form is to write a constant directly to spi_write function
like: spi_write(0x03);
in this case the dig displays number 3, which is correct.
2- In the second case i create an int data;
then i gave data a value, i sent the data using spi_write(data);
but the display always shows me a 0 value whatever the value of data is.
I searched for the parameter the spi_write function should take and i found that it is an 8 bit int, so i don't know where the problem is.
Thanks for reply. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Nov 03, 2010 2:24 pm |
|
|
Post a short, compilable test program that shows the two methods
of using spi_write().
Here's an example of a short test program:
http://www.ccsinfo.com/forum/viewtopic.php?t=42446&start=5
Note how it has the #include for the PIC, #fuses, #use delay, main(),
setup_spi(), spi_write(), and very little else. There is no useless Wizard
code or anything else. It only demonstrates SPI writes.
Make a similar short program that shows your problem. It must compile
with no errors.
Also post your compiler version. |
|
|
hisham.i
Joined: 22 Aug 2010 Posts: 43
|
|
Posted: Wed Nov 03, 2010 2:35 pm |
|
|
This is my program :
Code: |
#include <16f877a.h>
#use delay(clock = 4MHZ)
#fuses XT,NOWDT
setup_7219()
{
output_low(PIN_B0);
spi_write(0x0F); //wirte to display test register
spi_write(0x00);
output_high(PIN_B0);
output_low(PIN_B0);
spi_write(0x09); //write to decode mode register
spi_write(0xFF);
output_high(PIN_B0);
output_low(PIN_B0);
spi_write(0x0A); //wirte to intensity register
spi_write(0x0D);
output_high(PIN_B0);
output_low(PIN_B0);
spi_write(0x0C); //wirte to shut down register
spi_write(0x01);
output_high(PIN_B0);
output_low(PIN_B0);
spi_write(0x0B); //wirte to scan limit register
spi_write(0x00);
output_high(PIN_B0);
}
main()
{
int data = 20;
int i=0;
setup_spi(SPI_MASTER);
setup_7219();
while(1)
{
//Method 1
output_low(PIN_B0);
spi_write(0x01); //wirte to Dig 0 register
spi_write(0x04); //Data written to Dig 0
output_high(PIN_B0);
delay_ms(500);
//Method 2
output_low(PIN_B0);
spi_write(0x01); //wirte to Dig 0 register
spi_write(data); //Data written to Dig 0
output_high(PIN_B0);
delay_ms(500);
}
} |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Nov 03, 2010 3:18 pm |
|
|
Quote: | setup_spi(SPI_MASTER); |
This statement is missing the SPI mode setting, and the SPI clock speed.
Because of this, the above statement defaults to SPI Mode 1 and
SPI_CLK_DIV_4.
The Max7219 uses SPI Mode 0, so your code will not work correctly
because you have it set for Mode 1. The clock divisor of 4 with
your 4 MHz crystal, will give you an SPI clock of 1 MHz. The Max7219
data sheet says the maximum clock speed is 10 MHz, so there is no
problem with your clock speed.
But your setup_spi() statement should be like this:
Code: |
#define SPI_MODE_0 (SPI_L_TO_H | SPI_XMIT_L_TO_H)
#define SPI_MODE_1 (SPI_L_TO_H)
#define SPI_MODE_2 (SPI_H_TO_L)
#define SPI_MODE_3 (SPI_H_TO_L | SPI_XMIT_L_TO_H)
void main()
{
setup_spi(SPI_MASTER | SPI_MODE_0 | SPI_CLK_DIV_4); |
|
|
|
hisham.i
Joined: 22 Aug 2010 Posts: 43
|
|
Posted: Thu Nov 04, 2010 5:15 am |
|
|
I tried the code you send but i faced the same problem, when i write:
int data=20;
spi_write(data);
The 7 seg shows number 0! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Nov 04, 2010 12:07 pm |
|
|
What is your compiler version ?
I compiled the following test program with vs. 4.114 and ran it on a
PicDem2-Plus board. I see groups of 8 pulses on pin C3. This is SCLK.
I see groups of other pulses on pin C5. This is the SDO pin. It's working.
Try this program. Look at the signals with an oscilloscope.
Code: |
#include <16F877A.H>
#fuses XT, NOWDT, BROWNOUT, PUT, NOLVP
#use delay(clock=4000000)
#define SPI_MODE_0 (SPI_L_TO_H | SPI_XMIT_L_TO_H)
#define SPI_MODE_1 (SPI_L_TO_H)
#define SPI_MODE_2 (SPI_H_TO_L)
#define SPI_MODE_3 (SPI_H_TO_L | SPI_XMIT_L_TO_H)
//=========================================
void main()
{
int8 data = 20;
setup_spi(SPI_MASTER | SPI_MODE_0 | SPI_CLK_DIV_4);
while(1)
{
spi_write(data);
delay_us(10);
}
} |
|
|
|
hisham.i
Joined: 22 Aug 2010 Posts: 43
|
|
Posted: Fri Nov 05, 2010 1:08 am |
|
|
My compiler version is 4.0.0.206;
The problem is solved, i didn't put a delay of 10us after the spi_write(data) function, when i used this delay the code works properly and the 7 seg display gives the right result.
Thank you PCM programmer :D |
|
|
|