PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Welcher Controller hat 2 16BIT Timer



Smith-mini-plane
16.12.2013, 21:58
Hallo ,
habe an die Profis eine frage , welcher Controller hat zwei 16BIT Timer am besten mit DIL Gehäuse.
Habe zwei Programme die ich versuchen möchte, auf einen Controller zum laufen zu bringen,
Problem jeder Timer von den Programmen hat einen anderen Prescaler sind jedoch beide 16 Bit Timer.

Gruß und Danke für Euer Feedback.

Thomas

Kampi
16.12.2013, 22:51
Hey,

reicht dir der hier:

http://www.atmel.com/Images/doc2467.pdf

for_ro
16.12.2013, 23:10
... und in DIL wäre da der M1284 im 40-Pin Gehäuse. Evtl. gibt es auch noch andere.

Du kannst aber auch den Timer umkonfigurieren, wenn du das Programm wechselst.

oberallgeier
16.12.2013, 23:45
.. welcher Controller hat zwei 16BIT Timer am besten mit DIL Gehäuse ...
... und in DIL wäre da der M1284 im 40-Pin Gehäuse ...Sagn wir mal, 1 1/2 16-bit-Timer - oder hast Du den schon mal programmiert ? (Ich habe hier drei, vier am Laufen).
Ausserdem - den 128er gibts nach meiner Parametertabelle von Atmel (könnte aber schon überholt sein) nur als TQFP 64 und MLF 64. Der mega162 als TQFP 44, MLF 44 und PDIP 40 dürfte so ziemlich der Einzige mit der gewünschten Spezifikation sein. Selbstdie paar AT90CAN-Automotive-Typen gibts nicht in PDIP.

Kampi
17.12.2013, 06:05
Sagn wir mal, 1 1/2 16-bit-Timer - oder hast Du den schon mal programmiert ? (Ich habe hier drei, vier am Laufen).
Ausserdem - den 128er gibts nach meiner Parametertabelle von Atmel (könnte aber schon überholt sein) nur als TQFP 64 und MLF 64. Der mega162 als TQFP 44, MLF 44 und PDIP 40 dürfte so ziemlich der Einzige mit der gewünschten Spezifikation sein. Selbstdie paar AT90CAN-Automotive-Typen gibts nicht in PDIP.

Ach .... schmarn. Hab die Anforderung "DIL" überlesen...
Vergiss meinen Kommentar ^^
Mit ein bisschen Strickerei kann man doch sicher die 2 8-Bit Timer von einem Mega32 als 16-Bit Timer nutzen oder?

MagIO2
17.12.2013, 06:51
Der Propeller hat 16 x 32bit

oberallgeier
17.12.2013, 08:28
Ach Kampi .... schmarn. Hab die Anforderung "DIL" überlesen ...Schon gut *gg* - bin ja froh, wenn andere kurz vor Mitternacht auch schon mal nachlassen.


... Mit ein bisschen Strickerei kann man doch sicher die 2 8-Bit Timer ...Sollte schon gehen - mein 8bittiger Heartbeat-timer läuft z.B. mit 20 kHz und macht seinen Sekundenübergang demnach beim 20000 (nee, ich zähl runter, das geht besser - weil meiner Meinung nach die Abfage if ( !Izeit_2 ) schicker aussieht als der "Standard"). NUR - wenn ich die ersten dre Zeilen am Threadanfang lese, dann bin ich nicht sicher, ob der Kollege das so hinkriegt.

Na ja, schaugn wa mål ob er damit etwas anfangen kann (eben bei mir "nur" als C - ich kann kein Basic):

// ================================================== =========================== =
// === Initialisierung fuer Timer2 mega168 ==================================== =
// ##>>> Izeit_1 wird im main initialisiert
void TC2TMR_init(void) // Init Tmr/Cntr 2, 8-Bit auf 20 kHz = 50 µs
{ //
TCCR2A |= (1<<WGM21); // Timer im CTC-Mode, Top=OCR2A S 157
TCCR2B |= (1<<CS21); // Prescaler 1/8 / Clock <- CPU S 158
// OCR2A wird für den 50µs-Timer benutzt, OCR2B für einen restlichen Timer
OCR2A = 124; // Preset 124 für 50µs bei 20Mhz
OCR2B = 124; // dito
TIMSK2 |= (1<<OCIE2A); // Tmr/Cntr2 CompareA interrupt enabled für Rampe
TIMSK2 |= (1<<OCIE2B); // Tmr/Cntr2 CompareB interrupt enabled
} // Ende void TC2TMR_init(void)
// ================================================== =========================== =
// ================================================== =========================== =
// === Stoppen Timer2 mega168
void TC2_stop(void) // Stoppe Tmr/Cntr 2
{ //
TCCR2A &= ~(1<<WGM21); // Timer WGM21 resetten
TIMSK2 &= ~(1<<OCIE2A); // Tmr/Cntr2 CompA interrupt DIS abled
} // Ende void TC2_stop(void)
// ================================================== =========================== =

