PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [ERLEDIGT] Toggle Geschwindigkeit über Poti verstellen



BlaueLed
29.11.2011, 18:48
Hallo zusammen,

ich sitz momentan echt aufm Schlauch. Ich möchte über ein Potti die Toggle Geschwindigkeit eines Ausganges zwischen 0,2s und 5s verstellen. Das ganze linear.

Momentan lese ich den ADC 0 ein und teile den Wert durch 20. So komme ich auf einen Bereich von ca 0-50. Jetzt habe ich einen Timer mit einer Frequenz von 10Hz. Beim überlauf des Timers lasse ich eine Variable hochzählen. Wenn nun die Variable den Wert des Poti´s erreicht hat, toggle ich den Ausgang. Das ganze funktioniert, aber nicht wirklich schön. Die Abstufungen sind mir zu grob. Ich hätte halt gerne das ich im Bereich von 0,2s bis 5s schön linear am besten mit den vollen 1023 Schritten regeln kann.

Hier mein Code:



'_________________________________________________ ______________________________
'************************************************* ******************************
'*** Chip Definition ***
'************************************************* ******************************
'-------------------------------------------------------------------------------
$regfile = "m88def.dat"
$crystal = 8000000
$hwstack = 60
$swstack = 40
$framesize = 60
$baud = 9600

'_________________________________________________ ______________________________
'************************************************* ******************************
'*** Ports ***
'************************************************* ******************************
'-------------------------------------------------------------------------------
Config Pinb.0 = Input 'Taster
Config Pinb.1 = Input 'Taster
Config Pind.2 = Input 'RC-Signal
Config Pind.3 = Input 'RC-Signal
Config Portd.7 = Output 'Led

'_________________________________________________ ______________________________
'************************************************* ******************************
'*** Timer ***
'************************************************* ******************************
'-------------------------------------------------------------------------------
Config Timer1 = Timer , Prescale = 64
On Timer1 Timer_irq
Const Timervorgabe = 53036

'_________________________________________________ ______________________________
'************************************************* ******************************
'*** ADC ***
'************************************************* ******************************
'-------------------------------------------------------------------------------
Config Adc = Single , Prescaler = Auto

'_________________________________________________ ______________________________
'************************************************* ******************************
'*** Alias ***
'************************************************* ******************************
'-------------------------------------------------------------------------------
Led Alias Portd.7
Taster2 Alias Pinb.1
Taster1 Alias Pinb.0

'_________________________________________________ ______________________________
'************************************************* ******************************
'*** Dims ***
'************************************************* ******************************
Dim Tick_ticker As Word
Dim Adc_value As Word
Dim Adc_ticker As Word



'_________________________________________________ ______________________________
'************************************************* ******************************
'*** Konstanten ***
'************************************************* ******************************

'_________________________________________________ ______________________________
'************************************************* ******************************
'*** Main / Hauptprogramm ***
'************************************************* ******************************
'-------------------------------------------------------------------------------
'--- Boot ---
Portb.1 = 1 'Pullup aktivieren
Portb.0 = 1 'Pullup aktivieren

Enable Interrupts
Enable Timer1


'--- Main ---
Main:

Adc_value = Getadc(0)
Adc_ticker = Adc_value / 20
Print Adc_ticker

Goto Main


'--- Interrupt ---
Timer_irq:
Timer1 = Timervorgabe
Incr Tick_ticker

If Tick_ticker > Adc_ticker Then ' Wenn Wert von Variable größer als ADC Wert ist , dann löschen
Tick_ticker = 0
End If

If Tick_ticker = Adc_ticker Then
Toggle Led
Tick_ticker = 0
End If

Return


Kann mir jemand einen Tip geben, wie ich das ganze linearer hinbekommen könnte ?

Danke und Gruß
Kay

Kampi
29.11.2011, 19:23
Wenn du das ganze in 1024 Schritten linear haben möchtest, brauchst du erstmal ein sehr feines Poti für die 1024 Werte und das Poti sollte auch linear sein. Wenn das linear ist ist der Rest es auch ;)

Searcher
29.11.2011, 20:13
Hallo,
man könnte den Timer auf CTC einstellen mit

CONFIG TIMER1 = TIMER , PRESCALE = 1024
SET TCCR1B.WGM12 'CTC, TOP Ist OCR1A (weis nicht ob das im CONFIG TIMER Befehl geht)

Bei 8MHz läuft er dann mit 7812,5 Hz was einer Periodendauer von 128µs entspricht.
Um auf 5s zu kommen muß er 5s / 0,000128s = ca 39063 Takte laufen, also

OCR1A = 39063 'als TOP Wert zuweisen

Beim Topwert wird der COMPARE1A Interrupt ausgelöst

ON COMPARE1A ISR_Toggle_LED
ENABLE COMPARE1A
ENABLE INTERRUPTS 'LED wird nun alle 5 Sekunden getoggelt.

Mit Poti nun das OCR1A Register versorgen bis zu einem maximalen Wert von 39063

39063 / 1023 = ca 38 besser 39 ?

Also den vom ADC ausgelesenen Wert mit 39 multiplizieren und dem OCR1A in der Main zuweisen.

Von ADC Wert 0 bis 41 würde es dann aber auch unter 0,2s toggeln; könnte man mit IF THEN abschneiden.
Toggle Auflösung wäre pro ADC Schritt 39 * 128µs = ca 5ms.


In der ISR steht dann nur: Toggle Led

Wenn die Grenzwerte ganz genau eingehalten werden müssen, müßte man weiter überlegen.

Gruß
Searcher

BlaueLed
29.11.2011, 20:45
Hi und Danke für die Antworten. Ich werde das morgen mal testen.

Danke und Gruß
Kayle

BlaueLed
01.12.2011, 23:36
Hi,

vielen Dank für den Tip mit dem CTC Timer. Das Programm läuft soweit. Hier der Code:



'--- Chip ---
$regfile = "m88def.DAT"
$crystal = 8000000
$baud = 9600
$framesize = 40
$hwstack = 40
$swstack = 40

'--- Ports ---
Config Portb.1 = Output

'--- ADC ---
Config Adc = Single , Prescaler = Auto

'--- Dim ---
Dim Adc_wert As Word

'--- Timer ---
Config Timer1 = Timer , Prescale = 1024 , Compare_a = Toggle , Clear_timer = 1 ' Timer auf CTC Mode setzen und Ausgang OCR1A togglen

'--- Main ---
Do

Adc_wert = Getadc(0) ' ADC einlesen

Waitms 100 ' 100ms warten

If Adc_wert < 40 Then Adc_wert = 40 ' minimalen Wert von 40 einhalten / ca. 0,2s

Ocr1a = Adc_wert * 40 ' Timer setzen

Loop


Mit diesem code kann ich nun zwischen ca. 0,2s - 5s die Toggle Geschwindigkeit einstellen und das sehr "smooth". Wenn ich nun auf 5s stellen und dann "schnell" auf 0,2s runtergehe, dann dauert es natürlich maximal 5s bis die 0,2s eingestellt sind. Wie kann ich dafür sorgen, das wenn der aktuelle per Poti eingestellte Wert kleiner ist, als der des OCR1A Registers den Timer "stoppt" und neu startet für die 0,2s ?

Gruß Kay

radbruch
02.12.2011, 09:06
So vielleicht:


Ocr1a = Adc_wert * 40 ' Timer setzen
If Ocr1a < Tcnt1 Then Tcnt1 = 0 ' Zählregister anpassen

Loop

BlaueLed
07.12.2011, 23:37
Hi,

genau so funktionierts :-)

Danke für die Hilfe

Gruß Kay