Timing Probleme

Ich habe ein Problem mit dem Timing bzw der Zykluszeit des Arduinos. Bei mir läuft ein Code zur Generierung eines 30Hz PWM Signals. Ich kann nicht den Prescaler runtersetzen um den "normalen" OCR ausgang zu nutzten da ich auf die micros() und millis() angewisen bin. Ich habe bei meinen 10kB Programm eine Zyluszeit von 10ms mit Serial print und 8ms ohne. Dadurch habe ich keine möglichkeit meine eigene LOW_PWM laufen zu lassen
Das Problem ist dann folgendes ich kann mit meine Funktion keine Ontime(dutycyle) oberhalöb von 70% generiesen. kann ich jetzt mit dem Befehl ==>
noInterrupts();
// critical, time-sensitive code here

dann meine eigne Funktion ausführen lassen ohne unterbrechung laufen lassen weil die dann mit hoher Prio läuft.
Meine Funtion sieht so aus. Die Aktion muss man dann klar in die Loop aufnehmen. Ich will nur so mal ein denkfehler ausschließen

unsigned long pmicros;
int nextCall=HIGH;
int val=0;


void setup(){
  pinMode(13,OUTPUT);
 pinMode(12,OUTPUT);
 }

void loop(){
val=analogRead(0);
val=map(val,0,1023,1,100);
  Low_PWM(12,30,val);
  }

void Low_PWM(int Pin, int Fre, int Value){
long time;
long ontime;
time=1000000/Fre;
  ontime=time/100*Value;
  if (micros() - pmicros > time && nextCall==HIGH) {
    digitalWrite(Pin,HIGH);
    pmicros=micros();
    nextCall=LOW;
  }
  if (micros() - pmicros > ontime&& nextCall==LOW){ 
    digitalWrite(Pin,LOW);
    nextCall=HIGH;  
  }
}

Wenn Du noch Pins frei hast und Timer 1 und Timer 2 sonst nicht brauchst könntest Du ja per Timer 1 einen Takt für Timer 2 erezugen. D.h. Timer 1 als Vorteiler für Timer 2 mißbrauchen. Z.B. könntest Du mit Timer 1 den 16 Mhz Takt / 5333 auf 3000,1875 Hz vorteilen. Das dann als Takt in Timer 2 füttern und damit ein PWM Signal erzeugen.

Dann macht der Prozessor die Arbeit alleine und Du musst nicht kompliziert rumprogrammieren. Kostet aber 2 Pins und Timer 1 und 2 extra.

Alternativ könntest Du Dich auch in den Timer 0 Interrupt reinhängen. D.h. die Arduino Libs patchen.

Gruß, Udo

das wäre ne Lösung aber wie speise ich den Timer2 mit dem Timer1 den 0er brauche ich da ich die SPI schnittstelle verwende und das Nokia 3310 Lcd Shield. Ich muss wohl auf den Mega gehen den ich hier sowieso liegen habe. Kannst du das mit näher erlautern mit dem verknüpfen der beiden timer?

Danke

Naja, grundsätzlich schaut man sowas hier:
www.atmel.com/dyn/resources/prod_documents/doc8025.pdf.

Die interessanten Stellen sind:

15.11.2 TCCR1B – Timer/Counter1 Control Register B
? Bit 2:0 – CS12:0: Clock Select
The three Clock Select bits select the clock source to be used by the Timer/Counter, see Figure
15-10 and Figure 15-11.

16.3 External Clock Source
An external clock source applied to the T1/T0 pin can be used as Timer/Counter clock
...
An external clock source can not be prescaled.

17.11.8 ASSR – Asynchronous Status Register
? Bit 6 – EXCLK: Enable External Clock Input
When EXCLK is written to one, and asynchronous clock is selected, the external clock input buf-
fer is enabled and an external clock can be input on Timer Oscillator 1 (TOSC1) pin instead of a
32 kHz crystal. Writing to EXCLK should be done before asynchronous operation is selected.
Note that the crystal Oscillator will only run when this bit is zero.
? Bit 5 – AS2: Asynchronous Timer/Counter2
When AS2 is written to zero, Timer/Counter2 is clocked from the I/O clock, clkI/O. When AS2 is
written to one, Timer/Counter2 is clocked from a crystal Oscillator connected to the Timer Oscil-
lator 1 (TOSC1) pin. When the value of AS2 is changed, the contents of TCNT2, OCR2A,
OCR2B, TCCR2A and TCCR2B might be corrupted.

Du stellst also einen der Timer 1 oder 2 auf "external clock source" ein. Dann stellt Du den anderen Timer ein als PWM mit 50% Duty cycle und generierst damit den Takt für den anderen Timer der dann das eigentliche PWM generieren soll. Die Idee ist, daß damit einer der beiden Timer als Vorteiler arbeiten kann. Vermutlich ist es sogar besser Timer2 als Taktgenerator zu nehmen weil der Vorteiler unabhängig von Timer0 und 1 ist. Dann den Output von Timer2 in Timer1 als externen Takt und Timer1 für PWM konfigurieren.

Im Datenblatt ist das sehr ausführlich beschrieben. Man muss es sich nur einmal von vorne bis hinten durchlesen. Da steht auch genau wie man die Register setzen muß damit die gewünschte Frequenz rauskommt.

Ich würde so vorgehen, daß ich zunächst mal die Frequenzen ausrechne. Dann würde ich Timer 2 konfigurieren und schauen ob er tut wie er soll. Dann den Output mit dem Input von Timer 1 verbinden (Pins auch entsprechend als Input/Output konfigurieren) und schauen ob Timer 1 wie gewünscht läuft. Dann Timer 1 PWM Output konfigurieren und schauen ob es rauskommt wie es soll.

Hilfreich ist es auf den Arduino Kontakten dir "richtigen" Atmel Pin Bezeichnungen drauf zu schreiben damit man nicht dauern suchen muß.

Gruß, Udo

So ich bin zur Lösung meines Problems gekommen. Ich werde einfach eine Analogspannung nehmen und auf eine TL494 geben der Vorteil jede beliebige PWM Base Frequenz + variable ontime. Ist zwar ein Bauteil extra aber dann habe ich keine extremen aufwand auf meinem Microp