// ================================================== =========================== =
// === Nicht unterbrechbare ISR für timer2
// Routine zählt hoch im Takt 20 kHz = 50 µs. Der Zählerwert wird von den ISR für
// EXT_INT0 und -INT1 ausgelesen und den Werten Iz_yseci zugewiesen
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ISR(TIMER2_COMPA_vect) // Vektor 7
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
{ //
Izeit_1 --; // ###>>> Izeit_1 ist aktuell int16_t ==>>
// Izeit_1 bleibt bis 32000 in der int16-Grenze
//RCzeit1 ++; // Tupsicounter uint16_t für RC-5-Decoding
if ( Izeit_1 ) // Interrupt-Timer = 1 ... 20 000 ... (1 sec blink)
{ } // WENN Izeit_1 =|= Null => wahr => Anweisung ausgeführen
else // Izeit_1 = Null = unwahr, daher "else" ausführen
{ // Eine Sekunde ist voll =>
Izeit_1 = Izthrznt; // ansonsten: Rückstellen auf Zeithorizont
ToggleBit (PgLED, L1g); // gnLED toggeln HEARTBEAT <<####, aktuell PC1
Isecundn ++; // Sekundenzähler hochtackern, max 9 Std
} // Ende if (Izeit_1 )
return;
} // Ende ISR(TIMER2_COMPA_vect)
// ================================================== =========================== =

// ================================================== =========================== =
// === Nicht unterbrechbare ISR für timer2
// Takt Takt 20 kHz = 50 µs bei 20Mhz
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ISR(TIMER2_COMPB_vect) // Vekt 0x008, Timerroutine für "allgemeine Zwecke"
// - - - - - - - - - - - - - - - -
{ // .. die nicht so eng zeitgebunden sind
Izeit_2 --; // ###>>> Izeit_2 ist aktuell int16_t ==>>
if ( !Izeit_2 ) // WENN Izeit_2 != Null => wahr => Anweisung ausgeführen
{ // Eine Sekunde ist voll => Izeit_2 auf Hrznt_2 setzen
Izeit_2 = Hrznt_2; // ansonsten: Rückstellen auf Zeithorizont2
} // Ende if ( !Izeit_2 )
// - - - - - - - - - - - - - - - -
// PWM-Rampe für Motor1/Mot12
if ( tmot1 ) // Rampencounter > 0
{ //
tmot1 --; //
if ( !tmot1 ) // Wenn Rampenwert abgelaufen ist
{ //
M12ocr = M12ocr + M12inc; //##>>Übegang zu NEGATIVEn M12ocr möglich
// Es folgt Drehrichtungsumkehr NACH Nulldurchgang
if (-1 == M12ocr) Mrechtszur (); //
if ( 1 == M12ocr) Mrechtsvor (); //
// Setze OCR1A aus vorzeichenbehaftetem M12ocr
if (M12ocr >= 0) OCR1A = M12ocr; //
else OCR1A = -1*M12ocr; //
if (M12ocr == P1soll) tmot1 = 0; // Rampe12: Ende mit Sollwert erreicht
else tmot1 = tdek1; // ansonsten ReInit Timer auf Rampenwert
} // Ende if ( !tmot1 )
} // Ende von if ( tmot1 )
// - - - - - - - - - - - - - - - -
return;
} // Ende ISR(TIMER2_COMPB_vect)
// ================================================== =========================== =

Die Größen Izthrznt und Hrznt_2 sind 16bit unsigned Integer - weil Zeit eben fast nicht negativ werden kann. Damit ginge der Timer bis über 3 sekunden - mit dieser Doppeldecker-Technik.

Nachtrag:
Ach so, und diese Rechnerei mit der "Rampe" in der COMPB-ISR gehört zu einer Beschleunigungsrampe für nen DC-Motor - hier ist das nur noch drin, um einen Zweck für diese ISR zu belegen.

for_ro
17.12.2013, 12:05
Sagn wir mal, 1 1/2 16-bit-Timer - oder hast Du den schon mal programmiert ? (Ich habe hier drei, vier am Laufen).

Hallo oberallgeier,
was geht denn bei dem Timer1 und nicht beim Timer3?
Meine 1284p habe ich jedenfalls bisher immer als vollwertige 2x16bit angesehen, aber natürlich noch nicht jede Ecke überprüft.

