CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Bit Banging s/w for MCP23S08 SPI & PIC16F877

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
bassplayer



Joined: 24 Jun 2004
Posts: 6

View user's profile Send private message

Bit Banging s/w for MCP23S08 SPI & PIC16F877
PostPosted: Wed Jun 21, 2006 8:55 am     Reply with quote

I am starting to write software utilizing the Port I/O expander MCP23S08 using a bit bang SPI method. I usually do this until I see everything work then transfer over to the SPI functions of the PIC16F877. I'm having trouble though with the MCP23S08 not transmitting data to the 877. This must mean that I do not understand the fundamentals of the 23S08 yet. As such, I have a few general questions:

a) If I am going to transmit a Device Opcode from the 877 to the 23S08 do I send the MSB first? ie. 0100 0 A1 A0 R/W? Here is the bit bang code example with address A1=0 A0=0:

output_low(TDIP_CS); //
delay_us(50);

output_low(TDIP_CLK);
delay_us(50);
output_low(TDIP_DOUT); //opcode 0
delay_us(50);
output_high(TDIP_CLK);
delay_us(50);

output_low(TDIP_CLK);
delay_us(50);
output_high(TDIP_DOUT); // opcode 1
delay_us(50);
output_high(TDIP_CLK);
delay_us(50);

output_low(TDIP_CLK);
delay_us(50);
output_low(TDIP_DOUT); // opcode 0
delay_us(50);
output_low(TDIP_CLK);
delay_us(50);

output_low(TDIP_CLK);
delay_us(50);
output_low(TDIP_DOUT); // opcode 0
delay_us(50);
output_low(TDIP_CLK);
delay_us(50);


output_low(TDIP_CLK);
delay_us(50);
output_low(TDIP_DOUT); // opcode 0
delay_us(50);
output_low(TDIP_CLK);
delay_us(50);

output_low(TDIP_CLK);
delay_us(50);
output_low(TDIP_DOUT); //a1
delay_us(50);
output_high(TDIP_CLK);
delay_us(50);

output_low(TDIP_CLK);
delay_us(50);
output_low(TDIP_DOUT); //a0
delay_us(50);
output_high(TDIP_CLK);
delay_us(50);

output_low(TDIP_CLK);
delay_us(50);
output_high(TDIP_DOUT); //read bit = 1 write bit = 0
delay_us(50);
output_high(TDIP_CLK);
delay_us(50);



b) Can the CS signal stay low the entire transmission of the OPCODE byte, ADDRESS byte, and DATA byte?

c) I only want to use the MCP23S08 to read 8 DIP switches. Upon device RESET, the device automatically comes up configured for input. I attached an R/C filter to the RESET pin to allow the device to properly RESET. If my only use is to poll the GPIO Port via a bit bang method then I would assume I would send the OPCODE 0100 0001, ADDRESS BYTE 0000 1001, and then read the DATA BYTE from the MCP23S08? Or do I need to configure each register in software?

Thanks for the help!!! Smile
Ttelmah
Guest







PostPosted: Wed Jun 21, 2006 9:52 am     Reply with quote

First comment, use 1uSec (or preferably one _cycle_) delays, rather than 50Sec. The MCP23x08, supports clock rates up to 10MHz...
Second comment get into thinking about sending the data by shifting it out of a single byte, and not having to work 'bit by bit'.
Third, get the data sheet. It shows the data format, including which order the bits need to be sent, and how the CS line should be operated. Pages 26&27.
Something like:

Code:

void send_byte(int8 val_to_send) {
   int8 count;
   for (count=0;count<8;count++) {
      output_bit(TDIP_DOUT, shift_left(&val_to_send,1,0));
      output_high(TDIP_CLK);
      //If you are using 'fast_io', add one cycle of delay here
      output_low(TDIP_CLK);
   }
}

int8 get_byte(void) {
   int8 count;
   int8 val;
   for (count=0;count<8;count++) {
      output_high(TDIP_CLK);
      shift_left(&val,1,input_bit(TDIP_DIN));
      output_low(TDIP_CLK);
   }
   return(val);
}

main {
   ///Masses of other stuff here
   output_high(TDIP_CS);
   //Make sure CS goes _high_ when the PIC powers up & clock low
   output_low(TDIP_CLK);



   //Then to send a byte
   output_low(TDIP_CS);
   send_byte(0x41);
   send_byte(9);
   //Hint the GPIO port is register 9, not 0...
   val=read_byte();
   output_high(TDIP_CS);

   //masses more to do what you want...
}
bassplayer



Joined: 24 Jun 2004
Posts: 6

View user's profile Send private message

Much Thanks!! It all works great!!!
PostPosted: Wed Jun 21, 2006 10:22 am     Reply with quote

Couldn't ask for anything more. Thanks again!!!
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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