PDA

View Full Version : SPI hardware communication issue



Lestat
- 25th February 2018, 22:18
Hello,

Can I have some guidance, I have written the code below to drive a set of LEDs attached to a SN74HC595, I am using a PIC16F1825 to drive the SN74HC595.

3 LEDs are attached to the PIC16F1825 to provide feedback that the code is cycling as expected. These all function correctly.

The connection between the PIC and the shift register is as below:

PIC16F1825 SN74HC595
SDO PIN 3 RA4 PIN 14 SER
SDI PIN 9 RA5 Floating Not Connected
SCK PIN 10 RC0 PIN 11 SRCLK
Latch out PIN 11 RA2 PIN 12 RCLK

Common ground and 5V power supply is provided to both the PIC and shift register. no resistors or capacitors are connected between the PIC and the shift register.

LEDs are connected to the 9 outputs of the shift register.

The LEDs attached to the shift register stay lit, but do not cycle off, or make any of the expected patterns.

What am I doing wrong? Thank you in advance.



TxData var BYTE

define OSC 4
OSCCON = %01101010

HC_Data var PORTA.4 'SDO
HC_Clk var PORTC.0 'SCK
HC_latch var PORTA.2 'Digital output

LED_YELLOW var PORTA.1
LED_GREEN var PORTC.3
LED_RED var PORTA.0

TRISA = 0 'all digital outputs
PORTA = 0 'make all pins low
ANSELA = 0

TRISC = %00000010 'all digital outputs except port 1
PORTC = 0 'make all pins low
ANSELC = 0

APFCON0 = %01000000 'set SPI pin alternative
SSP1STAT = %00000000
SSP1CON1 = %01100010
SSP1CON3 = %00010000

txdata = 0 'SPI output byte

pause 200 'prove LED function
LED_YEllow = 1
LED_Green = 1
LED_red = 1
pause 200
LED_YEllow = 0
LED_Green = 0
LED_red = 0

Main: 'set up sequence of signals for output

LED_Yellow = 1

TxData = %10101010
Gosub Send_Data

TXDATA = %00000000
Gosub Send_Data

TxData = %10000000
Gosub Send_Data

TxData = %01000000
Gosub Send_Data

TxData = %00100000
Gosub Send_Data

LED_Yellow = 0

LED_gREEN = 1

TxData = %00010000
Gosub Send_Data

TxData = %00001000
Gosub Send_Data

TxData = %00000100
Gosub Send_Data

TXDATA = %00000010
Gosub Send_Data

TXDATA = %00000001
Gosub Send_Data

LED_GREEN = 0

goto main
end

Send_Data :
SSP1CON1.5 = 0
SSP1CON1.5 = 1
toggle LED_RED
PAUSEUS 10
SSP1BUF = TXDATA
PAUSEUS 10

HC_Latch=1
pauseus 5
HC_Latch=0

pause 750

return

richard
- 26th February 2018, 00:03
I don't think you have set the mssp port correctly and



PAUSEUS 10
SSP1BUF = TXDATA
PAUSEUS 10

is a dangerous way to wait for tx to complete before latching data

try this , it works perfectly for me

'************************************************* ***************
'* Name : SPI_74HC595.BAS *
'* Author : RICHARD *
'* Notice : *
'* : *
'* Date : 2/26/2018 *
'* Version : 1.0 *
'* Notes : *
'* : *
'************************************************* ***************
#CONFIG
__config _CONFIG1, _FOSC_INTOSC & _CP_OFF & _WDTE_OFF & _PWRTE_ON & _MCLRE_ON & _CLKOUTEN_OFF
__config _CONFIG2, _PLLEN_OFF & _LVP_OFF
#ENDCONFIG
TxData var BYTE
define OSC 4
OSCCON = %01101010
HC_Data var PORTA.4 'SDO
HC_Clk var PORTC.0 'SCK
HC_latch var LATA.2 'Digital output

LED_RED var LATA.1
TRISA = %11101001
PORTA = 0 'make all pins low
ANSELA = 0
TRISC = %11111110 'digital output C.0
PORTC = 0 'make all pins low
ANSELC = 0
APFCON0 = %01000000 'set SPI pin alternative
SSP1CON1=$22
SSP1STAT=$40
pause 200 'prove LED function
LED_red = 1
pause 200
LED_red = 0
Main: 'set up sequence of signals for output
TxData = 0
Gosub Send_Data

