element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet & Tria Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • About Us
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      • Japan
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Vietnam
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Embedded and Microcontrollers
  • Technologies
  • More
Embedded and Microcontrollers
Embedded Forum Running a pic18F45K20 at full speed
  • Blog
  • Forum
  • Documents
  • Quiz
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Embedded and Microcontrollers to participate - click to join for free!
Actions
  • Share
  • More
  • Cancel
Forum Thread Details
  • Replies 16 replies
  • Subscribers 474 subscribers
  • Views 1341 views
  • Users 0 members are here
  • i2c
  • pic18f45k20
  • ds1803
  • pics
Related

Running a pic18F45K20 at full speed

JohnDSiviter
JohnDSiviter over 15 years ago

Can anyone help with this simple problem, I want to achieve full speed 64MHz, at the moment I am getting 16MHz external, when I run a simple while loop (while(1){PORTD=0xFF;PORTD=0x00;}, I get a 4MHz squarewave, also I am having problems getting I2C working communicating with a DS1803E-010DS1803E-010 digital potentiometer:

 


#pragma config FOSC = INTIO7, FCMEN = OFF, IESO = OFF                       // CONFIG1H
#pragma config PWRT = ON, BOREN = OFF, BORV = 30                            // CONFIG2L
#pragma config WDTEN = OFF, WDTPS = 32768                                   // CONFIG2H
#pragma config MCLRE = OFF, LPT1OSC = OFF, PBADEN = OFF, CCP2MX = PORTC     // CONFIG3H
#pragma config STVREN = ON, LVP = OFF, XINST = OFF                          // CONFIG4L
#pragma config CP0 = OFF, CP1 = OFF, CP2 = OFF, CP3 = OFF                   // CONFIG5L
#pragma config CPB = OFF, CPD = OFF                                         // CONFIG5H
#pragma config WRT0 = OFF, WRT1 = OFF, WRT2 = OFF, WRT3 = OFF               // CONFIG6L
#pragma config WRTB = OFF, WRTC = OFF, WRTD = OFF                           // CONFIG6H
#pragma config EBTR0 = OFF, EBTR1 = OFF, EBTR2 = OFF, EBTR3 = OFF           // CONFIG7L
#pragma config EBTRB = OFF                                                  // CONFIG7H

/** I N C L U D E S **************************************************/
#include "p18f45k20.h"
#include "07 ADC.h"  // header file
#include "delays.h"
#include "spi.h"
#include "i2c.h"

//#include "math.h"
//#include "08 Interrupts.h"  // header file ****throws error

/** Prototypes**/
void main(void);
unsigned char I2C_SendByte(char myVolume);//char myByte)
unsigned char IncrementGrey(unsigned char Value); unsigned char DecrementGrey(unsigned char Value);
unsigned char WriteI2C1(  unsigned char data_out );
unsigned char ReadI2C1(  unsigned char data_out );
/** V A R I A B L E S *************************************************/
#pragma udata   // declare statically allocated uinitialized variables

/** D E C L A R A T I O N S *******************************************/
#pragma code    // declare executable instructions

/*******Global Variables******************/

/**********************************/
void main(void)
{
unsigned char count=1;
signed   char Direction_Up=-1;
unsigned char volume=0x00;
unsigned char PA=0x00;
unsigned char NAPA=0x00;
unsigned char greyCode=0x00;
unsigned char temp;
unsigned char PORTx;
/******************************************************************/
WDTCONbits.SWDTEN = 0; // Disable Watchdog
OSCTUNEbits.PLLEN    = 1; // Enable PLL //PLL enabled for INTOSC (4 MHz and 8 MHz only)

// IDLEN IRCF2 IRCF1 IRCF0 OSTS(1) IOFS SCS1 SCS0

OSCCONbits.IDLEN     = 0;    // Not enable pherimetral during sleep()
OSCCONbits.SCS1      = 1;    // Internal oscillator selected
OSCCONbits.SCS0      = 0;    //

OSCCONbits.IRCF2     = 1;    // 16 Mhz selected, 110=8Mhz
OSCCONbits.IRCF1     = 1;
OSCCONbits.IRCF0     = 1;

while(OSCCONbits.OSTS == 0){}       //Oscillator Start-up Time-out Status bit
while(OSCCONbits.IOFS == 0){}       //INTOSC Frequency Stable bit       
/******************************************************************/
    // Init I/O
    TRISC = TRISD = 0x00;      // PORTD bits 7:0 are all outputs (0)
    TRISB = 0xFF;  // PORTB (Encoder) are all inputs (1)
// TRISAbits.TRISA0 = 1;  // TRISA0 input

INTCON2bits.RBPU = 0;  // enable PORTB internal pullups
INTCON = 0b11100000;
INTCONbits.GIEL = 1;
INTCON2bits.INTEDG1 = 0;
INTCON3bits.INT1IP = 0;
INTCON3bits.INT1IE = 1;
INTCON3bits.INT1IF = 0;
//INTCON.PLLEN = 1;
RCONbits.IPEN = 1;

WPUBbits.WPUB0 = 1;   // enable pull up on RB0
    TRISBbits.TRISB0 = 1;       // PORTB bit 0 (connected to switch) is input (1)

PA=NAPA=PORTD=0;
volume=0xFF;PORTD=0xFF;
while(1)
{

PA=NAPA;
/* remove this after test */
while (!Switch_Pin1)
{
  Delay1KTCYx(50); //delay for switch debouncing - triggers lagging edge
  if (Switch_Pin1) {Delay1KTCYx(50);NAPA = IncrementGrey(NAPA);} //Increments PA on key release
}
/**************************/
// NAPA=PORTB;
if (PA!=NAPA)
{
  switch(NAPA)
  {

     case 0x00:
        switch (PA) //check last state
        {
         case 0x02:Direction_Up=1; break;
         case 0x01:Direction_Up=0; break;
         default:  Direction_Up=-1;break;
        }
      break;

      case 0x01:
        switch (PA)
        {
         case 0x00:Direction_Up=1; break;//TEMP STOP CODE break;
         case 0x03:Direction_Up=0; break;
         default:  Direction_Up=-1;break;
        }
      break;

     case 0x03:
        switch (PA)
        {
         case 0x01:Direction_Up=1; break;
         case 0x02:Direction_Up=0; break;
         default:  Direction_Up=-1;break;
        }
      break;
         
      case 0x02:
        switch (PA)
        {
         case 0x03: Direction_Up=1; break;   
         case 0x00: Direction_Up=0; break;
         default:   Direction_Up=-1;break;
        }
      default:break;
    
  }
}

switch (Direction_Up)
{
  case 1: volume++;PORTx = I2C_SendByte(volume);PORTD = volume;break;
    default: break;
  case 0: volume--;PORTx = I2C_SendByte(volume);PORTD = volume;break;
}

Direction_Up=-1;
} //while end

}


unsigned char I2C_SendByte(char myVolume)//char myByte)
{
unsigned char SPI_result=-1;
 
//• MSSP Control Register 1 (SSPCON1)
//• MSSP Control Register 2 (SSPCON2)
//• MSSP STATUS register (SSPSTAT)
//• Serial Receive/Transmit Buffer Register
//(SSPBUF)
//• MSSP Shift Register (SSPSR) – Not directly
//accessible
//• MSSP Address Register (SSPADD)
SSPSTAT = 0x80;//Disable SMBus & Slew Rate Control
SSPCON1 = 0x28; //Enable MSSP Master, SSPCON1=MASTER;
   // SPPADD must go after SSPCON1=MASTER; // ADD<7:0> = 1/Fi2c * FOSC-1 = 1/400,000 * 16,000 - 1 = 39 = 0010,0111b = 0x27
SSPCON2 = 0x00; //Clear Control Bits
//SSPADD = 0x18; //Should be 0x18 for 100kHz
SSPADD=0x27;//SCL pin clock period = ((ADD<7:0> + 1) *4)/FOSC
DDRCbits.RC3 = 1; //Configure SCL as Input
DDRCbits.RC4 = 1; //Configure SDA as Input
   //StartI2C();
   //OpenI2C(MASTER, SLEW_ON);
     SPI_result =WriteI2C(0b10100000);// 0101,address
     Delay1KTCYx(500);
  SPI_result =WriteI2C(myVolume);
  //Delay1KTCYx(500);
  return ReadI2C();
}

 

unsigned char IncrementGrey(unsigned char Value)
{
switch (Value)
{
   case 0x00:Value=0x01;break;
   case 0x01:Value=0x03;break;
   case 0x03:Value=0x02;break;
   case 0x02:Value=0x00;break;
   default:break;
}
return Value;
}
unsigned char DecrementGrey(unsigned char Value)
{
switch (Value)
{
   case 0x00:Value=0x02;break;
   case 0x01:Value=0x00;break;
   case 0x03:Value=0x01;break;
   case 0x02:Value=0x03;break;
   default:break;
}
return Value;
}

  • Sign in to reply
  • Cancel
Parents
  • Former Member
    Former Member over 15 years ago

    I'm new here, thought I would chime in..

    You will NOT see the full 64MHz (or even 16MHz) on a scope, if you're just looking at a pin output.

     

    Assuming your uC is running at the full 64MHz (16MHz with 4X PLL and NO cpu division, aka CPU_DIV = 1), the instruction clock speed is actually 64MHz/4 = 16MHz, since the PIC18F architecture uses a "1 instruction per 4 clock cycle" division.

     

    Then, your while loop is adding further overhead to your square wave output, because you are executing two instructions plus an additional comparison instruction or two per iteration of the while loop. That kills the frequency you would see on the output, and thus it is not representative of the true operating speed of the PIC. For a better (although still not ideal) test, simply copy the instructions "PORTD=0xFF;PORTD=0x00;" many many times in your main loop (or in a while(1) loop) and now try viewing the output on a scope. You should see a 16MHz/2 = 8MHz square wave, with an occasional hiccup (where the while loop ends/restarts). If you don't see around 8MHz something else is wrong, and if you're using the internal oscillator it almost HAS to be the software configuration of the oscillator bits or PLL. Hope that helps!

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
  • JohnDSiviter
    JohnDSiviter over 15 years ago in reply to Former Member

    Thanks Brennathi, that is the answer that wins for me, makes perfect sense, hope I get the 8MHz squarewave when I try later image

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
  • MicrochipRTCfr
    MicrochipRTCfr over 15 years ago in reply to JohnDSiviter

    John

     

    The best way to check the processor speed by toggling a port is to use a timer interrupt.

    If you write code in C it will generate several assembly instructions and therefore you'll never toggle the port at the fastest speed. This is only possible in assembler.

    Another VERY IMPORTANT point : for all ports bits that you use in output mode use LATx instead of PORTx.  e.g : LATD = 0xFF instead of PORTD = 0xFF.

     

    If you use TIMER1 to generate interrupts with the prescaler set to 1/8 and writing (65536-20000) into PR1 you will generate an interrupt every Fosc/4  / 8 / 20000 = 10ms which will be easy to look at with a scope (or counting every 50 interrupts) with give a 1s blinking LED.

    Note : assume Fosc = 64MHz

     

    regards

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
  • Former Member
    Former Member over 15 years ago in reply to MicrochipRTCfr

    But if you use an interrupt doesn't the PIC first have to jump to the interrupt vector, then jump to the service routine and THEN toggle the output pin? It seems like there would be just as much overhead that way. Or is there a way to directly toggle a pin the instant an interrupt is triggered?

     

    The way I said will still work, even though it's not the most elegant solution. The C18 compiler will optimize the port toggle instructions so that they each only take one assembly instruction. You could also just directly toggle the port in assembly if you're paranoid about the compiler.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
Reply
  • Former Member
    Former Member over 15 years ago in reply to MicrochipRTCfr

    But if you use an interrupt doesn't the PIC first have to jump to the interrupt vector, then jump to the service routine and THEN toggle the output pin? It seems like there would be just as much overhead that way. Or is there a way to directly toggle a pin the instant an interrupt is triggered?

     

    The way I said will still work, even though it's not the most elegant solution. The C18 compiler will optimize the port toggle instructions so that they each only take one assembly instruction. You could also just directly toggle the port in assembly if you're paranoid about the compiler.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
Children
No Data
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube