Forum: Mikrocontroller und Digitale Elektronik Zwei Ports mit unterschiedlichen Funktionen ansprechen


von Leopold S. (leopold)


Angehängte Dateien:

Lesenswert?

Ich möchte mit Portb2 alle 20 sek. eine Led mit 200ms blitzen lassen und
parallel auf Portb3 alle 24 Std. für 30 sek. das Portb3 aktivieren.
Was muß ich in meinem Programm dafür ändern?
mfg
LS

von Daniel V. (danvet)


Lesenswert?

Mit Bascom kenne ich mich leider nicht aus. Aber wenn ich deinen Code 
sehe, dann sollte er entweder genau das machen, was du möchtest (was ich 
aber stark bezweifle), oder aber du solltest dich eingehend mit µC und 
insbesondere mit der Programmierung beschäftigen.

Du brauchst einen Timer.

von Leopold S. (leopold)


Lesenswert?

Mein problem ist nur da ich parallel 2 Schleifen habe, weis ich nicht ob 
nur eine Schleife abgearbeitet wird od. beide parallel?
mfg

von Daniel V. (danvet)


Lesenswert?

Leopold S. schrieb:
> Mein problem ist nur da ich parallel 2 Schleifen habe, weis ich nicht ob
> nur eine Schleife abgearbeitet wird od. beide parallel?
> mfg

Wenn Bascom kein Multitasking umsetzt, wirst du in einer Schleife hängen 
bleiben (was ich stark vermute).

Du brauchst einen Timer!

von Peter D. (peda)


Lesenswert?

Nimm nen Timerinterrupt mit dem kleinsten nötigen Intervall (200ms).
Zähl darin 2 Variablen für die 2 Prozesse und werte sie entsprechend 
aus.


Peter

von Vuvuzelatus (Gast)


Lesenswert?

>Was muß ich in meinem Programm dafür ändern?

Fast alles. Insbesondere brauchst Du einen Timer.

von Karl (Gast)


Lesenswert?

Ja, der Code funktioniert so nicht. Die erste "Do Loop" Schleife wird 
vom Programm nie verlassen, die zweite also nie ausgeführt. Wie meine 
Vorschreiber schon angemerkt haben, funktioniert das am besten über 
einen Timer. In Bascom kannst Du auch relativ leicht eine Softclock 
implementieren, über die man dann relativ ungenau (ohne Quarz) alle 24h 
oder alle 20s etwas tun lassen kann.

von Leopold S. (leopold)


Angehängte Dateien:

Lesenswert?

Sollte es so nicht auch funktionieren?
Habe neuen Bascomcode angehängt.
lg
LS

von Peter D. (peda)


Lesenswert?

Ich versuche solche Aufgaben immer in ein Schema zu pressen, daß die 
Lösung möglichst universell ist.
Hier ein Beispiel, welches für beide Loops jeweils einen Zähler 
verwendet.
Damit ist es beliebig erweiterbar und beide laufen unabhängig 
voneinander. Man kann also die Zeiten getrennt ändern, ohne den anderen 
zu beeinfluusen.
Ich kann aber nur C:
1
#include <avr/io.h>
2
#define F_CPU   1e6
3
#include <util/delay.h>
4
5
//                      Access bits like variables:
6
struct bits {
7
  uint8_t b0:1, b1:1, b2:1, b3:1, b4:1, b5:1, b6:1, b7:1;
8
} __attribute__((__packed__));
9
#define SBIT_(port,pin) ((*(volatile struct bits*)&port).b##pin)
10
#define SBIT(x,y)       SBIT_(x,y)
11
12
13
#define PORT_B2         SBIT( PORTB, 2 )
14
#define DDR_B2          SBIT( DDRB,  2 )
15
#define PORT_B3         SBIT( PORTB, 3 )
16
#define DDR_B3          SBIT( DDRB,  3 )
17
18
19
int main()
20
{
21
  uint32_t t1 = 0;
22
  uint32_t t2 = 0;
23
24
  DDR_B2 = 1;
25
  DDR_B3 = 1;
26
27
  while( 1 ){                                   // main loop
28
    _delay_ms( 200 );                           // 0.2s tick
29
30
    switch( ++t1 ){                             // time loop 1:
31
      case 1:
32
                PORT_B2 = 1;
33
                break;
34
      case 2:
35
                PORT_B2 = 0;                    // off after 0.2s
36
                break;
37
      case (uint32_t)(20 / 0.2):
38
                t1 = 0;                         // repeat after 20s
39
                break;
40
    }
41
42
    switch( ++t2 ){                             // time loop 2:
43
      case 1:
44
                PORT_B3 = 1;
45
                break;
46
      case (uint32_t)(30 / 0.2):
47
                PORT_B3 = 0;
48
                break;                          // off after 30s
49
      case (uint32_t)(24 * 3600.0 / 0.2):
50
                t2 = 0;                         // repeat after 24h
51
                break;
52
    }
53
  }
54
}


