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

Differences in instruction times using PIC16F1827 and PIC18F
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
krugger



Joined: 12 Jul 2011
Posts: 18
Location: El Salvador

View user's profile Send private message

Differences in instruction times using PIC16F1827 and PIC18F
PostPosted: Wed Jul 20, 2011 11:53 am     Reply with quote

Dear all,

I'm pretty sure this should be related with delay definitions, but I still can't find the error. Let me put you in context. I'm working in a project to measure, store and send data from 6 lines to perform energy quality measures via FFT.

In my design I have a micro acting as SPI Master controlling 3 elements:

- A MCP3008 10 bit external ADC.
- A 23K256 SPI SRAM Memory.
- A RFM22B RF Module.

I was using PIC16F1827 and everything was going well in my Proteus simulation. However, I've realized I need to store more data than the maximum SRAM size, so I started to think in having an MMC Card.

Ok.

To control that MMC I can't use 16F1827 due to its RAM size limitations, so I decided to upgrade to PIC18F2553. But, before starting with the MMC controller programming I decided to check that the rest of the program was running exactly as it was running in PIC16F1827.

And here is where I found the unpleasant surprise.

Apparently PIC18F2553 is running four times slower than the PIC16F1827. I have more or less the same Config file for both project, and I've checked that 40 MHz appears in the properties of both components in Proteus VSM, so I don't know what can I be doing wrong, and what is worst, now I don't know whether the correct timing measures are the ones of the PIC16 or the ones of the PIC18.

Let me show you the codes:

Code for PIC16F1827:

//16F1827.h

Code:

#include <16F1827.h>
#device ICD=TRUE
#device adc=10

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES ECH                   
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOMCLR                     //Master Clear pin DISABLED
#FUSES NOCPD                    //No EE protection
#FUSES NOBROWNOUT               //No brownout reset
#FUSES IESO                     //Internal External Switch Over mode enabled
#FUSES FCMEN                    //Fail-safe clock monitor enabled
#FUSES WDT_SW               
#FUSES NOCLKOUT             
#FUSES NOWRT                    //Program memory not write protected
           
#FUSES PLL                   
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES STVREN                   //Stack full/underflow will cause reset
#FUSES BORV19               
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O

#use delay(clock=40000000)

#define SPI_MODE_0_0  (SPI_L_TO_H | SPI_XMIT_L_TO_H)
#define SPI_MODE_0_1  (SPI_L_TO_H)
#define SPI_MODE_1_0  (SPI_H_TO_L)
#define SPI_MODE_1_1  (SPI_H_TO_L | SPI_XMIT_L_TO_H)



The 18F2553 is an exact copy of the driver file that I've copied into my working directory path.


Code for PIC18F2553:


//Config.h

Code:
#include <18F2553.h>
#device ICD=TRUE

#FUSES NOWDT                    //No Watch Dog Timer

#FUSES CPUDIV1
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOMCLR                   //Master Clear pin DISABLED
#FUSES NOCPD                    //No EE protection
#FUSES NOBROWNOUT               //No brownout reset
#FUSES IESO                     //Internal External Switch Over mode enabled
#FUSES FCMEN                    //Fail-safe clock monitor enabled


#FUSES NOWRT                    //Program memory not write protected
           
#FUSES PLL1                   
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES STVREN                   //Stack full/underflow will cause reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O

#use delay(clock=40000000)

#define SPI_MODE_0_0  (SPI_L_TO_H | SPI_XMIT_L_TO_H)
#define SPI_MODE_0_1  (SPI_L_TO_H)
#define SPI_MODE_1_0  (SPI_H_TO_L)
#define SPI_MODE_1_1  (SPI_H_TO_L | SPI_XMIT_L_TO_H)


The 18F2553 is an exact copy of the driver file that I've copied into my working directory path.

The main programs are:

For PIC16F1827:

Code:
#include "C:\Users\USUARIO\Dropbox\Tesis Francisco Menjivar\16F1827.h"
#include "C:\Users\USUARIO\Dropbox\Tesis Francisco Menjivar\23K256b.c" 
#include "C:\Users\USUARIO\Dropbox\Tesis Francisco Menjivar\RFM22.c"
#include "C:\Users\USUARIO\Dropbox\Tesis Francisco Menjivar\MCP3008.c"
//#include "D:\Mis documentos\Dropbox\Tesis Francisco Menjivar\mmc_spi.c"

#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdlibm.h>
#include <string.h>
 

#int_SSP
void  SSP_isr(void)
{

}

#int_SSP2
void  SSP2_isr(void)
{

}

  #use fast_io(A)
  #use fast_io(B)

static int actualADch=0;
static int16 address=0;
static long int medida=0;

struct parts {
    unsigned int8 lsb;
    unsigned int8 msb;
  } ; 