oberallgeier
17.12.2013, 16:58
... was geht .. bei ... Timer1 und nicht beim Timer3 ... aber natürlich noch nicht jede Ecke überprüft.Ich kenne auch nicht jede Ecke des m1284.
Es ist ne Weile her, ich hatte meine Servoplatine (theor. 18 .. 20 Servos) programmiert und da wollte der ~3 trotz emsigen Bemühens und Lesen der dreißig Doku-Seiten nicht so wie ich wollte. Bei der Suche nach ner Möglichkeit fiel mir ein Ausweg in Form einer Variante mit dem Timer1-A/B ein, die schick und sauber läuft. Dies der Teil 1.

Teil 2 ist die Auskunft im Datenblatt
Peripheral Features
...
– One/two 16-bit Timer/Counter with Separate Prescaler, Compare Mode, and Capture Mode
so ne Bemerkung hatte ich schon mal nicht beachtet und es mit endlosen Mühen und einem krönenden Misserfolg bezahlt.

Smith-mini-plane
17.12.2013, 21:25
... und in DIL wäre da der M1284 im 40-Pin Gehäuse. Evtl. gibt es auch noch andere.

Du kannst aber auch den Timer umkonfigurieren, wenn du das Programm wechselst.

Hallo Zusammen,
erstmal danke für die Antworten
Werde mir mal den Atmega 1284 besorgen , den kann ich schon auf´s Steckbrett stecken !!

Anbei mal die zwei Programme die ich als eine eine Programm brauche.

["CODE"]$regfile = "m8def.dat"
$crystal = 1000000

$hwstack = 32 ' default use 32 for the hardware stack
$swstack = 10 ' default use 10 for the SW stack
$framesize = 40 ' default use 40 for the frame space

Config Portb = Output
Led1 Alias Portb.1
Led2 Alias Portb.2
Led3 Alias Portb.3

Config Portd.2 = Input
Portd.2 = 1
Eingang Alias Pind.2

Config Int0 = Change
On Int0 Signalmessung
Enable Interrupts
Enable Int0

' Bei Timer1 (65536) mit 1 MHz und Prescaler=1
' 1 Tick: 1/1000000 *1 = 1 us

Config Timer1 = Timer , Prescale = 1
Timer1 = 0
On Timer1 Timer1_isr
Enable Timer1
Enable Interrupts


Dim Servowert As Word 'Wert in us. Normal: ca. 1000..2000


Do

Select Case Servowert
Case 0 To 1333 :
Led1 = 1 : Led2 = 0 : Led3 = 0
Case 1334 To 1666 :
Led1 = 0 : Led2 = 1 : Led3 = 0
Case 1667 To 2500 :
Led1 = 0 : Led2 = 0 : Led3 = 1
End Select

Waitms 100

Loop
End


Signalmessung:
If Eingang = 1 Then 'Wenn Signal=1 dann
Timer1 = 0 ' bei Null im us Takt
Start Timer1 ' anfangen zu zaehlen '
Else 'sonst
Stop Timer1 ' Timer stoppen und
Servowert = Timer1 ' Wert uebergeben
End If
Return


Timer1_isr: 'Fehleranzeige..
Led1 = 1 ' ..sollte nicht eintreten
Led2 = 1
Led3 = 1
Wait 5
Return["/CODE"]

Anbei der zweite code
["CODE"]$regfile = "m8def.dat"
$crystal = 1000000

$hwstack = 32 ' default use 32 for the hardware stack
$swstack = 10 ' default use 10 for the SW stack
$framesize = 40 ' default use 40 for the frame space


Config Portb = Output

'Const Linkeranschlag = 35 'oder z.B. 40 ganz rechts - je nach Servo
'Const Rechteranschlag = 10 'oder z.B. 110 ganz links- je nach Servo

' Bei Timer1 (65536) mit 1 MHz und Prescaler=8
' 1 Tick: 1/1000000 *8 =8us
' 65536 - 63036 = 2500 * 8us = 20ms
' 65536 - 65411 = 125 * 8us = 1ms
' 65536 - 65286 = 250 * 8us = 2ms

Const 20ms = 63036
Const Rechteranschlag = 65411 '1ms
Const Linkeranschlag = 65286 '2ms Differenz=125

Config Timer1 = Timer , Prescale = 8
Timer1 = 20ms
On Timer1 Timer1_isr
Enable Timer1
Enable Interrupts

Dim Servo As Word '0..125

Dim Wiederholung As Byte
Dim I As Byte

Dim Analogwandler As Integer 'Variable zur Aufnahme des Wertes vom Analogwandler
Config Adc = Single , Prescaler = Auto , Reference = Avcc 'Analogwandler definieren
'Start Adc 'AD-Wandler starten (nach Config automatisch)


'Schnelles Hin- und Herschalten zwischen links und rechts:
For Wiederholung = 1 To 3 '3 mal
Servo = 0 'ganz links
Wait 1
Servo = 125 'ganz rechts
Wait 1
Next Wiederholung


