Because power consumption is directly depending on clock frequency, I usually use very low clock frequency when running in battery mode.
This is fine as long as I always run in this frequency, then I can set that in mP's project setting.
But sometimes it is necessary to rise the speed, i.e. if I connect the device to USB or Ethernet, because otherwise it will not work.
The easiest way is to use two oscillators (internal one for low speed, external XTAL for high speed) and to switch between them, but mikroPASCAL does not support that. Even if I can switch the oscillators, all timings will be wrong then, because mP doesn't correct all delays and timings.
It will be very helpful if I could switch the oscillator settings and -frequency at runtime.
Speed switching within running application
-
- Posts: 111
- Joined: 19 Sep 2006 21:21
- Location: Julian NC, US
- Contact:
It seems to me that clock speed is in the hardware domain rather than software. It should not be difficult to change the speed of an external clock from within the program by changing a single port bit. I would first try a VCO (voltage controlled oscillator) for the oscillator to assure a smooth transition. It will be the programmers responsibility to check the status of the speed control bit with each delay call and adjust the delay functions accordingly.
Constructing a suitable VCO with the operating range and low power consumption may prove to be a challenge.
Constructing a suitable VCO with the operating range and low power consumption may prove to be a challenge.
John Ferrell W8CCW
Rainer ,
I agree with you .. it would be handy to have a compiler directive to tell the compiler which clock speed is the current one if it differs from the one specified in the IDE .... So not at runtime ... but at compile time influence the delay_ms, delay_us and probably timings in the LCD libs too ..
Grx....
Eric
I agree with you .. it would be handy to have a compiler directive to tell the compiler which clock speed is the current one if it differs from the one specified in the IDE .... So not at runtime ... but at compile time influence the delay_ms, delay_us and probably timings in the LCD libs too ..
Grx....
Eric
Here is how it goes:
If you have a look at the provided library named __Lib_delays.mpas you will find the function named "VDelay_ms". The implementation of the routine is like this:
The routine calculates a variable delay depending on the oscilator speed. So if you want to change the oscillator at run time then you can easily modify this routine in such way that you do not use the run time constant Clock_kHz. Instead, you can easily invent a variable which will change its value depending how you run the oscillator.
I hope this helps.
If you have a look at the provided library named __Lib_delays.mpas you will find the function named "VDelay_ms". The implementation of the routine is like this:
Code: Select all
procedure VDelay_ms ( Time_ms : word );
var NumberOfCyc : dword;
begin
// Note: There has to be at least one addressing to the NumberOfCyc before
// while loop, so that the bank is set (if necessary) outside of this loop.
// That way it will have the smallest effect to the timings.
NumberOfCyc := Clock_kHz shr 2; // this will be done by compiler, no asm will be genereated except that for assignment;
NumberOfCyc := Time_ms * NumberOfCyc ;
if NumberOfCyc < 660 then
exit;
NumberOfCyc := NumberOfCyc - 660;
NumberOfCyc := NumberOfCyc shr 5; // Dec and While below take around 32 instructions
while (NumberOfCyc <> 0) do
begin
dec(NumberOfCyc);
asm
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
end;
end;
end;
The routine calculates a variable delay depending on the oscilator speed. So if you want to change the oscillator at run time then you can easily modify this routine in such way that you do not use the run time constant Clock_kHz. Instead, you can easily invent a variable which will change its value depending how you run the oscillator.
I hope this helps.
Rainer,
as such you are right, powerconsumption and clockrate are related. Microchip is aware of this and on recent chips actually refined this feature, you can selectively switch gear for CPU and peripherals making the issue you started even more complex.
I have done some projects involving battery-management/low power and found a ( primitive) solution in switching between normal speed and sleep only. This worked pretty well for that application but is obviously not a real cure for this. I feel this issue demonstrates once more how poor solution are delays in general, a reason all the more not to use them for timing but wherever to use timers. The moment you switch clokrate in your code you can correct for the relevant peripherals like SPI/Uart as these have their own clock-circuitry. At the moment all sensitive is gathered in the delays-unit, maybe some sort of realtime recalculation is possible in the future.
In this context USB and Ethernet are rather hungry peripherals, if you want to be low power oldfashioned Uart will be a better option.
as such you are right, powerconsumption and clockrate are related. Microchip is aware of this and on recent chips actually refined this feature, you can selectively switch gear for CPU and peripherals making the issue you started even more complex.
I have done some projects involving battery-management/low power and found a ( primitive) solution in switching between normal speed and sleep only. This worked pretty well for that application but is obviously not a real cure for this. I feel this issue demonstrates once more how poor solution are delays in general, a reason all the more not to use them for timing but wherever to use timers. The moment you switch clokrate in your code you can correct for the relevant peripherals like SPI/Uart as these have their own clock-circuitry. At the moment all sensitive is gathered in the delays-unit, maybe some sort of realtime recalculation is possible in the future.
In this context USB and Ethernet are rather hungry peripherals, if you want to be low power oldfashioned Uart will be a better option.
Au royaume des aveugles, les borgnes sont rois.
Hello!
@ zristic:
It would be a very good idea to do that what you suggested in the original unit. A little procedure (i.e. set_delay_frequ() ) could be called with that frequency, which the CPU currently is set to.
So I choose an oscillator (i.e. switch from internal to external with higher speed) and call then this procedure to adapt all timings to the new frequency the MCU now has.
Or do it through something like ConfigureCPUclock() and hand over there the currently selected CPU clock.
___
In general it is a problem with the compiler if the frequency changes, as all timings (not only some delay...() function) will be affected. So I am not able to use SoftUART then, it will surely use a finer or different timer, and others. Therefore such mechanism of speed switching must be anchored deeply inside, everything else is patchwork.
@ zristic:
It would be a very good idea to do that what you suggested in the original unit. A little procedure (i.e. set_delay_frequ() ) could be called with that frequency, which the CPU currently is set to.
So I choose an oscillator (i.e. switch from internal to external with higher speed) and call then this procedure to adapt all timings to the new frequency the MCU now has.
Or do it through something like ConfigureCPUclock() and hand over there the currently selected CPU clock.
___
In general it is a problem with the compiler if the frequency changes, as all timings (not only some delay...() function) will be affected. So I am not able to use SoftUART then, it will surely use a finer or different timer, and others. Therefore such mechanism of speed switching must be anchored deeply inside, everything else is patchwork.