typedef static union {
  unsigned int16 sample;
  unsigned int8 v[2];
  struct parts bytes;
} measure; 

measure medidas;

void ADMeasure(int canal);
void Measure(int16 Muestras);
void Save2SRAM(void);

void ADMeasure(int canal)
{
medida=read_ext_adc(canal);
medidas.sample=medida;
Save2SRAM();
}

void Save2SRAM(void)
{
write_ext_sram(address++,Medidas.bytes.MSB);
write_ext_sram(address++,Medidas.bytes.LSB);
}

void Measure(int16 Muestras)
{
address=0;
int16 i;
for (i=0;i<Muestras;i++)
   {
   actualADch = (i%6);
   ADMeasure(actualADch);
   
   }
}


void main()
{
   setup_adc_ports(sAN2|sAN3|sAN4|sAN5|sAN6|sAN7|VSS_VDD);
   setup_adc(ADC_CLOCK_DIV_64);
   setup_spi(SPI_MASTER|SPI_MODE_0_0|SPI_SS_A5|SPI_CLK_DIV_4|SPI_SAMPLE_AT_MIDDLE);
//   setup_spi2(SPI_MASTER|SPI_CLK_DIV_4|SPI_SAMPLE_AT_MIDDLE);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
 //  enable_interrupts(INT_SSP);
 //  enable_interrupts(INT_SSP2);
   enable_interrupts(GLOBAL);
//Setup_Oscillator parameter not selected from Intr Oscillator Config tab

   // TODO: USER CODE!!

set_tris_a(0x1C);
set_tris_b(0x62);

init_RFM22();
init_ext_sram();
adc_init();
//mmc_init();


Measure(7200);
Measure(14400);

}



and for PIC18F2553:
Code:

  #include "C:\Users\USUARIO\Dropbox\Tesis Francisco Menjivar\CONFIG.h"
 
#USE SPI (MASTER, SPI1, MODE=0, BITS=8, STREAM=STREAM_ADC1)
#USE SPI (MASTER, SPI1, MODE=0, BITS=8, STREAM=STREAM_SRAM)
#USE SPI (MASTER, SPI1, MODE=0, BITS=8, STREAM=STREAM_RFM22)
 
  #include <stdio.h>
  #include <stddef.h>
  #include <stdlib.h>
  #include <stdlibm.h>
  #include <string.h>
  #include <stdint.h>
 
  #include "C:\Users\USUARIO\Dropbox\Tesis Francisco Menjivar\23K256bb.c" 
  #include "C:\Users\USUARIO\Dropbox\Tesis Francisco Menjivar\RFM22b.c"
  #include "C:\Users\USUARIO\Dropbox\Tesis Francisco Menjivar\MCP3008b.c"
  //#include "C:\Users\USUARIO\Dropbox\Tesis Francisco Menjivar\mmcsd.c"


  #use fast_io(A)
  #use fast_io(B)
  #use fast_io(C)

static int actualADch=0;
static int16 address=0;
static long int medida=0;

struct parts {
    unsigned int8 lsb;
    unsigned int8 msb;
  } ; 

typedef static union {
  unsigned int16 sample;
  unsigned int8 v[2];
  struct parts bytes;
} measure; 

measure medidas;

void ADMeasure(int canal);
void Measure(int16 Muestras);
void Save2SRAM(void);

void ADMeasure(int canal)
{
medida=read_ext_adc(canal);
medidas.sample=medida;
Save2SRAM();
}

void Save2SRAM(void)
{
write_ext_sram(address++,Medidas.bytes.MSB);
write_ext_sram(address++,Medidas.bytes.LSB);
}

void Measure(int16 Muestras)
{
address=0;
int16 i;
for (i=0;i<Muestras;i++)
   {
   actualADch = (i%6);
   ADMeasure(actualADch);
   
   }
}


void main()
{
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_CLOCK_DIV_64);
   setup_spi(SPI_MASTER|SPI_CLK_DIV_4|SPI_MODE_0_0);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
 //  enable_interrupts(INT_SSP);
 //  enable_interrupts(INT_SSP2);
   //enable_interrupts(GLOBAL);
//Setup_Oscillator parameter not selected from Intr Oscillator Config tab

   // TODO: USER CODE!!

set_tris_a(0x00);
set_tris_b(0x01);
set_tris_c(0x00);

init_RFM22();
init_ext_sram();
adc_init();
//mmcsd_init();


Measure(7200);
Measure(14400);

}


The only difference between:

- 23K256b and 23K256bb.c
- RFM22.c and RFM22b.c
- MCP3008.c and MCP3008b.c

are the definitions og the CS_PIN for each one, but they're exact copies of the corresponding drivers from the CCS drivers folder.

I'm using CCS 4.114 and Proteus 7.8 sp2.

