PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Frequenzanzeige mit Atmega 32 ?



nase
31.08.2010, 12:19
Suche Hilfe bei meiner Frequenzanzeige mit dem Atmega 32 !
Habe einen Taktgenerator mit Bascom erstellt , nun möchte ich die erstellte Frequenz des Taktgenerators auf dem Display darstellen, habe aber das Problem das wenn ich den Takt zähle dieser ja hochgezählt wird , und so auch auf dem Display erscheint, also ich bekomme eine Fortlaufende Anzeige der Zählimpulse.
Nun möchte ich das die Anzeige aber bevor der Zähler wieder auf Null gesetzt um wieder neu zu zählen als fester Wert für eine bestimmte Zeit auf dem Display stehen bleibt . ( Bin Anfänger und wäre dankbar wenn mir jemand hilft der sich die Mühe macht es mir verständlich zu machen.

gruß Nase

Hier den benutzten Code:
interner 1 Mhz Takt
'
' Display an folgenden Ports
' Enable = Port C.4
' RS = Port C.5
' DB7 = Port C.7
' DB6 = Port C.6
' DB5 = Port C.3
' DB4 = Port C.2
'
' Leds an folgenden Ports
' Grün an A.0
'
$regfile "m32def.dat" 'Definiert den Atmega als Atmega 32
$crystal = 1000000 'Gibt die Quarzfrequenz an in Herz
$hwstack = 32 'Default use 32 for the hardware stack
$swstack = 10 'Default use 10 for the SW stack
'-------------------------------------------------------------------------------
' Konfiguration fürs Display
Config Lcd = 16 * 2 'definiert das LCD Display in Art und Größe
Config Lcdpin = Pin , Db4 = Portc.2 , Db5 = Portc.3 , Db6 = Portc.6 , Db7 = Portc.7 , Rs = Portc.5 , E = Portc.4

'------------------------------------------------------------------------------
' Variablen
Dim Takt1 As Word
Dim Takt2 As Word

'------------------------------------------------------------------------------
Enable Interrupts

Portb = &B00011110 ' Pull Up setzen für Pin B1
Ddra = &B11111111 ' Pin A.7 als Ausgang setzen für blaue Led
'------------------------------------------------------------------------------
' Timer 0
Config Timer0 = Timer , Prescale = 1024
Enable Timer0
On Timer0 Timer_null
'---------------------------------------
' Timer 1
Config Timer1 = Timer , Prescale = 64
Enable Timer1
On Timer1 Timer_eins

Cls
'------------------------- H A U P T P R O G R A M M --------------------------
Do
Gosub Anzeige

Waitms 500
Loop


'------------------------------ D I S P L A Y - A N Z E I G E -----------------
Anzeige:
Cls
Locate 1 , 1
Lcd "Takt" ; Takt1
Waitms 200
Return
'--------------------------------- T I M E R - 0 -----------------------------
Timer_null:
Toggle Porta.0 ' Led Grün
If Porta.7 = 1 And Porta.0 = 1 Then Takt1 = Takt1 + 1
If Porta.7 = 0 Then Takt1 = 0

Return

'--------------------------------- T I M E R - 1 ------------------------------
Timer_eins:
Toggle Porta.7 ' Led Blau
Return
'------------------------------------------------------------------------------

radbruch
31.08.2010, 13:48
So vielleicht?


' Display an folgenden Ports
' Enable = Port C.4
' RS = Port C.5
' DB7 = Port C.7
' DB6 = Port C.6
' DB5 = Port C.3
' DB4 = Port C.2
'
' Leds an folgenden Ports
' Grün an A.0
'
$regfile "m32def.dat" 'Definiert den Atmega als Atmega 32
$crystal = 1000000 'Gibt die Quarzfrequenz an in Herz
$hwstack = 32 'Default use 32 for the hardware stack
$swstack = 10 'Default use 10 for the SW stack
'-------------------------------------------------------------------------------
' Konfiguration fürs Display
Config Lcd = 16 * 2 'definiert das LCD Display in Art und Größe
Config Lcdpin = Pin , Db4 = Portc.2 , Db5 = Portc.3 , Db6 = Portc.6 , Db7 = Portc.7 , Rs = Portc.5 , E = Portc.4

'------------------------------------------------------------------------------
' Variablen
Dim Takt1 As Word
Dim Takt2 As Word
Dim Takt1_temp As Word
Dim Takt2_temp As Word
'------------------------------------------------------------------------------

Portb = &B00011110 ' Pull Up setzen für Pin B1
Ddra = &B11111111 ' Pin A.7 als Ausgang setzen für blaue Led
'------------------------------------------------------------------------------
' Timer 0
Config Timer0 = Timer , Prescale = 1024
Enable Timer0
On Timer0 Timer_null
'---------------------------------------
' Timer 1
Config Timer1 = Timer , Prescale = 64
Enable Timer1
On Timer1 Timer_eins

Enable Interrupts

Cls
'------------------------- H A U P T P R O G R A M M --------------------------
Do
Gosub Anzeige

Waitms 500
Loop


'------------------------------ D I S P L A Y - A N Z E I G E -----------------
Anzeige:

Disable Interrupts
Takt1 = Takt1_temp
Takt1_temp = 0
Takt2 = Takt2_temp
Takt2_temp = 0
Enable Interrupts

Cls
Locate 1 , 1
Lcd "Takt1" ; Takt1
Lcd "Takt2" ; Takt2
Return

'--------------------------------- T I M E R - 0 -----------------------------
Timer_null:
Toggle Porta.0 ' Led Grün
Takt1_temp = Takt1_temp + 1
Return

'--------------------------------- T I M E R - 1 ------------------------------
Timer_eins:
Toggle Porta.7 ' Led Blau
Takt2_temp = Takt2_temp + 1
Return
'------------------------------------------------------------------------------
(ungetestet)

Die Zählerstände werden alle 0,5 Sekunden angezeigt und auf null gesetzt. Da jeder Aufruf der Interruptroutinen gezählt wird, sollte das Display so direkt die Frequenz in Hz anzeigen.

Beim Lesen der 16-Bit Zählerstände werden die Interrupts kurz gesperrt. Das könnte zusammen mit der (Un-)Genauigkeit von Waitms 500 zu einem kleinen Messfehler führen.

Gruß

mic

nase
31.08.2010, 23:35
Danke für die schnelle Hilfe, hab's ausprobiert, und siehe da die Anzeige steht wirklich, allerdings blinkt die grüne Led ca 3 bis 4 mal in der Sekunde , das Display zeigt unter Takt1 den Wert 10 und unter Takt2 den Wert von 20 an.Genauen Werte werde ich noch einmal nachmessen und dann bekannt geben.
:lol:

Hab den Prescaler von Timer 1 von 64 auf 8 verringert, und bekomme immer noch den gleichen Wert bei Takt1 angezeigt, obwohl sich ja die Torzeit dadurch verringert hat.

radbruch
01.09.2010, 09:37
Hallo

Das war ja klar, dass es nicht auf Anhieb funktioniert ;)