'Langsames Hin- und Herschalten zwischen links und rechts:
For Wiederholung = 1 To 3 '3 mal
For I = 0 To 125 'langsam in eine Richtung
Servo = I
Waitms 20
Next

For I = 125 To 0 Step -1 'langsam in andere Richtung
Servo = I
Waitms 20
Next
Next Wiederholung

'Servostellung je nach Poti-Stellung:
Do
Analogwandler = Getadc(0) '0..1023
Servo = Analogwandler / 8 ' 0..127
Loop
End


Timer1_isr:
If Pinb.1 = 1 Then 'wenn 1 war
Portb.1 = 0 'dann aus und
Timer1 = 20ms ' Pause ca. 20 ms
Else 'sonst
Portb.1 = 1 'Impuls
Timer1 = Linkeranschlag + Servo ' für 1ms bis 2ms
End If
Return["/CODE"]


Habe beim ersten code schon mal probiert die werte * 8 zu erhöhen jedoch funktioniert leider nicht es geht nur eine LED auf dauer 1

Muß aber noch sagen das ich absoluter neuling GREENHORN bin .

Ich brauche doch die zwei 16 BIT Timer ???
Möchte ja mit meinem Fernsteuer Signal auch meine Servos steuern ( Sequenz), der ADC Poti Eingang im 2 Code fliegt raus.
Zur not kann ich auch zwei Controller nehmen und die Kommunikation über I/O ( Relais paralell zur LED ) nicht gerade Professionell aber funktioniert .

Wer eine gute Idee hat kann sich ja mal melden.

Bis dahin und nochmal Danke.

Gruß Thomas

P.S warum kann ich meinen Code nicht im Scroll-Fenster darstellen ??

["CODE"]
Ist doch richtig so ??
["/CODE"]

oberallgeier
17.12.2013, 22:02
... P.S warum kann ich meinen Code nicht im Scroll-Fenster darstellen ??

["CODE"]
Ist doch richtig so ??
["/CODE"]
Weil das so nur FAST richtig ist - Anführungsstriche weg - und schon funzt´s.

Siehe (aus "Anbei der zweite code") :

$regfile = "m8def.dat"
$crystal = 1000000$hwstack = 32 ' default use 32 for the hardware stack
$swstack = 10 ' default use 10 for the SW stack
$framesize = 40 ' default use 40 for the frame space

Config Portb = Output
'Const Linkeranschlag = 35 'oder z.B. 40 ganz rechts - je nach Servo
'Const Rechteranschlag = 10 'oder z.B. 110 ganz links- je nach Servo
' Bei Timer1 (65536) mit 1 MHz und Prescaler=8
' 1 Tick: 1/1000000 *8 =8us
' 65536 - 63036 = 2500 * 8us = 20ms
' 65536 - 65411 = 125 * 8us = 1ms
' 65536 - 65286 = 250 * 8us = 2ms
Const 20ms = 63036
Const Rechteranschlag = 65411 '1ms
Const Linkeranschlag = 65286 '2ms Differenz=125
Config Timer1 = Timer , Prescale = 8
Timer1 = 20ms
On Timer1 Timer1_isr
Enable Timer1
Enable Interrupts
Dim Servo As Word '0..125
Dim Wiederholung As Byte
Dim I As Byte
Dim Analogwandler As Integer 'Variable zur Aufnahme des Wertes vom Analogwandler
Config Adc = Single , Prescaler = Auto , Reference = Avcc 'Analogwandler definieren
'Start Adc 'AD-Wandler starten (nach Config automatisch)

'Schnelles Hin- und Herschalten zwischen links und rechts:
For Wiederholung = 1 To 3 '3 mal
Servo = 0 'ganz links
Wait 1
Servo = 125 'ganz rechts
Wait 1
Next Wiederholung

'Langsames Hin- und Herschalten zwischen links und rechts:
For Wiederholung = 1 To 3 '3 mal
For I = 0 To 125 'langsam in eine Richtung
Servo = I
Waitms 20
Next
For I = 125 To 0 Step -1 'langsam in andere Richtung
Servo = I
Waitms 20
Next
Next Wiederholung
'Servostellung je nach Poti-Stellung:
Do
Analogwandler = Getadc(0) '0..1023
Servo = Analogwandler / 8 ' 0..127
Loop
End

Timer1_isr:
If Pinb.1 = 1 Then 'wenn 1 war
Portb.1 = 0 'dann aus und
Timer1 = 20ms ' Pause ca. 20 ms
Else 'sonst
Portb.1 = 1 'Impuls
Timer1 = Linkeranschlag + Servo ' für 1ms bis 2ms
End If
Return

Allerdings sind durch das Kopieren evtl. vorhandene Einrückungen verloren gegangen.