Jump to content

Recommended Posts

I'm trying to operate an 18F2321 as an SPI slave, but I'm not really sure where I'm going wrong:

 

void main()
{
set_bit(trisa, 5);
set_bit(trisc, 3);
while (!test_bit(portc,3));
sspstat = 0x40;
sspcon1 = 0x24;
pie1 |= 0x80;
pir1 = 0;
// Enable Peripheral Interrupt Bit
intcon.PEIE	= 1;
// Enable Global Interrupt Bit
intcon.GIE	= 1;

StartDisplayLoop();
}

 

void interrupt(void)
{
char tmp;
if (test_bit(pir1, SSPIF))
{
	clear_bit(pir1, SSPIF);
	tmp = sspbuf;
	Bar0 = tmp;
}
}

 

StartDisplayLoop() just takes the data for Bar0 and spits it out on a display. That part works. The problem is that when I send some data, nothing happens. I'm probably just not setting it up correctly, I've never used a PIC in SPI Slave mode before, and I'm not quite sure what's going on.

Share this post


Link to post
Share on other sites

Not sure if you have the correct manual for this chip :(

 

You need to set pei1.SSPIE to enable the interrupts.

RC5 has to be set for an output (SDO).

Are you pulling the SS/ pin low ?

 

There may be more, but this is a start.

 

Cheers

 

Reynard

Share this post


Link to post
Share on other sites

Just to elaborate a bit clearer,

 

First you control the SlaveSelect(SS) line from the master, then the master controls the clock line.

After that, data is transfered in a normal fashion, but keep in mind only one device can control the clock line at a time and only the master controls SS.

 

Just to question something in the fog of my brain, isn't there an issue with using the bit functions in an interrupt? I've been away from PIC programming for a few months so some things are a bit rusty.

Edited by emte

Share this post


Link to post
Share on other sites

I've got it sort of working:

 

	set_bit(trisa, 5);
set_bit(trisc, 3);
set_bit(trisc, 4);
while (!test_bit(portc,3));
sspstat = 0x40;
sspcon1 = 0x24;
pie1 |= 0x08;
pir1 = 0;
intcon.PEIE	= 1;
intcon.GIE	= 1;

 

is my new main(). The interrupt routine stays the same. I was setting PIE1 wrong.

 

Anyway, my new problem is that the interrupt is ocurring whether or not SS for this particular little chip is pulled low. Basically, I have it set so that I push a button on the master, and it sends a signal out to this slave, which works. But I also have another button which sends something to another slave....This 18f2321's interrupt is being thrown when that happens.

 

Any idea why that would be happening? I've confirmed that the SS line is staying high the entire time, but the interrupt is still being thrown.

 

It's acting like SSPCON1 is set to 0x25, disabling the need for the SS pin.

Edited by Heimdall

Share this post


Link to post
Share on other sites

Have you tried configuring sspcon1 = 0x04 before enabling the serial port sspcon1.SSPEN = 1;

 

The chip may not like configuring and enabling at the same time. They can be funny that way.

 

You still do not have SDO pin set for output.

 

Cheers

 

Reynard

Share this post


Link to post
Share on other sites

On reset, aren't pins set to output by default?

 

Anyway, I tried this:

 

	set_bit(trisa, 5);
clear_bit(trisc, 5);
set_bit(trisc, 3);
set_bit(trisc, 4);
while (!test_bit(portc,3));
sspstat = 0x40;
sspcon1 = 0x04;
pie1 |= 0x08;
pir1 = 0;
intcon.PEIE	= 1;
intcon.GIE	= 1;
sspcon1.SSPEN = 1;

 

No change. It does the exact same thing.

Share this post


Link to post
Share on other sites
Anyway, my new problem is that the interrupt is ocurring whether or not SS for this particular little chip is pulled low. Basically, I have it set so that I push a button on the master, and it sends a signal out to this slave, which works. But I also have another button which sends something to another slave....This 18f2321's interrupt is being thrown when that happens.

 

Any idea why that would be happening? I've confirmed that the SS line is staying high the entire time, but the interrupt is still being thrown.

 

It's acting like SSPCON1 is set to 0x25, disabling the need for the SS pin.

 

We would have to see your interrupt routine, it could be as simple as not detecting which slave or just a line outside your loop.

Share this post


Link to post
Share on other sites

The interrupt routine is the same as in the first post:

 

void interrupt(void)
{
char tmp;
if (test_bit(pir1, SSPIF))
{
	clear_bit(pir1, SSPIF);
	tmp = sspbuf;
	Bar0 = tmp;
}
}

 

I haven't made any changes to it.

 

Shouldn't the SSPIF interrupt only ever fire when SS is pulled low for this chip?

Edited by Heimdall

Share this post


Link to post
Share on other sites
The interrupt routine is the same as in the first post:

 

void interrupt(void)
{
char tmp;
if (test_bit(pir1, SSPIF))
{
	clear_bit(pir1, SSPIF);
	tmp = sspbuf;
	Bar0 = tmp;
}
}

 

I haven't made any changes to it.

 

Shouldn't the SSPIF interrupt only ever fire when SS is pulled low for this chip?

 

The SSPIF interrupt will trip for any SSPIF event, you need a second flag to detect which slave you want to deal with.

Something like:

if ((test_bit(pir1, SSPIF))&&_slaveOne)
.
.
else /* for all other slaves */
{
clear_bit(pir1, SSPIF); /* clear for second slave */
tmp = sspbuf;			 /* empty buffer to avoid overflow */
}

 

 

Oh and also related, some chips have multiple slave type settings, would have to check the datasheet though.

Edited by emte

Share this post


Link to post
Share on other sites

Wait. I'm confused.

 

The interrupt routine I've posted is on the slave, not the master. I'm waiting for the master to send a command. In this particular instance the slave doesn't send any data back to the master yet, I haven't gotten that far. So shouldn't it only be firing when SS is pulled low? I didn't think I'd have to check the SS line, because by the time SSBUF is filled, the SS line could already be pulled high again, right?

 

Anyway, I've set the right slave mode with the sspcon1 = 0x04. That's slave with the SS pin enabled.

Share this post


Link to post
Share on other sites

Could be used either way, but yes I was thinking on the master.

 

Out of curiosity are you using the serial port on the slave? Since RC6 is both /SS and TX...

And I also do not see you setting RC6 as an input...

Share this post


Link to post
Share on other sites

I put this code on an 18F2321:

 

#include <system.h>
#pragma CLOCK_FREQ 1000000
#pragma DATA _CONFIG1H, _OSC_INTIO2_1H
#pragma DATA _CONFIG2H, _WDT_OFF_2H
#pragma DATA _CONFIG3H, _MCLRE_OFF_3H & _PBADEN_DIG_3H & _LPT1OSC_OFF_3H
#pragma DATA _CONFIG4L, _STVREN_ON_4L & _LVP_ON_4L
#pragma DATA _CONFIG5L, _CP0_OFF_5L & _CP1_OFF_5L
#pragma DATA _CONFIG5H, _CPB_OFF_5H & _CPD_OFF_5H
#pragma DATA _CONFIG6L, _WRT0_OFF_6L & _WRT1_OFF_6L
#pragma DATA _CONFIG6H, _WRTB_OFF_6H & _WRTD_OFF_6H
#pragma DATA _CONFIG7L, _EBTR0_OFF_7L & _EBTR1_OFF_7L
#pragma DATA _CONFIG7H, _EBTRB_OFF_7H

void interrupt(void)
{
if (test_bit(pir1,SSPIF))
{
	clear_bit(pir1,SSPIF);
}
}

void main()
{
set_bit(trisa, 5);
clear_bit(trisc, 5);
set_bit(trisc, 3);
set_bit(trisc, 4);
sspstat = 0x40;
sspcon1 = 0x04;
pie1 |= 0x08;
pir1 = 0;
intcon.PEIE	= 1;
intcon.GIE	= 1;
sspcon1.SSPEN = 1;

while (1);	
}

 

And put it on a breadboard with nothing but: Power to the chip, SS pulled high, and SCK pulled low, and an LED with the anode on 5V, and the cathode on SDO.

 

The LED is turned on, despite the fact that I'm pretty sure SDO should be floating.

Edited by Heimdall

Share this post


Link to post
Share on other sites

On reset ALL ports are inputs (TRISX = 0xff).

 

Also ALL adc channels are enabled. You will have to set adcon1 = 0x0f if you are not using any analogue inputs.

The SS/ is on AN4 (RA5) so maybe causing some problems.

 

Cheers

 

Reynard

Edited by Reynard

Share this post


Link to post
Share on other sites

Thanks. ADCON1 did the trick.

 

The chip seems to be glossing over some commands (It could be the cable I'm using. It's about 2 feet long), and I have to figure out how to recieve multiple bytes, send bytes, etc. But at least it's working now.

Share this post


Link to post
Share on other sites

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×
×
  • Create New...