|
|
View previous topic :: View next topic |
Author |
Message |
krugger
Joined: 12 Jul 2011 Posts: 18 Location: El Salvador
|
Differences in instruction times using PIC16F1827 and PIC18F |
Posted: Wed Jul 20, 2011 11:53 am |
|
|
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
|
|
Posted: Wed Jul 20, 2011 12:14 pm |
|
|
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: 9221 Location: Greensville,Ontario
|
|
Posted: Wed Jul 20, 2011 12:38 pm |
|
|
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
|
|
Posted: Wed Jul 20, 2011 3:15 pm |
|
|
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
|
|
Posted: Wed Jul 20, 2011 3:30 pm |
|
|
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: 9221 Location: Greensville,Ontario
|
|
Posted: Wed Jul 20, 2011 3:38 pm |
|
|
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
|
|
Posted: Wed Jul 20, 2011 3:40 pm |
|
|
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
|
|
Posted: Wed Jul 20, 2011 3:45 pm |
|
|
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
|
|
Posted: Wed Jul 20, 2011 4:26 pm |
|
|
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
|
|
Posted: Wed Jul 20, 2011 4:46 pm |
|
|
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
|
|
Posted: Wed Jul 20, 2011 5:04 pm |
|
|
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
|
|
Posted: Wed Jul 20, 2011 5:37 pm |
|
|
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: 9221 Location: Greensville,Ontario
|
|
Posted: Wed Jul 20, 2011 5:53 pm |
|
|
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
|
|
Posted: Wed Jul 20, 2011 6:03 pm |
|
|
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: 9221 Location: Greensville,Ontario
|
|
Posted: Thu Jul 21, 2011 4:42 am |
|
|
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. |
|
|
|
|
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
|