Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] PIC complete discussion for all

Status
Not open for further replies.
yes a bit clearer now.. I will just use PORTB instead in my future I/O programs...

A better plan would be to read from PORTB when you are sensing a change on the lines due to some attached device and to read from LATB when you are using the previously written value to LATB in some calculation, for example when you are walking a lit LED back and forth from pin 0 to pin 7 using a logical shift right then left on the previous value of LATB to obtain the next value in the sequence.

By the way this is also an example of why you would use a shadow register, to hold the previous value in stable storage and not relying on the pins of a PORT to act as storage and be unknowing altered by an external event.

Ciao
 
hi,

Im setting up my SPI protocol..this is my configuration.. pls check if I missed something in my initialization..


PHP:
void SPI_init()
{
	/* Enables serial port and configures SCK, SDO, SDI and SS as serial port pins */
	SSPCON1 = 0b00100000;

	/* Input data sampled at end of data output time
	   Transmit occurs on transition from active to Idle clock state */
	SSPSTAT = 0b11000000;

	TRISCbits.TRISC7 = 0; //SD0 set as output

	  
	TRISBbits.TRISB0 = 1; //SDI set as input

	TRISBbits.TRISB1 = 0; //SCK set as output 
	
	TRISCbits.TRISC2 = 0; //CS set as output

	
}


---------- Post added at 19:27 ---------- Previous post was at 19:26 ----------

I hope I understand correctly the datasheet... :grin:

---------- Post added at 19:28 ---------- Previous post was at 19:27 ----------

and next is I will write a function on how to send and received a byte..

---------- Post added at 19:41 ---------- Previous post was at 19:28 ----------

**broken link removed**

based on that line selected above..

"When SSPSR
receives a complete byte, it is transferred to SSPBUF
and the SSPIF interrupt is set."

how about if SSPSR only receives a single character 'a' then I think it will not make a complete byte.. (not sure.. Im confused) then the SSPIF will not be set when SSPBUF is empty.. right?

or it is not possible to transmit a data less than a byte?? hmm I dont know if my question is correct because I dont know how to raise this question properly..

---------- Post added at 19:43 ---------- Previous post was at 19:41 ----------

i need some sleep :)
 
Last edited:
Im stuck.. :-x I dont know what's next...

Im using the SPI debugger of proteus just to check what is going on in my SPI output (SDO).. but I dont understand what is happening the debugger what I see in only time and not the data I transmitted.. maybe I just dont know how to use the debugger... :grin:


I got stuck how do I manipulate the SSPSR and SSPBUF..hmm

let say for example I want to transmit data then I will store is first to SSPBUF then transfer it to my SDO pin using SSPSR. right?

and for receiving data, my SDI pin receives data from physical world then store it to SSPSR then later will be transmitted to the SSPBUF.. right? hmmmm just want to clarify the process.. correct me If Im wrong..
 
Last edited:

Have you implemented SPI on the 16F877A yet?

The 16F877A shares quite a bit of similarity with your 16F628, I believe this was the PIC you were originally using in your physical designs.

Configuring and implementing a new feature, first on a known MCU, will great simplify your understanding of the correct procedures of configuring it.

Once you have successfully implemented SPI on the 16F877A, then migrate it over to the relatively unfamiliar PIC 18F4550.

Attached is a very good example of implementing SPI on the 16F87XA family of PICs. Examine the spi.h and spi.c files, you'll notice similarities in the example code's initialization of the SPI bus and your snippet above. Unfortunately, the example makes use of a LTC2404, which I believe Proteus does not have a model. However, you should be able to select a component with a SPI interface, download its datasheet and swap it out in the simulation. This will allow you to simulate the SPI interface with a known physical component and see your results.

Let me know what you think, about my suggestion.

Ciao
 

Attachments

  • PIC_Hi-Tech_C_example_SPI_Linear_Tech_LTC2404_24bit_AD.zip
    6.2 KB · Views: 78
Besides, once you understand the basics, one of the primary reasons for using a compiler like the Hi-Tech C, is to take advantage of its available libraries. Such as the SPI library which will greatly simplify your implementation of the SPI interface in your app.