Der Takt der grünen Led:
1000000Hz/256/1024 oder etwa 3,81Hz

Rote Led:
1000000Hz/256/64 oder etwa 61Hz
(Rot zu Grün wie 1024 zu 64 oder 61/16=3,8125)

Der grobe Fehler ist sicher die Zeitmessung mit waitms. Dazu kommen noch die Funktionsaufrufe und die Ausgaben zum LCD. Wissenschaftlicher wäre die Verwendung eines zusätzlichen Timers zum Auslesen der Frequenzzähler:


' Display an folgenden Ports
' Enable = Port C.4
' RS = Port C.5
' DB7 = Port C.7
' DB6 = Port C.6
' DB5 = Port C.3
' DB4 = Port C.2
'
' Leds an folgenden Ports
' Grün an A.0
'
$regfile "m32def.dat" 'Definiert den Atmega als Atmega 32
$crystal = 1000000 'Gibt die Quarzfrequenz an in Herz
$hwstack = 32 'Default use 32 for the hardware stack
$swstack = 10 'Default use 10 for the SW stack
'-------------------------------------------------------------------------------
' Konfiguration fürs Display
Config Lcd = 16 * 2 'definiert das LCD Display in Art und Größe
Config Lcdpin = Pin , Db4 = Portc.2 , Db5 = Portc.3 , Db6 = Portc.6 , Db7 = Portc.7 , Rs = Portc.5 , E = Portc.4

'------------------------------------------------------------------------------
' Variablen
Dim Takt1 As Word
Dim Takt2 As Word
Dim Takt3 As Word
Dim Takt1_temp As Word
Dim Takt2_temp As Word
'------------------------------------------------------------------------------

Portb = &B00011110 ' Pull Up setzen für Pin B1
Ddra = &B11111111 ' Pin A.7 als Ausgang setzen für blaue Led
'------------------------------------------------------------------------------
' Timer 0
Config Timer0 = Timer , Prescale = 1024
Enable Timer0
On Timer0 Timer_null
'---------------------------------------
' Timer 1
Config Timer1 = Timer , Prescale = 64
Enable Timer1
On Timer1 Timer_eins
'---------------------------------------
' Timer 2
Config Timer2 = Timer , Prescale = 8
Ocr2 = 6 'nach 250 Zählschritten folgt der Interrupt
Enable Timer2
On Timer2 Timer_zwei

Enable Interrupts

Takt3 = 0
Cls
'------------------------- H A U P T P R O G R A M M --------------------------
Do
Gosub Anzeige

Waitms 300
Loop


'------------------------------ D I S P L A Y - A N Z E I G E -----------------
Anzeige:
Cls
Locate 1 , 1
Lcd "Takt1: " ; Takt1
Lcd "Takt2: " ; Takt2
Return

'--------------------------------- T I M E R - 0 -----------------------------
Timer_null:
Toggle Porta.0 ' Led Grün
Takt1_temp = Takt1_temp + 1
Return

'--------------------------------- T I M E R - 1 ------------------------------
Timer_eins:
Toggle Porta.7 ' Led Blau
Takt2_temp = Takt2_temp + 1
Return

'--------------------------------- T I M E R - 2 ------------------------------
'Die Werte werden jede 1/2 Sekunde ausgelesen. Das Setup des Timers sieht so aus:
'1MHz mit Prescaler/8 ergibt 125000 Timertakte pro Sekunde. Das Zählregister startet
'mit 6, nach 250 Schritten erfolgt der Interrupt. Das ergibt 125000/250=500 Interrupts
'pro Sekunde.Nach 250 Interrupts werden dann die Werte eingelesen und zurückgesetzt.
'Die Frequenzkorrektur berücksichtigt auch die Takte, die schon gezählt wurden und
'entfernt zusätzliche 3 Takte für Laden, Berechnen und Speichern des OCR2-Wertes.
Timer_zwei:
Ocr2 = Ocr2 + 9 'Frequenzkorrektur (256-6-3)
If Takt3 < 250 Then
Takt3 = Takt3 + 1
Else
Takt3 = 0
Takt1 = Takt1_temp 'Zähler auslesen und resten
Takt1_temp = 0
Takt2 = Takt2_temp
Takt2_temp = 0
End If
Return
'------------------------------------------------------------------------------
(ungetestet)

Ich hoffe, das passt jetzt so in etwa. Ich bin mir nicht sicher, ob OCR2 wirklich mit 6 oder nur mit 5 starten muss.

Gruß

mic

nasen58
01.09.2010, 22:31
Hallo

Das war ja klar, dass es nicht auf Anhieb funktioniert ;)

Der Takt der grünen Led:
1000000Hz/256/1024 oder etwa 3,81Hz

Rote Led:
1000000Hz/256/64 oder etwa 61Hz
(Rot zu Grün wie 1024 zu 64 oder 61/16=3,8125)

Der grobe Fehler ist sicher die Zeitmessung mit waitms. Dazu kommen noch die Funktionsaufrufe und die Ausgaben zum LCD. Wissenschaftlicher wäre die Verwendung eines zusätzlichen Timers zum Auslesen der Frequenzzähler:


' Display an folgenden Ports
' Enable = Port C.4
' RS = Port C.5
' DB7 = Port C.7
' DB6 = Port C.6
' DB5 = Port C.3
' DB4 = Port C.2
'
' Leds an folgenden Ports
' Grün an A.0
'
$regfile "m32def.dat" 'Definiert den Atmega als Atmega 32
$crystal = 1000000 'Gibt die Quarzfrequenz an in Herz
$hwstack = 32 'Default use 32 for the hardware stack
$swstack = 10 'Default use 10 for the SW stack
'-------------------------------------------------------------------------------
' Konfiguration fürs Display
Config Lcd = 16 * 2 'definiert das LCD Display in Art und Größe
Config Lcdpin = Pin , Db4 = Portc.2 , Db5 = Portc.3 , Db6 = Portc.6 , Db7 = Portc.7 , Rs = Portc.5 , E = Portc.4

'------------------------------------------------------------------------------
' Variablen
Dim Takt1 As Word
Dim Takt2 As Word
Dim Takt3 As Word
Dim Takt1_temp As Word
Dim Takt2_temp As Word
'------------------------------------------------------------------------------

Portb = &B00011110 ' Pull Up setzen für Pin B1
Ddra = &B11111111 ' Pin A.7 als Ausgang setzen für blaue Led
'------------------------------------------------------------------------------
' Timer 0
Config Timer0 = Timer , Prescale = 1024
Enable Timer0
On Timer0 Timer_null
'---------------------------------------
' Timer 1
Config Timer1 = Timer , Prescale = 64
Enable Timer1
On Timer1 Timer_eins
'---------------------------------------
' Timer 2
Config Timer2 = Timer , Prescale = 8
Ocr2 = 6 'nach 250 Zählschritten folgt der Interrupt
Enable Timer2
On Timer2 Timer_zwei

Enable Interrupts

Takt3 = 0
Cls
'------------------------- H A U P T P R O G R A M M --------------------------
Do
Gosub Anzeige

Waitms 300
Loop


'------------------------------ D I S P L A Y - A N Z E I G E -----------------
Anzeige:
Cls
Locate 1 , 1
Lcd "Takt1: " ; Takt1
Lcd "Takt2: " ; Takt2
Return

'--------------------------------- T I M E R - 0 -----------------------------
Timer_null:
Toggle Porta.0 ' Led Grün
Takt1_temp = Takt1_temp + 1
Return

'--------------------------------- T I M E R - 1 ------------------------------
Timer_eins:
Toggle Porta.7 ' Led Blau
Takt2_temp = Takt2_temp + 1
Return

'--------------------------------- T I M E R - 2 ------------------------------
'Die Werte werden jede 1/2 Sekunde ausgelesen. Das Setup des Timers sieht so aus:
'1MHz mit Prescaler/8 ergibt 125000 Timertakte pro Sekunde. Das Zählregister startet
'mit 6, nach 250 Schritten erfolgt der Interrupt. Das ergibt 125000/250=500 Interrupts
'pro Sekunde.Nach 250 Interrupts werden dann die Werte eingelesen und zurückgesetzt.
'Die Frequenzkorrektur berücksichtigt auch die Takte, die schon gezählt wurden und
'entfernt zusätzliche 3 Takte für Laden, Berechnen und Speichern des OCR2-Wertes.
Timer_zwei:
Ocr2 = Ocr2 + 9 'Frequenzkorrektur (256-6-3)
If Takt3 < 250 Then
Takt3 = Takt3 + 1
Else
Takt3 = 0
Takt1 = Takt1_temp 'Zähler auslesen und resten
Takt1_temp = 0
Takt2 = Takt2_temp
Takt2_temp = 0
End If
Return
'------------------------------------------------------------------------------
(ungetestet)

Ich hoffe, das passt jetzt so in etwa. Ich bin mir nicht sicher, ob OCR2 wirklich mit 6 oder nur mit 5 starten muss.

Gruß

mic

Ich glaube da fehlt etwas , kann nicht erkennen wozu Takt3 da ist ?
Takt3 wird in Zeile 51 auf Null gesetzt , dann noch einmal in den Zeilen 90 bis 93 abgefragt, aber dann nicht mehr benutzt ?????

Außerdem zeigt mir das Display unter Takt1: den Wert 2
und unter Takt2: den Wert0 an


Gruß nase

radbruch
01.09.2010, 23:37
Ojeojeoje. Es ist eben immer schlecht, wenn man es nicht selbst testen kann. Beim Timer2 sollte man schon das Zählregister TCNT2 manipulieren, OCR2 ist hier völlig falsch.

Takt3 zählt die Aufrufe der Interruptroutine des Timer2. Solange Takt3 kleiner als 250 ist wird es erhöht. Bei 250 sollte eine halbe Sekunde vergangen sein. Es werden dann die Zählerstände von Taktx_temp nach Taktx kopiert und die Taktx_temp gelöscht. Takt3 wird wieder auf null gesetzt und das Spiel beginnt von vorne.


If Takt3 < 250 Then 'solange Takt3 kleiner 250
Takt3 = Takt3 + 1 'Takt3 erhöhen
Else 'die 1/2 Sek. ist vorbei
Takt3 = 0 'Takt3 reseten
Takt1 = Takt1_temp 'Zähler auslesen
Takt1_temp = 0 'und reseten
Takt2 = Takt2_temp
Takt2_temp = 0
End If


Gleichzeitig werden ca. alle 300ms die aktuellen Werte von Takt1 und 2 am LCD ausgegeben. Der Code mit dem richtigen TCNT2-Register sieht dann so aus:


' Display an folgenden Ports
' Enable = Port C.4
' RS = Port C.5
' DB7 = Port C.7
' DB6 = Port C.6
' DB5 = Port C.3
' DB4 = Port C.2
'
' Leds an folgenden Ports
' Grün an A.0
'
$regfile "m32def.dat" 'Definiert den Atmega als Atmega 32
$crystal = 1000000 'Gibt die Quarzfrequenz an in Herz
$hwstack = 32 'Default use 32 for the hardware stack
$swstack = 10 'Default use 10 for the SW stack
'-------------------------------------------------------------------------------
' Konfiguration fürs Display
Config Lcd = 16 * 2 'definiert das LCD Display in Art und Größe
Config Lcdpin = Pin , Db4 = Portc.2 , Db5 = Portc.3 , Db6 = Portc.6 , Db7 = Portc.7 , Rs = Portc.5 , E = Portc.4

