|
|
View previous topic :: View next topic |
Author |
Message |
edbfmi1
Joined: 18 Jul 2006 Posts: 94
|
|
Posted: Fri Mar 23, 2018 2:22 pm |
|
|
Sorry PCM programmer I didn't see your request.
I am just using 8 seven segment displays that are being driven by the MAX7219CWG+ The part is a LITEON LSHD-5503 Below is the link to the display.
https://media.digikey.com/pdf/data%20sheets/lite-on%20pdfs/lshd-5503.pdf
Last edited by edbfmi1 on Fri Mar 23, 2018 2:34 pm; edited 1 time in total |
|
|
edbfmi1
Joined: 18 Jul 2006 Posts: 94
|
|
Posted: Fri Mar 23, 2018 2:29 pm |
|
|
More weirdness.
When I have the #use spi setups as follows Code: |
#use spi(SPI1, MASTER, MODE=0, bits=32, stream=MAX31855)
#use spi(SPI1, MASTER, MODE=0, bits=32, stream=MAX7219) |
I can only set a breakpoint on the first #use spi
When I use the following I can set a breakpoint on either one?
Code: |
#use spi(SPI1, MASTER, MODE=0, bits=32, stream=MAX31855)
#use spi(SPI1, MASTER, MODE=0, bits=8, stream=MAX7219) |
|
|
|
edbfmi1
Joined: 18 Jul 2006 Posts: 94
|
|
Posted: Fri Mar 23, 2018 2:40 pm |
|
|
Since I originally had the spi configured using SETUP_SPI when I started this thread would it be worth trying to go back to that? I only switched because the data sheet was misleading and looked like I had 2 different modes but after reviewing the timing diagrams they are both mode 0. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19249
|
|
Posted: Sat Mar 24, 2018 11:26 am |
|
|
edbfmi1 wrote: | Since I originally had the spi configured using SETUP_SPI when I started this thread would it be worth trying to go back to that? I only switched because the data sheet was misleading and looked like I had 2 different modes but after reviewing the timing diagrams they are both mode 0. |
No.
The fundamental problem is because the two different clock modes have different levels on the lines. You have to force the actual bus to switch before you select the second chip.
Have you tried the version I posted?.
If you don't need to change modes, then you don't need to use two streams. Just use the spi_speed command. However it is critical that you read the return from the spi_xfer command. This ensures the byte has completed clocking oout. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9127 Location: Greensville,Ontario
|
|
Posted: Sat Mar 24, 2018 12:01 pm |
|
|
simplify your code and life...just use ONE speed, say 100K, at least for initial test purposes. Usually 'temperature stuff' is snail slow and displays only have to be say 100 Hz for us humans to see OK.
Since you can use one mode for both peripherals, that makes coding easier.
It almost sounds like you need to start over, usng the two working sections of code, get the display working 100%, then the temperature, then merge the two and see what happens. |
|
|
edbfmi1
Joined: 18 Jul 2006 Posts: 94
|
|
Posted: Sat Mar 24, 2018 12:34 pm |
|
|
I came in Saturday and this is what I found.
When I remarked out all the lines in the subroutine for MAX31855 temperature IC so only the Display IC would be written to as follows.
Code: | void readMAX()
{
delay_us(2);
// int32 MAXread;
// spi_xfer(MAX31855,0,32); //switches the stream to mode 0
// delay_us(2);
// output_low(TEMP);
// delay_us(2);
// MAXread=spi_xfer(MAX31855,0,32);
// delay_us(2);
// output_high(TEMP);
// delay_us(2);
// TempByte3=MAXread>>24 & 0xff;
// TempByte2=MAXread>>16 & 0xff;
// TempByte1=MAXread>>8 & 0xff;
// TempByte0=MAXread & 0xff;
} |
and remark out the #use spi that refers to the MAX31855
Code: | //#use spi(SPI1, MASTER, MODE=0, bits=32, stream=MAX31855)
#use spi(SPI1, MASTER, MODE=0, bits=32, stream=MAX7219) |
and looked at the chip selects and data lines for the two ICs with my scope, only the chip select and data lines for the MAX7219 display IC are active.
This is as expected,
but when I do the same thing for the MAX7219 display driver IC so only the MAX31855 will be read as follows
Code: | void maxsend() // send routine for max7219 to update display
{
delay_us(2);
// spi_xfer(MAX7219,0,8); //switches the stream to mode 0
// delay_us(2);
// output_low(DISP);
// delay_us(2);
// spi_xfer(MAX7219,address,8); //send address
// delay_us(2);
// spi_xfer(MAX7219,data,8); //send data
// delay_us(2);
// output_high(DISP);
// delay_us(2);
} |
and remark out the #use spi that refers to the MAX7219 display driver
Code: |
#use spi(SPI1, MASTER, MODE=0, bits=32, stream=MAX31855)
// #use spi(SPI1, MASTER, MODE=0, bits=32, stream=MAX7219)
|
I get the chip select and data on for the MAX31855 temperature IC as expected but I also get signal on the data line for the MAX7219 (SPI_DO Pin) and get nothing on the chip select for the Display IC.
Since I am not doing anything to the SPI_DO pin at this time I am confused.
The final thing I tried since both ICs are operating on the same mode was to only have one #USE SPI and then kept them both at 8 bits. I then took the information from the MAX31855 in four successive spi_xfer and the problem went away.
This was my final code.
Code: |
#use spi(SPI1, MASTER, MODE=0, bits=32, stream=SPI_PORT1)
|
Code: |
/**********************************************************************************
// Send Update Display, MAX7219
**********************************************************************************/
void maxsend() // send routine for max7219 to update display
{
delay_us(2);
delay_us(2);
output_low(DISP);
delay_us(2);
spi_xfer(SPI_PORT1,address,8); //send address
delay_us(2);
spi_xfer(SPI_PORT1,data,8); //send data
delay_us(2);
output_high(DISP);
delay_us(2);
}
/*******************************************************************************
//Read SPI data From MAX31855
*******************************************************************************/
void readMAX()
{
delay_us(2);
int32 MAXread;
output_low(BURNER_TEMP);
delay_us(2);
TempByte3=spi_xfer(SPI_PORT1,0,8);
TempByte2=spi_xfer(SPI_PORT1,0,8);
TempByte1=spi_xfer(SPI_PORT1,0,8);
TempByte0=spi_xfer(SPI_PORT1,0,8);
delay_us(2);
output_high(BURNER_TEMP);
delay_us(2);
}
|
When I look at the Chip selects and Data doing it this way the data is only active for the corresponding chip select.
That is when chip select for the MAX31855 is selectived data is only seen on the SPI_IN pin
and when the chip select for the MAX7219 is selected data is only seen on the SPI_OUT pin
Maybe someone smarter than me can figure out why this happens but for now it is doing what I need.
Thanks for all the help everyone. If anyone has any ideas why this worked I am all ears. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9127 Location: Greensville,Ontario
|
|
Posted: Sat Mar 24, 2018 2:04 pm |
|
|
Just because you don't send data out by the SPI DO line doesn't necesarily mean the SPI peripheral doesn't, at least to my old school thinking.
SPI was originally a method of 'clocking' data in and data out at the same time, send one bit out, get one in,clk, send another out, get another in. It's a form of 'full duplex' mode of serial communications.
I don't know if the SPI peripheral in a PIC will send 'zero' as bits if you're doing a 'receive only' form of SPI. What I can see is the SPI xmt buffer having random bits set and transmitting that.
That being said the 'chip select' lines _should_ disable an SPI device but....it sounds like that isn't happening, at least not properly. Perhaps you need to 'reset' the SPI bus and pause a bit between accessing the 2 devices?
You may need to load 'dummy data' into the xmt buffer when you want to receive data from the temp. sensor.
Hopefully someone very,very familiar with the actual silicon inside the PIC will reply.
Jay |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19249
|
|
Posted: Sat Mar 24, 2018 3:09 pm |
|
|
You need to understand SPI.
SPI is always full duplex. A byte is sent at the same time as one is received.
If you perform the instruction:
spi_xfer(SPI_PORT1,data,8); //send data
A byte is loaded into the SPI buffer and the command returns _immediately_. The hardware starts clocking the data out at the specified rate.
At the same time the chip clocks in the data being received. May be real, or may just be garbage.
This is all going on while you perform subsequent instructions.
If instead you perform:
val=spi_xfer(SPI_PORT1,data,8); //send data
This loads the data and waits for the byte to sent and be received.
This is why I told you earlier to use a dummy variable and load this.
The key point is that if you do:
spi_xfer(SPI_PORT1,data,8); //send data
and then raise the CS, the CS line will be going up _before_ the byte has actually sent.
The delays added here are rescuing you, but basically you need to read the return, even from commands that are not actually returning anything. This then ensures that the value has completed sending.
The spi buffer will contain the last byte sent or received, if you trigger a receive only, so this is what will be sent in this case. |
|
|
edbfmi1
Joined: 18 Jul 2006 Posts: 94
|
|
Posted: Sat Mar 24, 2018 3:10 pm |
|
|
Thank Jay,
I am not too familiar with the SPI protocol.
I did notice on the data sheet for the MAX7219 that it says the MAX7221 is a fully SPI compatible.
The MAX7219 has a “Load” instead of “Chip Select”. The data sheet says
Quote: | For the MAX7219, serial data at DIN, sent in 16-bit
packets, is shifted into the internal 16-bit shift register
with each rising edge of CLK regardless of the state of
LOAD. For the MAX7221, CS must be low to clock data
in or out. The data is then latched into either the digit or
control registers on the rising edge of LOAD/CS.
LOAD/CS must go high concurrently with or after the
16th rising clock edge, but before the next rising clock
edge or data will be lost. |
I need to look into this a little more to see if this is what was causing the issues.
Thanks again for all the help! |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9127 Location: Greensville,Ontario
|
|
Posted: Sat Mar 24, 2018 3:48 pm |
|
|
Do as Mr. T. tells you
IE:
val=spi_xfer(SPI_PORT1,data,8); //send data
val is just a 'dummy' data variable, you never use data in it.
this will get rid of the nasty timing problem and the 'no display' on the MAX7221 due to the data being lost.
also, just for the sake of 'clarity'..
this
output_high(TEMP);
perhaps should be changed to
output_high(TEMP_CS); // chip select of temperature device
'TEMP' to most means a 'TEMPorary' variable, not an important item like 'chip select' !
These days compilers/lauguages allow you lots of space to call variables self descriptive names unlike the 'good old days' where we were only allow 2 characters for a variable name. |
|
|
|
|
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
|