TXDATA = 1
Gosub Send_Data

TxData = 2
Gosub Send_Data

TxData = 4
Gosub Send_Data

TxData = 15
Gosub Send_Data

goto main

end
Send_Data :
LED_RED=!LED_RED
pir1.3=0
SSP1BUF = TXDATA
while ! pir1.3 :wend ;WAIT TILL TX COMPLETES
HC_Latch=0 ;LATCH IN NEW DATA
;@ NOP ; IF NEEDED FOR HIGHER CLOCK SPEEDS
HC_Latch=1
pause 500
return

Lestat
- 26th February 2018, 00:29
Hi Richard,

Thank you for the response, and thank you for the working example.

I shall review it tomorrow after work.

Just for reference what PIC did you use with that code?

Many thanks.

richard
- 26th February 2018, 00:36
same as you 16f1825

Lestat
- 26th February 2018, 09:15
I uploaded that code before work and can confirm it worked perfectly, now to study it when I get home and understand where my mistakes are in my original code.

Thank you for your help.

Lestat
- 26th February 2018, 21:50
My thanks goes to Richard for his help. But as a benefit to anybody else struggling with this, my corrections to my code are as follows:

I can confirm that CLKOUT configuration line was the largest issue, as this was blocking the output of the SDO1 therefore the signal to the SN74HC595 was not being sent.

I have taken Richard's advice to implement using the interrupt flag to check when the signal had been sent to the SN74HC595, though the my next step is to have this trigger as interrupt to control the latch while performing another routine.

Finally changed the clock edge bit such that the signal is sent on the correct edge of the clock signal for the serial data output so the data arrives at the SN74HC595 correctly.

This is my modified code based on my initial code:



#CONFIG
__config _CONFIG1, _CLKOUTEN_OFF
#ENDCONFIG

TxData var BYTE

define OSC 4
OSCCON = %01101010

HC_Data var PORTA.4 'SDO
HC_Clk var PORTC.0 'SCK
HC_latch var PORTA.2 'Digital output

LED_YELLOW var PORTA.1
LED_GREEN var PORTC.3
LED_RED var PORTA.0

SSP1IF VAR PIR1.3 'SPI interrupt flag

TRISA = 0 'all digital outputs
PORTA = 0 'make all pins low
ANSELA = 0

TRISC = %00000010 'all digital outputs except port 1
PORTC = 0 'make all pins low
ANSELC = 0

APFCON0 = %01000000 'set SPI pin alternative
SSP1STAT = %01000000
SSP1CON1 = %00100010

'prove LED function
LED_YEllow = 1
LED_Green = 1
LED_red = 1
pause 200
LED_YEllow = 0
LED_Green = 0
LED_red = 0

Main: 'set up sequence of signals for output

LED_Yellow = 1

TXDATA = %00000000
Gosub Send_Data
TxData = %10101010
Gosub Send_Data
TxData = %01010101
Gosub Send_Data
TXDATA = %00000000
Gosub Send_Data
TxData = %10000000
Gosub Send_Data
TxData = %01000000
Gosub Send_Data
TxData = %00100000
Gosub Send_Data

LED_Yellow = 0

LED_gREEN = 1

TxData = %00010000
Gosub Send_Data
TxData = %00001000
Gosub Send_Data
TxData = %00000100
Gosub Send_Data
TXDATA = %00000010
Gosub Send_Data
TXDATA = %00000001
Gosub Send_Data
TXDATA = %11111111
Gosub Send_Data

LED_GREEN = 0

goto main
end

Send_Data :
toggle LED_RED
SSP1IF = 0
SSP1BUF = TXDATA
while ! SSP1IF :wend ;WAIT TILL TX COMPLETES

HC_Latch=1
'could need a delay here on high processor speeds or no operation commands
HC_Latch=0

pause 500

return

tumbleweed
- 27th February 2018, 12:47
though the my next step is to have this trigger as interrupt to control the latch while performing another routine
It might be a lot less complicated to just increase the osc speed from 4MHz and clock the SPI faster. Running at 32MHz with SPICLK=8MHz it takes <2us to send out a byte... hardly worth the bother. At the speed you're running now it takes longer than that just to branch to an interrupt.

I'd also ditch the PAUSE in the Send_Data routine.