No more manually setting registers, just:

Code:
     OpenSPI();
     WriteSPI(...);
     ReadSPI(...);
     CloseSPI(...);

Of course that would just make your life very boring, no challenge what so ever. And we wouldn't want that now would we?

Attached is the manual for the Hi-Tech PIC18 Library.
 

Attachments

  • plibs.pdf
    398.8 KB · Views: 117

OpenSPI();
WriteSPI(...);
ReadSPI(...);
CloseSPI(...);

yeah i see this stuff in the spi.h.. Im looking for the spi.c but i cant found it... hehe I want to read what's written in that file.. hehe
 

Im stuck.. :-x I dont know what's next...

Im using the SPI debugger of proteus just to check what is going on in my SPI output (SDO).. but I dont understand what is happening the debugger what I see in only time and not the data I transmitted.. maybe I just dont know how to use the debugger... :grin:

I've never used the Proteus SPI debugger, maybe I'll fire up Proteus and see what I can figure out. It's a shame when you don't have enough time to learn and use the software on your own computer.

Let you know what I find out.

Ciao
 

Of course that would just make your life very boring, no challenge what so ever. And we wouldn't want that now would we?

yes but makes life easier.. Im understanding SPI because I want to learn my own functions like what I did in UART before...

---------- Post added at 06:18 ---------- Previous post was at 06:13 ----------

This library of HI-TECH c for SPI is using software SPI and not hardware SPI.. right?
 

yeah i see this stuff in the spi.h.. Im looking for the spi.c but i cant found it... hehe I want to read what's written in that file.. hehe

Are you referring to the compiler spi.h and spi.c?

I was actually referring to the example I uploaded, however the sources for the Hi-Tech PIC18 libs are located:

C:\Program Files\HI-TECH Software\PICC-18\PRO\9.66\sources\plib\spi

or relative to your installation.

The example I uploaded above contains both a spi.h and spi.c for implementing SPI on a 16F87XA, you should be able to use it to implement a simulation in Proteus.

Ciao
 

Keep in mind those library routines are for the PIC18 series and there are some significant differences between the PIC18 and PIC16 as far as initial configuration of registers.
 
Keep in mind those library routines are for the PIC18 series and there are some significant differences between the PIC18 and PIC16 as far as initial configuration of registers.

I'll just go directly to PIC18 since I have the datasheet here.. and if I don't get it then I'll get back to PIC16.. hehe I want to encounter what you said a rocky road... joke..! :)

---------- Post added at 06:35 ---------- Previous post was at 06:33 ----------

I'll take a nap maybe 30min then take my bath and then get back working.. :) Im having headache on always facing the computer monitor.. :)
 

im here again.. I cannot get it right..

why is that when i write any data to SSPBUF the Buffer Full Status bit(BF) must be set but BF is not set at all..
that is why when I put a line like this while(BF==0); the code will get stuck....


PHP:
#include <htc.h>




void SPI_init();
unsigned char ReadSPI( void );
void WriteSPI( unsigned char data_out );


void main()
{
	char x;
	CMCON = 0b111;
	ADCON0 = 0b00000000;
	SPI_init();  // initialize SPI mode
	TRISAbits.TRISA0 = 0;

	WriteSPI( 0x01 ); //writing to data to SSBUF

	if(SSPBUF == 0x01)  //checking written data
	PORTAbits.RA0 = 0;	  // turn off LED when read data is equal to written data.

	
	while(1);
   
		
		
		
		
   
}



void SPI_init()
{
	/* Enables serial port and configures SCK, SDO, SDI and SS as serial port pins 
	   SPI Master mode, clock = FOSC/64(3) */
	SSPCON1 = 0b00100010;

	/* Input data sampled at end of data output time
	   Transmit occurs on transition from active to Idle clock state */
	SSPSTAT = 0b11000000;

	TRISCbits.TRISC7 = 0; //SD0 set as output

	  
	TRISBbits.TRISB0 = 1; //SDI set as input

	TRISBbits.TRISB1 = 0; //SCK set as output 
	
	TRISCbits.TRISC2 = 0; //CS set as output

}



void WriteSPI( unsigned char data_out )
{
  SSPBUF = data_out;           // write byte to SSPBUF register
  while(BF==0); 
}


unsigned char ReadSPI( void )
{
  SSPBUF = 0x00;                  // initiate bus cycle
  while ( !BF );      // wait until cycle complete
  return ( SSPBUF );              // return with byte read 
}
 

thanks ckshivaram,

I will try those links.. I dont know which part I have missed.. but i have one question about the code below.
the datasheet stated that when the SSPBUF register full then the BF flag will be set but when I tried writing in that register the BF is not set.

and now here is my question:

the SSPBUF is 8bit register right? so when I write once using this function

PHP:
WriteSPI(0x01);

does it make the SSPBUF full that cause triggering to BF flag?



PHP:
void WriteSPI( unsigned char data_out )
{
  SSPBUF = data_out;           // write byte to SSPBUF register
  while(BF==0); 
}

I tried writing like that way but i cannot get BF to get high.. does it mean i need to write 8 times to get it full??
hmmm
 

I am looking into it but did you see in the C18 manual there is an example how to use SPI with an EEPROM.

---------- Post added at 19:56 ---------- Previous post was at 19:55 ----------

SSPBUF and SSPSR
As mentioned, the MSSP module consists of a transmit/receive shift register (SSPSR) and a buffer register (SSPBUF). The SSPSR shifts the data in and out of the device. The SSPBUF holds the data that was written to the SSPSR until the received data is ready. Once the eight bits of data have been received, that byte is moved to the SSPBUF register. Then, the Buffer Full detect bit, BF (SSPSTAT<0>) and the interrupt flag bit, SSPIF, are set.

Note: any write to the SSPBUF register during transmission/reception of data will be ignored. Still, if you do try to write, the Write Collision detect bit, WCOL (SSPCON1<7>), will be set. You must clear the WCOL bit so that it can be determined if the following write(s) to the SSPBUF register completed successfully.

The SSPBUF should be read before the next byte of data to transfer is written to the SSPBUF. The Buffer Full bit, BF (SSPSTAT<0>), indicates when SSPBUF has been loaded with the received data (transmission is complete). When the SSPBUF is read, the BF bit is cleared.
 
I am looking into it but did you see in the C18 manual there is an example how to use SPI with an EEPROM.

yes.. the same with Hitech C the manual teaches how to use the library of SPI..

I read all the builtin functions,configurations, bit by bit of registers but still it does not work at all.. I just want to do a basic spi protocol no other device yet.. let say i want to transmit a byte or receive without involving any device as slave
 

Code:
OpenSPI(SPI_FOSC_64, MODE_00, SMPEND);  // Initialize MSSP to SPI mode and enable MSSP in SPI
WriteSPI(0x01);   // Write a 0x01 byte to SSPBUF. Again, this message could be anything and depends on what device you are using.
 
	SPI_CS = 1;  // Allow Slave device to respond
	while (!DataRdySPI()); // Wait until buffer is filled
 
	x = ReadSPI(); // Read buffer
	SPI_CS = 0; // Give back control to the master
 
	CloseSPI(); // Disable the MSSP
 
	while(1);


---------- Post added at 20:02 ---------- Previous post was at 20:01 ----------

do you want to write the routing yourself or use inbuilt routine???
 
do you want to write the routing yourself or use inbuilt routine???

I want to write myself.. I already checked that inbuilt routine one by one and we have the same configuration but it did not worked..

PHP:
CloseSPI();  --// the content of this fucntion is just SSPEN: Master Synchronous Serial Port disable bit

PHP:
DataRdySPI() -- // this is just BF

PHP:
OpenSPI(SPI_FOSC_64, MODE_00, SMPEND); -- this are just  

0010 = SPI Master mode, clock = FOSC/64(3)
0 = Transmit occurs on transition from Idle to active clock state
1 = Input data sampled at end of data output time


I read all what is inside in the inbuilt routine and tried it but no luck... this is what we call rocky road... hehe
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top