Hi all,
I am trying to write a PBP program to interface a PIC18F2520 to the MCP23S17 port expander (on the EasyPIC6 dev board).
If you don't know the Port Expander is an SPI device that adds two 8 bit ports. To configure it you send a command byte ($40) followed by the register address you wish to write to and the value you wish to write (e.g. to set portA as an output you write $00 to the IODIRA register). Then to write a value to the port you send the command byte followed by the register GPIOA address and the value you wish to write, e.g. $FF to turn the port all ON.
If you didn't understand the above don't worry - its not particularly important in understanding my problem.
My program simply sets up the port expander by sending the appropriate bytes (see above) using the shiftout command and then runs a loop that increments a variable each cycle and writes it to the two ports on the port expander (which will just light some LEDs to give a visual indication that the port expander is working). The loop runs every 100ms and toggles PORTB.0 (an LED) on each cycle so I know that the program is running.
I compiled the code and simulated it in ISIS and it works fine. However when I load it onto the PIC it does not work - the PORTB.0 LED flashes so the program is running, however the Port Expander LEDs do nothing. I put an oscilloscope on the nCS, SCLK and SDO lines to check that the data is being sent by the pic as it is in the simulation. I can see the nCS pin toggling as it should, however there is nothing on the SCLK and SDO lines. This means that despite the simulation running correctly the PIC is just not shifting the data out therefore the port expander is not anything.
As an experiment I toggles the SCLK line manually inside the loop (just once up and once down) and put the scope on it. I can see this behaviour on the scope so I know that the pin is setup correctly as an output, it just isnt being driven by the shiftout command.
I also tried shiftout on two other pins but got nothing on them either so perhaps its a setup problem?
It seems odd that it simulates fine but does not function in reality, although I do not truly trust the ISIS simulation as I have seen it do very odd things in the past.
If anyone has any thoughts on this please let me know as its beginning to drive me insane.
Code:Include "modedefs.bas" asm __CONFIG _CONFIG1H, _OSC_XT_1H & _FCMEN_OFF_1H & _IESO_OFF_1H __CONFIG _CONFIG2L, _PWRT_ON_2L & _BOREN_OFF_2L & _BORV_2_2L __CONFIG _CONFIG2H, _WDT_OFF_2H __CONFIG _CONFIG3H, _MCLRE_ON_3H & _LPT1OSC_OFF_3H & _PBADEN_OFF_3H __CONFIG _CONFIG4L, _STVREN_ON_4L endasm ' ============================================================================== ' DEFINES ' ============================================================================== DEFINE OSC 4 TRISA = 0 TRISC = 0 TRISB = 0 PORTA = 0 PORTC = 0 PORTB = 0 ' ============================================================================== ' ADC Config ' ============================================================================== ADCON0.0 = 0 'Disable ADC Module ADCON1 = %00001111 'Set PORTA to digital ' ============================================================================== ' Constants ' ============================================================================== CONTROL_BYTE con $40 ' write operation to device address $00 IOCON con $0A IODIRA CON $00 IODIRB CON $01 GPIOA CON $14 GPIOB con $15 ' ============================================================================== ' Pin Definitions ' ============================================================================== SCLK var PORTC.3 SDI var PORTC.4 SDO var PORTC.5 nCS var PORTA.2 nRST var PORTA.3 ' ============================================================================== ' Variables ' ============================================================================== Data_Byte var byte Register var byte LCD_Cmd var bit ' denotes whether the data sent to the LCD is a command or ' a character. i.e. determines the state of the RS pin LCD_Byte var byte ' the byte to send to the LCD (character or command) gosub PE_INIT pause 250 REGISTER = GPIOA DATA_BYTE = $00 loop: pause 100 REGISTER = GPIOA 'DATA_BYTE = $00 gosub SEND_PE_BYTE REGISTER = GPIOB ' DATA_BYTE = $00 gosub SEND_PE_BYTE toggle PORTB.0 DATA_BYTE = DATA_BYTE + 1 goto loop: PE_INIT: nRST = 0 ' reset the port expander pause 10 nRST = 1 REGISTER = IOCON DATA_BYTE = %00100000 gosub SEND_PE_BYTE ' setup IOCON for Bank 0 non-sequetial operation REGISTER = IODIRA DATA_BYTE = $00 gosub SEND_PE_BYTE REGISTER = IODIRB DATA_BYTE = $00 gosub SEND_PE_BYTE ' set PORTB as output return SEND_PE_BYTE: nCS = 0 ' enable PE Shiftout SDO, SCLK, MSBFIRST, [CONTROL_BYTE,REGISTER,DATA_BYTE] nCS = 1 ' pause 10 return





Bookmarks