-
Ich weiß nicht, ob deine version so genau ist, da die schleife so oft aufgerufen wird, wie du millisekundne pausieren willst. Habe keine Ahnung, wie lange der Mikrochip braucht, aber ich denke meine ist besser (abgesehen davon, dass ich das mit den x/72 übersehen hatte)
Die beste Lösung (meiner Meinung wäre:)
Code:
//Deklaration der Funktionen
void Schlafen(long milliseconds);
int d2i(double d); // Double --> Integer
void main()
{
Schlafen(1337); //Funktionsaufruf
}
void Schlafen(long milliseconds)
{
long i; //Wiederholungs-variable
long rest; //Was bei der Division übrig bleibt
milliseconds *= 72 // Da Sleep(72); = 1ms
i = d2i(milliseconds / 255);
rest = milliseconds - d2i(milliseconds / 255 )*255;
{
int a;
for(a=1;a<=i;a++)
{
sleep(255);
}
}
if(rest!=0){sleep(rest)};
}
int d2i(double d)
{
return d;
}
In deiner Funktion ist ein fehler... müsste wohl heißen:
Code:
for(a=0;a<=zeit;a++)
// anstatt...
for(a=0;a<=1000 zeit;a++)
[/code]
-
hast recht
hast Recht. war ein Fehler bei mir drin
-
Das was ich da vor langer Zeit mal gecoded hatte funktioniert übrigens auch recht gut aufm AVR (ATMega-2560 @16MHz)
Test mit AVR-Simulator:
Aufruf: delayMilliSeconds(137);
Dauer: 138.950us = 138,95ms
macht knapp 2% Fehler
Ich vermute sehr stark, dass das einfach ein konstanter Faktor ist, den man mit einrechnen. Der Großteil wird wohl konstant innerhalb folgender Schleife verbraten:
Code:
for (currentCycle=0; currentCycle < totalCycles; currentCycle++){
_delay_ms(MAXIMUM_DELAY_MS);
}
Lässt sich vermutlich recht einfach rausrechnen (3-4 Werte ins EXCEL-Sheet...)
Wers selber probieren will...
"myUtil.h"
Code:
#include "myUtil.c"
void delayMilliSeconds(long totalMs);
"myUtil.c"
Code:
/**
* Converts an double value to an integer
*/
int doubleToInteger(double d);
/**
* AVRs cannot sleep more than the following per _delay_ms()-Call
* MAXIMUM_DELAY_MS = 262,2ms / F_CPU_in_MHz
*/
#ifdef F_CPU
#define MAXIMUM_DELAY_MS (262 / (F_CPU / 1000000))
#endif
void delayMilliSeconds(long totalMs){
long totalCycles; // Max-number of cycles
long rest; // Rest of the flolowing integer-division
// Calculate the total amount of cycles neccessary to reach the wanted delay
totalCycles = doubleToInteger(totalMs / MAXIMUM_DELAY_MS);
// Calculate the rest that has been lost due to integer-division
rest = totalMs - (totalCycles * MAXIMUM_DELAY_MS);
// Will hold the current Cycle
int currentCycle;
// Work out all full cycles
for (currentCycle=0; currentCycle < totalCycles; currentCycle++){
_delay_ms(MAXIMUM_DELAY_MS);
}
// Work out the rest if there is one
if(rest != 0){
_delay_ms(rest);
}
}
int doubleToInteger(double d){
return d;
}