'------------------------------------------------------------------------------
' Variablen
Dim Takt1 As Word
Dim Takt2 As Word
Dim Takt3 As Word
Dim Takt1_temp As Word
Dim Takt2_temp As Word
'------------------------------------------------------------------------------

Portb = &B00011110 ' Pull Up setzen für Pin B1
Ddra = &B11111111 ' Pin A.7 als Ausgang setzen für blaue Led
'------------------------------------------------------------------------------
' Timer 0
Config Timer0 = Timer , Prescale = 1024
Enable Timer0
On Timer0 Timer_null
'---------------------------------------
' Timer 1
Config Timer1 = Timer , Prescale = 64
Enable Timer1
On Timer1 Timer_eins
'---------------------------------------
' Timer 2
Config Timer2 = Timer , Prescale = 8
Tcnt2 = 6 'nach 250 Zählschritten folgt der Interrupt
Enable Timer2
On Timer2 Timer_zwei

Enable Interrupts

Takt3 = 0
Cls
'------------------------- H A U P T P R O G R A M M --------------------------
Do
Gosub Anzeige

Waitms 300
Loop


'------------------------------ D I S P L A Y - A N Z E I G E -----------------
Anzeige:
Cls
Locate 1 , 1
Lcd "Takt1: " ; Takt1
Lcd "Takt2: " ; Takt2
Return

'--------------------------------- T I M E R - 0 -----------------------------
Timer_null:
Toggle Porta.0 ' Led Grün
Takt1_temp = Takt1_temp + 1
Return

'--------------------------------- T I M E R - 1 ------------------------------
Timer_eins:
Toggle Porta.7 ' Led Blau
Takt2_temp = Takt2_temp + 1
Return

'--------------------------------- T I M E R - 2 ------------------------------
'Die Werte werden jede 1/2 Sekunde ausgelesen. Das Setup des Timers sieht so aus:
'1MHz mit Prescaler/8 ergibt 125000 Timertakte pro Sekunde. Das Zählregister startet
'mit 6, nach 250 Schritten erfolgt der Interrupt. Das ergibt 125000/250=500 Interrupts
'pro Sekunde.Nach 250 Interrupts werden dann die Werte eingelesen und zurückgesetzt.
'Die Frequenzkorrektur berücksichtigt auch die Takte, die schon gezählt wurden und
'entfernt zusätzliche 3 Takte für Laden, Berechnen und Speichern des TCNT2-Wertes.
Timer_zwei:
Tcnt2 = Tcnt2 + 9 'Frequenzkorrektur (256-6-3)
If Takt3 < 250 Then 'solange Takt3 kleiner 250
Takt3 = Takt3 + 1 'Takt3 erhöhen
Else 'die 1/2 Sek. vorbei
Takt3 = 0 'Takt3 reseten
Takt1 = Takt1_temp 'Zähler auslesen
Takt1_temp = 0 'und reseten
Takt2 = Takt2_temp
Takt2_temp = 0
End If
Return
'------------------------------------------------------------------------------

Zum Debuggen könnte man im else-Zweig in der Timer2-ISR noch eine Led togglen. Die sollte dann mit 1 Hz blinken.

Hast du inzwischen die Takte1 und 2 mal nachgemessen? Viele Multimeter können auch Frequenzen messen.

Gruß

mic

nasen58
02.09.2010, 08:37
Ok, hab im Zweig in des Timer2-ISR noch eine Rote Led angeschlossen.

Hab immer noch eine Anzeige von Takt1=2 und Takt2=0
[/img]

Signal1a
Blaue Led hat 0,12 Hz ( obere Signal)
Grüne Led hat 1,93 Hz ( untere Signal)

Signal2a
Rote Led hat 1,05 Hz

radbruch
03.09.2010, 17:20
Hallo

Timer 1 ist doch ein 16Bit-Timer. Deshalb muss man auch hier das Zählregister in der ISR manipulieren um ein messbares Ergebniss zu erhalten:


