|
|
View previous topic :: View next topic |
Author |
Message |
georpo
Joined: 18 Nov 2008 Posts: 281 Location: Athens, Greece.
|
PIC24FJ128GA204 clock switching |
Posted: Thu May 07, 2020 12:21 pm |
|
|
Hello,
I am using a PIC24FJ128GA204 at 32MHz for a wireless e-paper label.
After it receives all data I want to switch clock frequency to 8MHz in order to minimize the current draw from the battery.
I can update the e-paper with 8MHz but I cannot keep up to the wireless receiver if not running at 32MHz.
What is the proper way of doing it?
And also informing the compiler for the new clock so it uses the correct delay and uart baud rate?
Code: |
#fuses NOWDT,NODEBUG,NOPROTECT,NOPR,FRC_PLL,OSCIO
#use delay(clock=32M,int)
|
Thanks!!! _________________ George. |
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1345
|
|
Posted: Thu May 07, 2020 1:10 pm |
|
|
You can setup some minimal fuses (but avoid any oscillator related ones, then use multiple #use delay() statements and set which peripherals use which clock underneath. For delays, you'll need to provide wrapper functions for the 8MHz so that the compiler will generate two copies of the delay functions. You can then use setup_oscillator to swap around speeds as needed. Something similar to this test program:
Code: |
#include <24FJ128GA204.h>
#fuses NOWDT,NODEBUG,NOPROTECT,OSCIO, CKSFSM
#use delay(clock=8M)
// place #use for any peripherals that use 8MHz clock
#inline
void delay_ms_8mhz(unsigned int16 ms){
delay_ms(ms);
}
#inline
void delay_us_8mhz(unsigned int16 us){
delay_us(us);
}
#use delay(internal=8M, clock=32M)
// place #use for any peripherals that use 32MHz clock
void main() {
unsigned int count = 0;
while(true){
if(count++ == 10){
setup_oscillator(OSC_INTERNAL, 8000000, 8000000);
delay_ms_8mhz(1000);
}else if(count == 50){
setup_oscillator(OSC_INTERNAL, 32000000,8000000);
delay_ms(1000);
}else if(count >= 70){
count = 0;
}
}
}
|
It will generate some "info" messages unfortunately, but they don't impact anything. The fuses aren't actually changed in this scenario (I tested in 5.093). |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19496
|
|
Posted: Thu May 07, 2020 11:42 pm |
|
|
I suspect you are talking about the UART baud rate being wrong after
the clock switches, so serial does not work. The way to change speed
and keep baud rate working is to specify the clock in a set_uart_speed line.
So:
Code: |
//to switch to 8MHz
setup_oscillator(OSC_8MHZ);
set_uart_speed(9600,YOUR_STREAM,8000000);
//to switch to 32MHz
setup_oscillator(OSC_32MHZ);
set_uart_speed(9600,YOUR_STREAM,32000000);
|
These are both assuming 9600bps, and the stream name needs to be set
to suit your usage. Also assuming the clock rates are done using the
internal oscillator.
The point is that when you change speed the setting for the UART also
has to be reset. The compiler offers the ability for you to tell the uart
speed function what clock rate you are actually running, to handle this. |
|
|
georpo
Joined: 18 Nov 2008 Posts: 281 Location: Athens, Greece.
|
|
Posted: Fri May 08, 2020 2:54 am |
|
|
Thank you guys for the help!!! _________________ George. |
|
|
|
|
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
|