Zwei Ports mit unterschiedlichen Funktionen ansprechen

#2217258
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.
Gast #2217410
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.
#2217657
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
Gast #2217802
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
#2218169
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
Gast #2218296
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
...

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren