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 support@ccsinfo.com

interfacing pic16f877a with eeprom 25lc640

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



Joined: 24 May 2010
Posts: 8

View user's profile Send private message

interfacing pic16f877a with eeprom 25lc640
PostPosted: Mon May 31, 2010 10:49 am     Reply with quote

I'm trying write a memory 25lc640 and use this code to the pic:
Code:
#include <16F877.H>
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

#define SPI_MODE_0_0 0x4000
#define SPI_MODE_0_1 0x0000
#define SPI_MODE_1_0 0x0010
#define SPI_MODE_1_1 0x4010

/*
// If your hardware SPI pins are different than the
// ones used on the 16F877, then define them here
// and un-comment this section.
#define EEPROM_SELECT PIN_C2
#define EEPROM_CLK    PIN_C3
#define EEPROM_DI     PIN_C5
#define EEPROM_DO     PIN_C4
*/

#include <25LC640_Hardware_SPI.c>

#include <STDLIB.H>
//========================
void main()
{
int8 data;
int8 wrote;
int16 addr;
int16 errors = 0;
     
init_ext_eeprom();
     
// Fill eeprom with random data.
printf("\n\r");
printf("writing");

srand(0x55);

for(addr = 0; addr < EEPROM_SIZE; addr++)
   {
    write_ext_eeprom(addr, (int8)rand());
    if((int8)addr == 0)
       putc('.');
   }

// Read the eeprom and check for errors.
printf("\n\r");
printf("reading");

srand(0x55);

for(addr = 0; addr < EEPROM_SIZE; addr++)
   {
    data = read_ext_eeprom(addr);
    wrote = (int8)rand();
    if(data != wrote)
      {
       printf("%lx: read %x, should be %x\n\r", addr, data, wrote);
       errors++;
       if(errors >= 10)
          break;
      }

    if((int8)addr == 0)
       putc('.');
   }

printf("\n\r");
printf("done\n\r");

while(1);
}


And this code for driver memory:
Code:

#ifndef EEPROM_SELECT
#define EEPROM_SELECT PIN_C2
#define EEPROM_CLK    PIN_C3
#define EEPROM_DI     PIN_C5
#define EEPROM_DO     PIN_C4
#endif

#define EEPROM_ADDRESS long int
#define EEPROM_SIZE    8192

void init_ext_eeprom()
{
output_high(EEPROM_SELECT);   
setup_spi(SPI_MASTER | SPI_MODE_0_0 | SPI_CLK_DIV_16 );
}

//--------------------------------
int1 ext_eeprom_ready(void)
{
int8 data;

output_low(EEPROM_SELECT);
spi_write(0x05);
data = spi_read(0);
output_high(EEPROM_SELECT);
return(!bit_test(data, 0));
}

//--------------------------------
void write_ext_eeprom(EEPROM_ADDRESS address, BYTE data)
{
while(!ext_eeprom_ready());

output_low(EEPROM_SELECT);
spi_write(0x06);
output_high(EEPROM_SELECT);

output_low(EEPROM_SELECT);
spi_write(0x02);
spi_write(address >> 8);
spi_write(address);
spi_write(data);
output_high(EEPROM_SELECT);
}
//--------------------------------

BYTE read_ext_eeprom(EEPROM_ADDRESS address)
{
int8 data;

while(!ext_eeprom_ready());

output_low(EEPROM_SELECT);
spi_write(0x03);
spi_write(address >> 8);
spi_write(address);

data = spi_read(0);
output_high(EEPROM_SELECT);

return(data);
}


I take this code from PCM_PROGRAMER, but when i try to simulate it in proteus i receive the follows message:

[PIC16 MSSP] PC=0X0148. Data written SSPBUF whilst MSSP (in master mode) is active - data has been ignored.

[SPIMEM] Transfer did not end on a byte boundary, data will not be writen.
I think that is something wrong with my schematic, here is it.



If anyone knows what i did wrong, please help me.
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Mon May 31, 2010 11:21 am     Reply with quote

What is your compiler version number?
hansimg



Joined: 24 May 2010
Posts: 8

View user's profile Send private message

PostPosted: Mon May 31, 2010 11:29 am     Reply with quote

CCS 4.057
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon May 31, 2010 2:49 pm     Reply with quote

It works for me. I compiled your code with vs. 4.057, and ran it on
a PicDem2-Plus board with a 25LC640 on it. I get this result displayed
in the terminal window:
Quote:

writing................................
reading................................
done

It's not getting any errors. I looked at the signals with a scope and
they're all active. It's putting out bursts of 8 clocks on the SCLK pin.
I think it's working and the problem is in Proteus.
semmoor



Joined: 09 May 2012
Posts: 46
Location: KSA

View user's profile Send private message Send e-mail MSN Messenger

PostPosted: Fri Jul 27, 2012 5:20 am     Reply with quote

did it work on proteus?
temtronic



Joined: 01 Jul 2010
Posts: 9177
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Fri Jul 27, 2012 5:26 am     Reply with quote

Since PCM Programmer proved your code works on real hardware the problem( again) is Proteus !
Sigh, I know I sound like a broken record , but Proteus is FULL of bugs, errors, faulty DRCs and is NOT a reliable simulation.You cannot fix Proteus so I suggest you toss it into the 'trash bin' asap.
semmoor



Joined: 09 May 2012
Posts: 46
Location: KSA

View user's profile Send private message Send e-mail MSN Messenger

PostPosted: Fri Jul 27, 2012 5:42 am     Reply with quote

temtronic wrote:
Since PCM Programmer proved your code works on real hardware the problem( again) is Proteus !
Sigh, I know I sound like a broken record , but Proteus is FULL of bugs, errors, faulty DRCs and is NOT a reliable simulation.You cannot fix Proteus so I suggest you toss it into the 'trash bin' asap.


you're 100% right, it's full of bugs , and can never be like real hardware, but people use it because it's really easy to find any device and just use it, but i'm thinking to stop using it, everyday errors, bugs etc...
ettore



Joined: 30 Sep 2012
Posts: 1

View user's profile Send private message

PostPosted: Sun Sep 30, 2012 4:54 pm     Reply with quote

Don't be too fast to blame Proteus.
In such the case I can demonstrate how the bug comes from CCS compiler optimizer, not Proteus.

Just to begin I have made a simple program like this:

Code:
#include <16F877a.H>  //<18F458.H>
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=4000000)

#define SPI_MODE_0_0 0x4000
#define SPI_MODE_0_1 0x0000
#define SPI_MODE_1_0 0x0010
#define SPI_MODE_1_1 0x4010

#define CHIP_SELECT PIN_C2

void main()
 { volatile int8 data  = 0xAA;
   volatile int16 addr = 0x100;
//#OPT 0
   output_high(CHIP_SELECT);
   setup_spi(SPI_MASTER | SPI_MODE_0_0 | SPI_CLK_DIV_16 );

   output_low(CHIP_SELECT);
   spi_write(0x06);
   output_high(CHIP_SELECT);

   output_low(CHIP_SELECT);
   spi_write(0x02);
   spi_write(addr >> 8);
   spi_write(addr);
   spi_write( data);
   output_high(CHIP_SELECT);

   while(1);
 }

and used it on my HW board and Proteus simulator as well, and for either PIC16 or PIC18 popular devices. While the version for PIC18 ever works either for Proteus or real device the one for PIC16 did not; neither for Proteus nor for the real PIC. What I've got in the HW is the chip select pin which goes high before the entire 4 bytes writes procedure is completed. In Proteus I get the same as well and in addition I get a couple of warning messages that tell me I'm writing into the SSPBUF while the Master SSP module is still transmitting.

Given that with other compilers the program reported above works fine, then in order to understand where the problem resides I had to investigate about the assembler code generated with the compiler. The spi_Write(value) internal function is translated with asm codes like these (comment are mine):

Code:
....................    spi_write(0x02); 
004D:  MOVF   13,W    ; -> dummy read of the SSPBUF buffer. This clears the BF flag bit in status register, otherwise software polling won't work. 
004E:  MOVLW  02           
004F:  MOVWF  13      ; Value is written in SSPBUF. The BF flag bit is still cleared at this point.   
0050:  BSF    03.5    ; Switch to bank 1.
0051:  RRF    14,W    ; Rotate right the BF flag into the C flag STATUS bit.
0052:  BTFSC  03.0    ; Polling test of the BF bit of the status register (bit BF is rotated into the C STATUS flag). 
0053:  GOTO   051     ; When 8 bits are transmitted then BF is set and the software can go on, otherwise do polling again. 


For PIC16 and when optimizer is configured for all the levels but 0 the SSPBUF dummy read MOVF is removed! Perhaps the optimizer presumes it's an obsolete code or something like that but interestingly enough this happens when the data is a variable not a literal. Anyway, as a result of this code removal the BF flag bit is not cleared and polling test exits before than the whole byte is transmitted.

However if you put somewhere the directive #OPT 0 then the above code works well even for PIC16 family, although the translated code is not optimized anymore.
If you check the translated code with optimizer disabled then you'll see again the dummy read - MOVF 13,W - in the code, as it should be!
I have made these tests with the CCS compiler version 4.107.

Proteus is a great piece of a software, but certainly not bug free in any case ... exactly as the CCS compiler though! This thread is a demonstration.
At any rate, please feel free to send the results of my fault finding to the CCS company for further investigation and bug fixing.


Regards,

Ettore Arena
matheuslps



Joined: 29 Sep 2010
Posts: 73
Location: Brazil

View user's profile Send private message MSN Messenger

PostPosted: Sun Aug 25, 2013 4:09 pm     Reply with quote

Thanks ettore!!!

Your tip did work for me.

Just added #OPT 0 on the code and now it is working with Proteus! Finally!

I am able to work with the max7219.

bye
Ttelmah



Joined: 11 Mar 2010
Posts: 19378

View user's profile Send private message

PostPosted: Mon Aug 26, 2013 2:08 am     Reply with quote

Classic read the manual.....

If you perform spi_write, by default it will return as soon as the byte is transferred to the output buffer. A _subsequent_ spi_write, will wait till the previous transaction is completed.

However if you perform spi_read, this will always wait for the transfer to complete.

So the _last_ spi_write in the transaction, needs to be replaced with:
Code:

   int8 dummy; //in the declarations

   dummy=spi_read(data);
   output_high(CHIP_SELECT);

//Or
   spi_write( data);
   while (!spi_data_is_in()) ;
   output_high(CHIP_SELECT);
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