' Display an folgenden Ports
' Enable = Port C.4
' RS = Port C.5
' DB7 = Port C.7
' DB6 = Port C.6
' DB5 = Port C.3
' DB4 = Port C.2
'
' Leds an folgenden Ports
' Grün an A.0
'
$regfile "m32def.dat" 'Definiert den Atmega als Atmega 32
$crystal = 1000000 'Gibt die Quarzfrequenz an in Herz
$hwstack = 32 'Default use 32 for the hardware stack
$swstack = 10 'Default use 10 for the SW stack
'-------------------------------------------------------------------------------
' Konfiguration fürs Display
Config Lcd = 16 * 2 'definiert das LCD Display in Art und Größe
Config Lcdpin = Pin , Db4 = Portc.2 , Db5 = Portc.3 , Db6 = Portc.6 , Db7 = Portc.7 , Rs = Portc.5 , E = Portc.4

'------------------------------------------------------------------------------
' Variablen
Dim Takt1 As Word
Dim Takt2 As Word
Dim Takt3 As Word
Dim Takt1_temp As Word
Dim Takt2_temp As Word
'------------------------------------------------------------------------------

Portb = &B00011110 ' Pull Up setzen für Pin B1
Ddra = &B11111111 ' Pin A.7 als Ausgang setzen für blaue Led
'------------------------------------------------------------------------------
' Timer 0
Config Timer0 = Timer , Prescale = 1024
Enable Timer0
On Timer0 Timer_null
'---------------------------------------
' Timer 1
Config Timer1 = Timer , Prescale = 64
Tcnt1 = 65280 '16Bit! 65536-256
Enable Timer1
On Timer1 Timer_eins
'---------------------------------------
' Timer 2
Config Timer2 = Timer , Prescale = 8
Tcnt2 = 6 'nach 250 Zählschritten folgt der Interrupt
Enable Timer2
On Timer2 Timer_zwei

Enable Interrupts

Takt3 = 0
Cls
'------------------------- H A U P T P R O G R A M M --------------------------
Do
Gosub Anzeige

Waitms 300
Loop


'------------------------------ D I S P L A Y - A N Z E I G E -----------------
Anzeige:
Cls
Locate 1 , 1
Lcd "Takt1: " ; Takt1
Lcd "Takt2: " ; Takt2
Return

'--------------------------------- T I M E R - 0 -----------------------------
Timer_null:
Toggle Porta.0 ' Led Grün
Takt1_temp = Takt1_temp + 1
Return

'--------------------------------- T I M E R - 1 ------------------------------
Timer_eins:
Tcnt1 = Tcnt1+65283 '16Bit! 65536-256+3
Toggle Porta.7 ' Led Blau
Takt2_temp = Takt2_temp + 1
Return

'--------------------------------- T I M E R - 2 ------------------------------
'Die Werte werden jede 1/2 Sekunde ausgelesen. Das Setup des Timers sieht so aus:
'1MHz mit Prescaler/8 ergibt 125000 Timertakte pro Sekunde. Das Zählregister startet
'mit 6, nach 250 Schritten erfolgt der Interrupt. Das ergibt 125000/250=500 Interrupts
'pro Sekunde.Nach 250 Interrupts werden dann die Werte eingelesen und zurückgesetzt.
'Die Frequenzkorrektur berücksichtigt auch die Takte, die schon gezählt wurden und
'entfernt zusätzliche 3 Takte für Laden, Berechnen und Speichern des TCNT2-Wertes.
Timer_zwei:
Tcnt2 = Tcnt2 + 9 'Frequenzkorrektur (256-6-3)
If Takt3 < 250 Then 'solange Takt3 kleiner 250
Takt3 = Takt3 + 1 'Takt3 erhöhen
Else 'die 1/2 Sek. vorbei
Takt3 = 0 'Takt3 reseten
Takt1 = Takt1_temp 'Zähler auslesen
Takt1_temp = 0 'und reseten
Takt2 = Takt2_temp
Takt2_temp = 0
End If
Return
'------------------------------------------------------------------------------

Meine Frequenzberechnungen ergeben die Anzahl der ISR-Aufrufe. Die effektive Frequenz an der Led muss man natürlich halbieren.... (nobody is perfect ;)


Mein Testprogramm für den mit 8MHz getakteten RP6:

$regfile "m32def.dat" 'Definiert den Atmega als Atmega 32
$crystal = 8000000 'Gibt die Quarzfrequenz an in Herz
$hwstack = 32 'Default use 32 for the hardware stack
$swstack = 10 'Default use 10 for the SW stack
$baud = 38400
'-------------------------------------------------------------------------------
'Led1 PC4
'Led2 PC5
'LED3 PC6
'------------------------------------------------------------------------------
' Variablen
Dim Takt1 As Word
Dim Takt2 As Word
Dim Takt3 As Word
Dim Takt1_temp As Word
Dim Takt2_temp As Word
'------------------------------------------------------------------------------

Ddrc = &B01110000 ' PC4-6 sind die Leds
'------------------------------------------------------------------------------
' Timer 0
Config Timer0 = Timer , Prescale = 1024
Enable Timer0
On Timer0 Timer_null
'---------------------------------------
' Timer 1
Config Timer1 = Timer , Prescale = 64
Tcnt1 = 65280 '16Bit! 65536-256
Enable Timer1
On Timer1 Timer_eins
'---------------------------------------
' Timer 2
Config Timer2 = Timer , Prescale = 64 'RP6 mit 8MHz
Tcnt2 = 6 'nach 250 Zählschritten folgt der Interrupt
Enable Timer2
On Timer2 Timer_zwei

Enable Interrupts

Takt3 = 0
Cls
'------------------------- H A U P T P R O G R A M M --------------------------
Do
Gosub Anzeige

Waitms 300
Loop


'------------------------------ D I S P L A Y - A N Z E I G E -----------------
Anzeige:
Print "Takt1: " ; Takt1
Print "Takt2: " ; Takt2
Print
Return

'--------------------------------- T I M E R - 0 -----------------------------
Timer_null:
Toggle Portc.4 ' Led 1
Takt1_temp = Takt1_temp + 1
Return

'--------------------------------- T I M E R - 1 ------------------------------
Timer_eins:
Tcnt1 = Tcnt1+65283 '16Bit! 65536-256+3
Toggle Portc.5 ' Led 2
Takt2_temp = Takt2_temp + 1
Return

'--------------------------------- T I M E R - 2 ------------------------------
'Die Werte werden jede 1/2 Sekunde ausgelesen. Das Setup des Timers sieht so aus:
'1MHz mit Prescaler/8 ergibt 125000 Timertakte pro Sekunde. Das Zählregister startet
'mit 6, nach 250 Schritten erfolgt der Interrupt. Das ergibt 125000/250=500 Interrupts
'pro Sekunde.Nach 250 Interrupts werden dann die Werte eingelesen und zurückgesetzt.
'Die Frequenzkorrektur berücksichtigt auch die Takte, die schon gezählt wurden und
'entfernt zusätzliche 3 Takte für Laden, Berechnen und Speichern des TCNT2-Wertes.
Timer_zwei:
Tcnt2 = Tcnt2 + 9 'Frequenzkorrektur (256-6-3)
If Takt3 < 250 Then 'solange Takt3 kleiner 250
Takt3 = Takt3 + 1 'Takt3 erhöhen
Else 'die 1/2 Sek. vorbei
Toggle Portc.6 ' Led 3
Takt3 = 0 'Takt3 reseten
Takt1 = Takt1_temp 'Zähler auslesen
Takt1_temp = 0 'und reseten
Takt2 = Takt2_temp
Takt2_temp = 0
End If
Return
'------------------------------------------------------------------------------

Die Ausgabe:

Takt1: 15
Takt2: 244

Takt1: 15
Takt2: 244

Takt1: 15
Takt2: 245

Takt1: 15
Takt2: 245


Gruß

mic

nase
03.09.2010, 20:31
Hab dein Testprogramm getestet, bzw, versucht zu testen , bekam beim Comilieren gleich folgende Fehlermeldungen:

Zeile 40 Assignment error TCNT 1:0
Zeile 79 Invalid Datatype [0007]
Zeile 79 Interrupt needs return

Um nochmal zum eigentlichen Thema zurück zu kommen, es geht mir nicht um die Genauigkeit der Anzeige, zumindest jetzt noch nicht , evtl wenn ich mal weiter bin.
Es geht mir in der Hauptsache darum eine Stabile Anzeige auf dem Display zu erhalten.

gruß Nase

radbruch
03.09.2010, 20:58
Hallo

Seltsam, mein Bascom (Demo 1.11.9.8) schluckt das anstandslos. TCNT2 funktioniert bei dir ja auch. Hier eine Variante in der TCNT1 durch TIMER1 ersetzt ist:


' Display an folgenden Ports
' Enable = Port C.4
' RS = Port C.5
' DB7 = Port C.7
' DB6 = Port C.6
' DB5 = Port C.3
' DB4 = Port C.2
'
' Leds an folgenden Ports
' Grün an A.0
'
$regfile "m32def.dat" 'Definiert den Atmega als Atmega 32
$crystal = 1000000 'Gibt die Quarzfrequenz an in Herz
$hwstack = 32 'Default use 32 for the hardware stack
$swstack = 10 'Default use 10 for the SW stack
'-------------------------------------------------------------------------------
' Konfiguration fürs Display
Config Lcd = 16 * 2 'definiert das LCD Display in Art und Größe
Config Lcdpin = Pin , Db4 = Portc.2 , Db5 = Portc.3 , Db6 = Portc.6 , Db7 = Portc.7 , Rs = Portc.5 , E = Portc.4

'------------------------------------------------------------------------------
' Variablen
Dim Takt1 As Word
Dim Takt2 As Word
Dim Takt3 As Word
Dim Takt1_temp As Word
Dim Takt2_temp As Word
'------------------------------------------------------------------------------

Portb = &B00011110 ' Pull Up setzen für Pin B1
Ddra = &B11111111 ' Pin A.7 als Ausgang setzen für blaue Led
'------------------------------------------------------------------------------
' Timer 0
Config Timer0 = Timer , Prescale = 1024
Enable Timer0
On Timer0 Timer_null
'---------------------------------------
' Timer 1
Config Timer1 = Timer , Prescale = 64
Timer1 = 65280 '16Bit! 65536-256
Enable Timer1
On Timer1 Timer_eins
'---------------------------------------
' Timer 2
Config Timer2 = Timer , Prescale = 8
Tcnt2 = 6 'nach 250 Zählschritten folgt der Interrupt
Enable Timer2
On Timer2 Timer_zwei

Enable Interrupts

Takt3 = 0
Cls
'------------------------- H A U P T P R O G R A M M --------------------------
Do
Gosub Anzeige

Waitms 300
Loop


'------------------------------ D I S P L A Y - A N Z E I G E -----------------
Anzeige:
Cls
Locate 1 , 1
Lcd "Takt1:" ; Takt1
Lcd "Takt2:" ; Takt2
Return

'--------------------------------- T I M E R - 0 -----------------------------
Timer_null:
Toggle Porta.0 ' Led Grün
Takt1_temp = Takt1_temp + 1
Return

'--------------------------------- T I M E R - 1 ------------------------------
Timer_eins:
Timer1 = Timer1 + 65283 '16Bit! 65536-256+3
Toggle Porta.7 ' Led Blau
Takt2_temp = Takt2_temp + 1
Return

'--------------------------------- T I M E R - 2 ------------------------------
'Die Werte werden jede 1/2 Sekunde ausgelesen. Das Setup des Timers sieht so aus:
'1MHz mit Prescaler/8 ergibt 125000 Timertakte pro Sekunde. Das Zählregister startet
'mit 6, nach 250 Schritten erfolgt der Interrupt. Das ergibt 125000/250=500 Interrupts
'pro Sekunde.Nach 250 Interrupts werden dann die Werte eingelesen und zurückgesetzt.
'Die Frequenzkorrektur berücksichtigt auch die Takte, die schon gezählt wurden und
'entfernt zusätzliche 3 Takte für Laden, Berechnen und Speichern des TCNT2-Wertes.
Timer_zwei:
Tcnt2 = Tcnt2 + 9 'Frequenzkorrektur (256-6-3)
If Takt3 < 250 Then 'solange Takt3 kleiner 250
Takt3 = Takt3 + 1 'Takt3 erhöhen
Else 'die 1/2 Sek. vorbei
Takt3 = 0 'Takt3 reseten
Takt1 = Takt1_temp 'Zähler auslesen
Takt1_temp = 0 'und reseten
Takt2 = Takt2_temp
Takt2_temp = 0
End If
Return
'------------------------------------------------------------------------------

Ich bin halt leider nicht so sehr der Bascom-Profi :(

Gruß

mic

nase
04.09.2010, 08:00
Super, diesmal hat's geklappt !
Funktioniert wunderbar bekomme als Display Anzeige den Wert Takt1=2
und für Takt2=30 gemessen hab ich für Takt 1 =1,91 Hz und für Takt 2= 31,25 Hz. Auch die Anzeige ist Stabil, so wie ich es haben wollte.
Werde jetzt versuchen einen Drehgeber anzuschließen um damit die Frequenz zu verändern , mal sehen wie es dann aussieht . Erst einmal Danke für deine Umfangreiche Hilfe. Werde bestimmt noch mit weiteren Problemen zu kämpfen haben und mich ggf wieder melden.

Hab eigentlich vor einen kleinen Batteriebetriebenen Frequenzgenerator mit Anzeige zu basteln , wobei weder die Frequenz noch die Anzeige sehr genau sein muss , aber man will eben ungefähr wissen wie hoch die Frequenz so in etwa ist.

Gruß Nase