Menu

Is there a proccedure for changing the oscillator frequency on-the-fly?

Haroen
2023-02-12
2023-02-14
  • Haroen

    Haroen - 2023-02-12

    I found this post with an example but don't understand it.
    https://sourceforge.net/p/gcbasic/discussion/579125/thread/081ebeee9c/#4622

    In PICAXE there is a function Setfreq to easily change the µP frequency.
    I have this at the program start: "#chip mega328p,32"
    And want to change it temporarily in code to 16MHz.
    Is there a short way to make a procedure called "SetFreq ...MHz" to change the µP frequency?

     
    • Anobium

      Anobium - 2023-02-12

      The simple answer is no.

      Why would you want to do this? All the timings will go wrong.

      That question asked. You can create your own method. But, the answer to 'why?' will help is understand the requirement.

       
  • Ccin E Crout

    Ccin E Crout - 2023-02-12

    It can be done with a PIC by setting some registers - I think the example following the link uses that method, but those registers do not exist in the mega328.

     
  • Haroen

    Haroen - 2023-02-12

    I tried the TOF10120 laser distance code again and changed it from 16MHz to "#chip mega328p,32".
    With 32MHz I get terminal messages like:

    <0><0><0><0><0><0><0><0><0><0><0><0>æø~†žfxæ˜à˜ø˜à˜žfžæ€˜€`fž~†žfxæ˜à˜ø˜žfžæ€˜€`fž~†žfxæ˜à˜ø˜x˜žfžæ€˜€`fž~†žfxæ˜à˜ø˜†˜žfžæ€˜€`fž~†žfxæ˜à˜x†˜žfžæ€˜€`fž~†žfxæ˜à˜ø˜f˜žfžæ€˜€`fž~†žfxæx<0>˜žfžæ€˜
    

    instead of 16MHz messages like:

    <0><0><0>à<0><0>à<0>²Êjµ5Distance= 1930 mm
    Distance= 1930 mm
    Distance= 1942 mm
    Distance= 1942 mm
    Distance= 1942 mm
    Distance= 1942 mm
    

    In many PICAXE projects I had to use the SetFreq command too.
    It would indeed be nice if all code could work on just one high frequency or on battery powered projects a low frequency to last longer.

     

    Last edit: Haroen 2023-02-12
  • Anobium

    Anobium - 2023-02-12

    Are you using an UNO board?

    What is the oscillator? If an UNO then chip has a 16mHz oscillator. So, changing the frequency to 32 will fail as the timing calls are at 32mHz and the physical chip is 16mHz.

    So, this is to use less power. Use sleep.

     
  • William Roth

    William Roth - 2023-02-12

    At compile time ... The Great Cow BASIC compiler calculates wait times, baud rates, I2C timing, etc based upon the Chip Frequency used with #chip. Example: #chip 18F27Q43, 32

    On most PIC microcontrollers the OSC frequency can be changed on-the- fly. The data sheet will show you how. The method will vary from chip to chip.

    However. . . . wait times, baud rates, etc will no longer be accurate after a clock speed change. You will need to compensate for this in your code.

    So in the above example, if you jack the frequency up from 32 to 64 MHz by setting the OSCFRQ bits with "OSCFRQ = 0b1111" .... then "Wait 100 us" will no longer be 100 us. It will be 50us. Baud 9600 will no longer be 9600, it will change to 19200. I2C and other calculated timings will change and may lead to unpredictable behavior. But It can be done and possibly useful if you are careful.

    I am not sure if you can change the frequency on-the-fly with Arduino. But I think not.

     

    Last edit: William Roth 2023-02-12
  • Anobium

    Anobium - 2023-02-12

    Let me explain some of the issues with this specific chip. These are NOT related to any other chip.

    The big assumption made with this chip is that is uses an external oscillator. And, the external oscillator is 16 mHz.
    The oscillator controlled via the fuses.
    As Bill Roth has stated the calcs for wait times, baud rates, I2C timing are based on 16 Mhz.
    Bringing these assumptions together means that there is no oscillator setup is the ASM ( therefore there is no oscillator setup with INITSYS() ).

    So, the calcs are based on external oscillator controlled by the fuses with no initsys(). The frequency must be 16Mhz.


    Assume for a moment that we could switch to the internal oscillator.

    Look at the datasheet, on page 369. The oscillator has variance of 10%. And, that oscillator is not calibrated (the factory default). It is not unreasonable to expect error as low as 1% for this. Microchip/Atmel provides a document for calibrating the oscillator yourself to 1% accuracy. But, is specific to each chip.

    I2C is a synchronous protocol, and timing accuracy is not relevant as long as minimum and maximum pulse times are respected. UART on the other hand is asynchronous, and then timing accuracy is important indeed. Most UARTs allow a half bit error in the last bit (the stop bit), so that's 5% for a 10 bit transmission. So, you will to complete the calibration procedure to get to 1%. If you calibrate then you can use the internal oscillator.

    To use the internal oscillator (post calibration) is therefore workable. This means that AVRDUDE and the Optibootloader now will not function as expected.- you have to use 57600bps for serial not 115300bps for AVRDUDE.

    Using the internal oscillator like this means you have to reprogram the chip with different fuses as this is the only way to change from the external oscillator to the internal oscillator.

    Once you have set the fuses, calibrated the chip, programmed the Optibootloader then I think you have the control you want.

    You can freely update the registers to control the frequency and therefore the power used.


    So, how do Arduino low power? See https://docs.arduino.cc/learn/electronics/low-power It is a bit of read but in passing it mentions the use of oscillators.


    Summary, I hopefully explained how Hugh designed and implemented mega328p support based upon a set of assumptions. I have given you insights into how to low the frequency. The external URL will give you more insights.

    I am sure other know way more than me about real world implementations of low power mega328ps.


    But, if you changed from an UNO with a mega328p to an UNO with an LGT8F328P then you get all the frequency control you need. As the LGT8F328P has a properly calibrated internal oscillator. See this on eBay or AliExpress


    Evan

     
  • Haroen

    Haroen - 2023-02-13

    I was testing with an Arduino Uno, Nano (16MHz max) and LGT8F328P (32MHz max) boards checking performances altogether. (At some times even forgot to switch back, compiling with too high frequency without the compiler giving an error on that?)

    Summary, I hopefully explained how Hugh designed and implemented mega328p support based upon a set of assumptions. I have given you insights into how to low the frequency.

    These essential explanations of you all show how important the first code line "#chip TYPE, FREQ" with frequency really is!

    Wait times, baud rates, I2C timing are based on 16 Mhz!
    UART could run on 32MHz if AVRDUDE and the Optibootloader work on 57600bps for serial and not 115300bps?

    I remember in my previous topic about SSD1306 i.c.w. oscilloscope that Stan didn't know why the LGT8F gave another curve than the Arduino Nano. Could it be the 32MHz frequency? I will try the LGT8F with 16MHz if that curve is ok.

     
    • Anobium

      Anobium - 2023-02-13

      Thank you.

      I think LGT is worth trying. Try lower frequencies. The power consumption results will be interesting.

      Good luck

      EDITED:

      Also see http://www.gammon.com.au/power This discusses a library. That library power.h could/should be easily ported to GCB and specificially the LGT.

       

      Last edit: Anobium 2023-02-13
  • stan cartwright

    stan cartwright - 2023-02-13

    Uno mega 328 runs at slower clock if run from 3.3V if any use. I found uot when trying to change pin logic levels. Pics don't work like that, logic levels drop but clock stays the same.

     

    Last edit: stan cartwright 2023-02-13
  • Haroen

    Haroen - 2023-02-14

    Good to know the difference in chip selection what is and is not supported.
    Thanks.

     

Log in to post a comment.