Peter

von Karl (Gast)


Lesenswert?

So könnte es z.B mit BASCOM aussehen. 1s schafft der 8-Bit Timer des 
Tiny nicht, da sind nur ms drin.

Zum Thema Timer und Bascom siehe hier:

http://www.rn-wissen.de/index.php/Bascom_und_Timer

Zur Berechnung des Timers siehe hier:

http://www.dieelektronikerseite.de/Tools/Timer-Rechner.htm
1
$regfile = "attiny13.dat"
2
$crystal = 9600000
3
$hwstack = 16
4
$swstack = 0
5
$framesize = 24
6
7
Dim Millisekunden As Integer                                '2ms
8
Dim Sekunden As Integer                                     '2s
9
10
Config Portb.2 = Output                                     
11
Config Portb.3 = Output                                   
12
13
Config Timer0 = Timer , Prescale = 256
14
On Timer0 Zaehler
15
Enable Timer0
16
Start Timer0
17
18
Enable Interrupts
19
20
Do
21
22
Select Case Millisekunden
23
24
   Case 10000:                                              '20s
25
      Toggle Portb.2
26
      Incr Sekunden
27
   Case 10100:                                              '20s + 200ms
28
      Toggle Portb.2
29
30
End Select
31
32
33
Select Case Sekunden
34
35
   Case 43200:                                              '24h
36
      Toggle Portb.3
37
   Case 43215                                               '24h+30s
38
      Toggle Portb.3
39
      Sekunden = 0
40
41
End Select
42
43
Loop
44
45
Zaehler:
46
47
   If Millisekunden > 10100 Then Millisekunden = 0
48
   Incr Millisekunden
49
50
Return
51
52
End

von Karl (Gast)


Lesenswert?

Sehe gerade, dass in der zweiten Case-Anweisung die Sekunden nicht 
richtig berechnet sind. Kann man ja leicht anpassen.

von Leopold S. (leopold)


Lesenswert?

Hallo!
Mit meinem letzten Code würde das nicht gehen?
Kannst du mir den Select case bzw. erklären od. kommentieren?
Wo liegt der Fehler bei den Sekunden?
mfg
LS

von Leopold S. (leopold)


Lesenswert?

Hallo
Ich rechne 24x60x60/2 =43200 plus 30 sek =43215
daher find ich keinen Fehler bei den Sekunden
mfg
LS

von Peter D. (peda)


Lesenswert?

Leopold S. schrieb:
> Ich rechne 24x60x60/2 =43200 plus 30 sek =43215
> daher find ich keinen Fehler bei den Sekunden

Kann Bascom konstante Ausdrücke nicht gefälligst selber ausrechnen?

Unter C habe ich es mir abgewöhnt, den Taschenrechner zu bemühen. Ich 
schreib immer nur die Rechnung hin und lasse es den Compiler ausrechnen.

Es geschieht ja schon zur Compilezeit, d.h. für den MC wird kein 
zusätzlicher Code erzeugt.
Und die Compilezeit verlängert sich auch nicht spürbar.


Peter

von Karl (Gast)


Lesenswert?

So sollte es stimmen. Die Sekunden wurden nur alle 20s (und nicht alle 
2s) hochgezählt.

Bezgl. SELECT CASE siehe hier:

http://avrhelp.mcselec.com/index.html?select_case_end_select.htm

Ob Dein Code funktioniert, habe ich nicht ausprobiert. Wollte nur 
zeigen, wie es mit einem TIMER aussehen könnte. Die Werte könnte 
natürlich auch BASCOM berechnen.

Ansonsten kann man in BASCOM auch immer die Simulation bemühen:

http://avrhelp.mcselec.com/index.html?program_simulate.htm

Man sollte dabei die Zahl der Sekunden beschränken, sonst sitzt man 
tagelang vorm Rechner. ;-)
1
...
2
Do
3
4
Select Case Millisekunden
5
6
   Case 1000:                                               '2s
7
      Incr Sekunden
8
   Case 10000:                                              '20s
9
      Toggle Portb.2
10
   Case 10100:                                              '20s + 200ms
11
      Toggle Portb.2
12
13
End Select
14
...

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.