I remark that both are working, but one (PIC16F1827) is running four times faster than the other (PIC18F2553).

I know it has to be a stupid thing and I'm sorry for posting all this brick but I've spent two days looking for an explanation and honestly I couldn't find it.

Hope you can help me.

Thanks and regards.

Pablo
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Jul 20, 2011 12:14 pm     Reply with quote

Quote:

#include <16F1827.h>
#use delay(clock=40000000)

The 16F1827 can't run at 40 MHz. Read the data sheet:
Quote:

PIC16(L)F1826/27

Flexible Oscillator Structure:
• Precision 32 MHz Internal Oscillator Block:
- Factory calibrated to ± 1%, typical
- Software selectable frequencies range of
31 kHz to 32 MHz
• 31 kHz Low-Power Internal Oscillator
• Four Crystal modes up to 32 MHz
• Three External Clock modes up to 32 MHz
• 4X Phase-Lock Loop (PLL)


16F1827 data sheet:
http://ww1.microchip.com/downloads/en/DeviceDoc/41391D.pdf
temtronic



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

View user's profile Send private message

PostPosted: Wed Jul 20, 2011 12:38 pm     Reply with quote

Welcome to the ugly world of 'simulation by Proteus'.

Once again Proteus has failed to correctly simulate the real world.

If, and I mean IF it had, it would have picked up on the PICs 32MHz limit when you coded 40MHz. It's this very simple, basic 'design rule check' that show how poorly Proteus really is. Since it can't get something as basic as this right do you actually feel comfortable with it regarding higher level aspects???
Sadly I see this problem daily on this board (and others), people blindly believing simulators are 100% real....nothing is further from the truth.
krugger



Joined: 12 Jul 2011
Posts: 18
Location: El Salvador

View user's profile Send private message

PostPosted: Wed Jul 20, 2011 3:15 pm     Reply with quote

Thank yoo both for your feedback. I've changed the frequency to 32 MHz on both, and still have differences in execution times.

Any other suggestion?

Thank you again for sharing your knowledge!

Pablo
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Jul 20, 2011 3:30 pm     Reply with quote

Quote:
Apparently PIC18F2553 is running four times slower than the PIC16F1827.

What are you measuring to determine this speed difference ?

What frequency is your crystal ? I notice you don't have the HSPLL fuse.
Does Proteus even care about fuses or crystals ? I don't know.
temtronic



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

View user's profile Send private message

PostPosted: Wed Jul 20, 2011 3:38 pm     Reply with quote

If you're still in 'simulation' mode again Proteus can easily be at fault ! If real hardware, that's another matter.

Also for data storage, consider one of those modules that take serial data and store onto a flashdrive into a file. Cheap, easy to use, transportable, no drivers to code.....all the hard stuff is done 'onboard'!
krugger



Joined: 12 Jul 2011
Posts: 18
Location: El Salvador

View user's profile Send private message

PostPosted: Wed Jul 20, 2011 3:40 pm     Reply with quote

I simulate both codes on their respectives similar schematics (only the PIC component changing from one to the other). I do it step by step, and Proteus shows the elapsed time between the previous instruction and the beginning of the current one.

Doing it like this I observe that times for 18F2553 are about 4 times bigger than times for PIC16F1827, not only for SPI reads or writes, but for every instruction. (i.e. a normal variable assignation lasts 50 ns simulated in PIC16 and 200 ns in PIC18).

Can yo explain me a bit further about the use of High frequency fuses or maybe redirecting me to a post in which this issue has been explained?

Thank you very much and best regards from El Salvador.

Pablo
krugger



Joined: 12 Jul 2011
Posts: 18
Location: El Salvador

View user's profile Send private message

PostPosted: Wed Jul 20, 2011 3:45 pm     Reply with quote

Quote:
Also for data storage, consider one of those modules that take serial data and store onto a flashdrive into a file. Cheap, easy to use, transportable, no drivers to code.....all the hard stuff is done 'onboard'!


Interesting... ¿Can you recommend me any particular component?

For me it's important to test with Proteus as I have to ask for specific items to be brought from abroad (El Salvador doesn't have a particularlly active electronics activity and it's hard to find even some passive components), so I've to be at least a bit sure about the components may work when mounted on hardware before purchasing them!

Thank you both for your kind help!

Pablo
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Jul 20, 2011 4:26 pm     Reply with quote

Your 16F1827 runs at 32 MHz maximum, so I made this program for
the 18F2553 which should also run it at 32 MHz. This requires a 4 MHz
crystal on the oscillator pins of the 18F2553 (and 22pf capacitors for it).
Code:

#include <18F2553.h>
#fuses XTPLL,NOWDT,CPUDIV2,PLL1
#use delay(clock=32M)

//======================================
void main(void)
{

// Blink an LED at a 1 Hz rate.
while(1)
  {
   output_high(PIN_B0);
   delay_ms(500);
   output_low(PIN_B0);
   delay_ms(500);
  }
 
}


I tested this with compiler vs. 4.122 on an 18F4550 in hardware.
The 18F4550 has the same oscillator circuit internally as the 18F2553.
krugger



Joined: 12 Jul 2011
Posts: 18
Location: El Salvador

View user's profile Send private message

PostPosted: Wed Jul 20, 2011 4:46 pm     Reply with quote

Ok, using your configuration in my header file I obtain the following execution times for some of the used instructions:

set_tris(0xXX); ==> 250 ns

spi_xfer_SRAM(0xXX); ==> 3.750 us

actualADch = (i%6) ==> 36.875 us ???????

spi_write(0xXX); ==> 1.75 us

write_ext_ram(add, content); ==> 16.75 us (Method from 23K256.c CCS driver)

Are those times reasonable or should they be smaller?

Thank you again!
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Jul 20, 2011 5:04 pm     Reply with quote

The 250ns for set_tris_a(0x00) means the PIC is running at 8 MHz.
However, you're running Proteus and I don't have it, and there is nothing
I can do to fix it.
ckielstra



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

View user's profile Send private message

PostPosted: Wed Jul 20, 2011 5:37 pm     Reply with quote

A few years ago I played with Proteus and was disappointed when I noticed the clock generating circuitry was not being simulated. The value you define in the property settings for the PIC process, that will be the speed the simulation is running with. Whatever crystal is connected to the PIC doesn't matter.

From the above test it seems like the PLL fuses are not simulated either. Doesn't surprise me. Change the XTPLL fuse by XT and my guess is you will see identical simulation results.
Proteus is nice for a quick test, but don't take the results for granted. It is only a tool and has many known flaws. I'm not recommending it for professional use.
temtronic



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

View user's profile Send private message

PostPosted: Wed Jul 20, 2011 5:53 pm     Reply with quote

I can understand the design before ordering parts problem as I got nailed very hard by Motorola when the 68HC11 series came out( that's why I switched to PICs 25 years ago!).
One suggestion is to design/buy a bigger PIC( more functions,pins,etc.) than you 'think' you need.Having a few spare pins is nice,more memory is great too ! I know it costs a bit more now, but if you stick with a common part your engineering costs, inventory,pcb costs, etc. go way, way down.Yes, it's 'overkill' to have a 40 pin 16F877 in some simple projects when an 18 pin PIC will do, but overall cost will go down.Another benefit is that you soon develop common working code (functions, I/O routines,etc.) that you KNOW work. If you need more speed it's easier to rework existing working code than trying a new PIC and wondering why is doesn't work like the other one does(SFR addresses changed perhaps ?)
Also , see who else locally needs PICs(schools ?) as shipping must be a huge factor for you.
The memory module is from Parallax.It's called a memoryDataStick( # 27937), about $40 USD.From their descrition it's easy to use ,easy to wire up(4 -5 wires).There may be others out there but that's the one I'm familiar with.
As for your 'timing' problem, it is very possible to be a glitch or bug in Proteus. You could use MPLAB to try the code,but again,I work in the real world with real chips as I've never been happy with any simulators performance.For accurate timing I always go back to the databook, dump the program listing(project.LST) and add up the instructions and their timings.Yes, to the new kids , it's a pain, but to us old guys it's what we had to do.Kind of like doing long hand division instead of using a calculator !
krugger



Joined: 12 Jul 2011
Posts: 18
Location: El Salvador

View user's profile Send private message

PostPosted: Wed Jul 20, 2011 6:03 pm     Reply with quote

Thank you to all.

Your feedback is greatly appreciated by all the users in this forum.

To sum up a bit:

I understand that all timing measures from Proteus-VSM are not reliable. Related question: Which tool to use for timing tests in applications that need a high-speed serial I/O? MPLAB?

Regards,

Pablo
temtronic



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

View user's profile Send private message

PostPosted: Thu Jul 21, 2011 4:42 am     Reply with quote

Pencil and paper ! Really. Just print the listing, open the databook to your PIC and manually calculate the time using the instruction set summary for the 'machine cycles' and what processor speed you're using.Yes, it'll take a few minutes of your time, but by reading the listing, and doing the simple math you'll see how the PIC works,maybe see a shortcut or improvement to your code as well.Also you'll have the REAL time it should take THEN compare that to what MPLAB or other program 'says' it takes. If the two are very,very close then you've verified the simulator is fairly accurate.
What do you mean by 'high speed'? Since I started with ASR33 Teletypes(110 baud), anything over 9600 is high speed for me!
I do know you can get over 900,000 KB on a PIC18 without any communication problems and run a 3 axis CNC machine.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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