I'm trying to connect a max7301ANI port expander up to the pic16F737 as a part
of my senior project for college. So far everything has gone so smoothely up
to this point but I can't figure out why the 7301 doesn't seem to want to talk
to my uC. Here is how i Have it connected:
I also have the two grounds on the 7301 connected together. They are connected
to the ISET pin through a 40 ohm resistor and to the power pin through a 47 nF
cap as is reccomended on the data sheet.
I then have pins P16-P24 hooked to LED's through resistors to ground so that I
can see the them turn on when I successfully change some of the pins to outputs
and try to write values to them. I have not connected Dout on the 7301 because
write now I am only concerned with getting data to write to the 7301 and not
read from it.
I have slowed down the chip as much as possible and when I connect an led to my
chip select line I can see it blink. I also hooked up another LED to another
port that is initially on but turns off when the writes to the 7301 are
complete so that I could be sure I wasn't getting stuck in an infinite loop
when I was transmitting data and waiting for the BF flag to get set. It seems
to transmit the data fine.
My Code: I'm just pasting the code relevant to the SPI because I have a lot of
other non-relevant code that seems to work fine
;set P16-P19 to active high outputs
banksel PORTB
bcf PORTB, 6
movlw 0x0C ;address byte
call spi_transmit
movlw B'01010101' ;set the 4 ports to outputs active high
call spi_transmit
banksel PORTB
bsf PORTB, 6
; set P20-P23 to active high outputs
banksel PORTB
bcf PORTB, 6
movlw 0x0D ; address bytes
call spi_transmit
movlw B'01010101' ; set the 4 ports to outputs active high
call spi_transmit
banksel PORTB
bsf PORTB, 6
;Put some data on P16-P23 and watch some leds turn on
banksel PORTB
bcf PORTB, 6
movlw B'01010000' ; address byte
call spi_transmit
movlw B'10101010' ; write data to the desired ports
call spi_transmit
banksel PORTB
bsf PORTB, 6
;I call this funciton earlier on
;----------------------------------------------------------------------------
;initialize the SPI hardware
spi_init:
global spi_init
banksel TRISB
bcf TRISB, 6
banksel PORTB
bsf PORTB, 6
banksel TRISC
bcf TRISC, 3
bcf TRISC, 5
bsf TRISC, 4
banksel SSPSTAT
bcf SSPSTAT, SMP ;input data is sampled at the end of data output
bsf SSPSTAT, CKE ;transmit occurs on transition from active to idel clock state
banksel SSPCON
bsf SSPCON, CKP ;idle state fo sck is high
bcf SSPCON, 3 ;set sck to fosc/4
bcf SSPCON, 2
bcf SSPCON, 1
bcf SSPCON, 0
bsf SSPCON, SSPEN ;enable spi
return
Also, when Im testing my code it gets stuck in the loop where I poll for the BF
flag. Is there a way to tell the debugger I want to go out of the loop? I
appreciate everyone's time a lot.
The only way you would be able to get out of that loop in the simulator
(that is the debugger that you're referring to?) is by stimulating the
register that contains the BF flag and actually manually setting the flag (
to a logical 1 in your case!). This can be achieved by 'editing' the value
in the register after stepping into the loop. You can edit the registers
value in the watch-window ( View --> Watch), or any other window that
enables you to see what's momentarily in that particular register.
Also: where you use: movf SSPBUF, 0 instead of the '0', you can use
'W', and instead of '1', you can use 'F'. It's a little more clear that way!
Have you looked at your SDO line and SCK on a scope (together) to make
sure that data is being passed on the right edge and that you are sending
what you think you're sending? I've used the I2C version of this chip and
initially I wasn't pausing long enough between commands sent to the io
expander which was causing some havoc.
I finally got it working. I guess you need to disable the "shutdown state" of
the max7301 before you can write to any of the pins as outputs. I somehow kept
reading over this in the data sheet.
I do still have one issue I never could resolve. When I finally got access to
an oscilloscope and looked at the signals I realized that my chip select wasn't
bouncing. At the time I was using pin B6 as the chip select pin (remember this
is on the PIC16F737). I eventually changed the chip select to be pin C0. I
went back and tried to make the chip select pin B6 and it still never would
work. The only thing special about that pin is it is used for programming the
chip but I don't see how that would distract it from being a general I/O.
> Hey Marc,
>
> Have you looked at your SDO line and SCK on a scope (together) to make
> sure that data is being passed on the right edge and that you are sending
> what you think you're sending? I've used the I2C version of this chip and
> initially I wasn't pausing long enough between commands sent to the io
> expander which was causing some havoc.
>
> James
> -