Bascom Timer to C Problem

OP #3935943
Lesenswert?

Hallo zusammen,
vorweg: Timer sind nicht meine Freunde!

Ok, ich habe einen Bascom Code welcher ein Martinshorn steuert. Das 
Ganze läuft über den Timer0 des Attiny13:
1
Enable Interrupts
2
Timer0 = Timer , Prescale = 64                    
3
Tcnt0 = 97
4
On Timer0 Horn
5
Enable Timer0
6

7
...
8

9
Horn:
10
Toggle Portb.2
11
Toggle Portb.0
12
Tcnt0 = D

Funktioniert einwandfrei.
Umgeschrieben, nein eher portiert nach C und nix kommt aus dem 
Lautsprecher:
1
cli();
2
TCCR0B |= (1<<CS01) | (1<<CS00);  
3
TIMSK0 |= (1<<TOIE0);  
4
TCNT0 = 97;
5

6
sei(); 
7

8
ISR (TIM0_OVF_vect) /* veraltet: SIGNAL(SIG_OVERFLOW0) */
9
{
10
 PORTB ^= ( 1 << PB0 );  // Toggle PB0 z.&nbsp;B. angeschlossene LED
11
 PORTB ^= ( 1 << PB2 );  // Toggle PB0 z.&nbsp;B. angeschlossene LED
12
 TCNT0=D;
13
 
14
}

Warum funktioniert das nicht? Wieso kapiere ich das nicht?? :(
OP #3936020
Lesenswert?

Sorry, das hatte ich vergessen. C wird in der Schleife hochgezählt und 
der variablen D dann 2 Werte übergeben um die 2 unterschiedlichen Töne 
zu erzeugen.
1
If C = 1 Then 
2
D = 97
3
Elseif C = 75 Then
4
D = 137
5
End If
6
If C = 150 Then
7
C = 0
8
End If

Ok, ich versuch es mal mit TIMER0_OVF_vect
Gast #3936086
Lesenswert?

Dominik Kristen schrieb:
> öhm,
> wenn ich TIMER0 schreibe kommt aber die Warnung:
>
> ../Sirene.c:12: warning: 'TIMER0_OVF_vect' appears to be a misspelled
> signal handler
>
> Bei TIM0 kommt keine!?!?!

Mit welchem C-Compiler arbeitest du?
Wenn's ein anderer als GCC ist, schau dir mal die Definition der 
Handler-Namen an, vermutlich lauten die bei deinem Compiler anders...
OP #3936097
Lesenswert?

Also, in der Main Schleife blitzen abwechseln 2 LED, das funktioniert 
auch bestens.

im Interrupt steht folgendes:
1
ISR (TIM0_OVF_vect) /* veraltet: SIGNAL(SIG_OVERFLOW0) */
2
{
3
 PORTB ^= ( 1 << PB0 );  // Toggle PB0 z.&nbsp;B. angeschlossene LED
4
 PORTB ^= ( 1 << PB2 );  // Toggle PB0 z.&nbsp;B. angeschlossene LED
5
  TCNT0=D;
6
 
7
}

da höre ich nur ein leises, durchgängiges Schrillen.
Wie gesagt, der Bascom Code gibt ein Martinshorn wieder!
Gast #3936102
Lesenswert?

Dominik Kristen schrieb:
> öhm,
> wenn ich TIMER0 schreibe kommt aber die Warnung:
>
> ../Sirene.c:12: warning: 'TIMER0_OVF_vect' appears to be a misspelled
> signal handler
>
> Bei TIM0 kommt keine!?!?!

Laut Datenblatt ist das der richtige Name.
Wie sieht denn dein Programm sonst aus?
Hast du die Portpin als Ausgang definiert?
OP #3936106
Lesenswert?

Ok, hier meine spärliche Umsetzung des bascom Codes! Bitte jetzt erstmal 
nicht über Kommentare oder Code organisation schimpfen:
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#define F_CPU 9600000UL  // 1,2 MHz (für delay.h)
4
                         // Standard-Takt 9,6 MHz / 8
5
#include <util/delay.h>
6

7

8
int A, B, C, D;
9
//********************************************************************
10

11
// Interruptserviceroutine
12
ISR (TIM0_OVF_vect) /* veraltet: SIGNAL(SIG_OVERFLOW0) */
13
{
14
 PORTB ^= ( 1 << PB0 );  // Toggle PB0 z.&nbsp;B. angeschlossene LED
15
 PORTB ^= ( 1 << PB2 );  // Toggle PB0 z.&nbsp;B. angeschlossene LED
16
  TCNT0=D;
17
 
18
}
19
//****************************************************************
20

21

22

23

24
int main(void){
25
 
26

27
cli();
28

29
DDRB |= _BV(PB3); //PD2 zum Ausgang machen (= 1. LED von links)
30
DDRB |= _BV(PB4); //PD0 zum Ausgang machen (= 2. LED von links)
31
DDRB |= _BV(PB0); //PD2 zum Ausgang machen (= 1. LED von links)
32
DDRB |= _BV(PB2); //PD0 zum Ausgang machen (= 2. LED von links)
33

34
 
35
    TCCR0B |= (1<<CS01) | (1<<CS00);  
36
            
37
  TCCR0A |= (1<<WGM01);  
38

39
  TIMSK0 |= (1<<TOIE0);  
40

41
 TCNT0 = 97;
42
   
43
 sei();                                       // Interrupts erlauben
44

45
  A=0; 
46
  B=67;
47
  C=0;
48

49

50
  
51
     
52
    while (1)  {        
53
     A=A+1;
54
   B=B+1;
55
   C=C+1;
56
   _delay_ms(10);
57

58
   if(A==79)  PORTB |= (1<<PB4);
59
   if(A==90)  PORTB &= ~(1<<PB4);
60
   if(A==99)  PORTB |= (1<<PB4);
61
   if(A==105) PORTB &= ~(1<<PB4), A=0;
62
   
63
   if(B==84) PORTB |= (1<<PB3);
64
   if(B==95) PORTB &= ~(1<<PB3);
65
     if(B==104) PORTB |= (1<<PB3);
66
   if(B==110)  PORTB &= ~(1<<PB3), B=0;
67

68
   if(C==1) D=97;
69
   if(C==75) D=137;
70
   if(C==150) C=0;
71

72

73
     }
74
        
75
    return 0;
76
}

Und hier der Bascom Code:
1
$regfile = "ATtiny13.DAT"
2
$crystal = 9600000                                          'Frequenz des internen Oszillators
3

4
$hwstack = 32                                               'default use 32 for the hardware stack
5
$swstack = 10                                               'default use 10 for the SW stack
6
$framesize = 40                                             'default Use 40 For The Frame
7

8
Stop Ac
9
Stop Adc
10

11

12

13
Config Portb = &B11111101                                   'Portb.1 auf 'Eingang' schalten
14
Portb = &B00000011                                          'Pullup Portb.1; Portb.0=1
15

16

17
Config Int0 = Rising
18
On Int0 Einaus                                              'INT0 konfiguriren, wird nur benutzt um Powerdown zu beenden
19

20

21
Dim A As Byte                                               'Softwarezähler LED an PortB.4
22
Dim B As Byte                                               'Softwarezähler LED an PortB.3
23
Dim C As Byte                                               'Softwarezähler Martinshorn
24
Dim D As Byte                                               'Variable für TCNT0
25

26
Anfang:                                                     'Beginn Initialisierung
27

28
Waitms 10
29

30
A = 0
31
B = 67
32
C = 0
33

34
Enable Int0
35
Enable Interrupts
36
Portb = &B00000011
37
Powerdown
38

39
Config Timer0 = Timer , Prescale = 64                       'TIMER0 erzeugt Tonfrequenzen
40
Tcnt0 = 97
41
On Timer0 Horn
42
Enable Timer0
43

44
Disable Int0
45

46

47
Schleife:                                                   'Entprellen nach Beendigung von Powerdown
48
If Pinb.1 = 0 Then
49
Goto Schleife
50
End If
51

52

53
Do                                                          'Do - Loop für die 3 Softwarezähler
54

55

56
Waitms 10
57

58
Incr A
59
Incr B
60
Incr C
61

62

63
If A = 79 Then
64
Portb.4 = 1
65
Elseif A = 90 Then
66
Portb.4 = 0
67
End If
68

69
If A = 99 Then
70
Portb.4 = 1
71
Elseif A = 105 Then
72
Portb.4 = 0
73
End If
74

75
If A = 105 Then
76
A = 0
77
End If
78

79

80
If B = 84 Then
81
Portb.3 = 1
82
Elseif B = 95 Then
83
Portb.3 = 0
84
End If
85

86
If B = 104 Then
87
Portb.3 = 1
88
Elseif B = 110 Then
89
Portb.3 = 0
90
End If
91

92
If B = 110 Then
93
B = 0
94
End If
95

96

97
If C = 1 Then
98
D = 97
99
Elseif C = 75 Then
100
D = 137
101
End If
102

103
If C = 150 Then
104
C = 0
105
End If
106

107

108
If Pinb.1 = 0 Then                                          'Ausschalten mit Entprellen
109
Stop Timer0
110
Portb = &B00000011
111

112
Kontakt:
113

114
   If Pinb.1 = 0 Then
115
   Goto Kontakt
116
   End If
117

118
Goto Anfang
119
End If
120

121

122
Loop
123

124

125
Horn:
126

127
Toggle Portb.0
128
Toggle Portb.2
129

130
Tcnt0 = D
131
Return
132

133

134
Einaus:
135
nop
136
Return
137

138

139
End

Wie gesagt, ichhab auf die Schnelle versucht es umzusetzen. Mit den LED 
klappt nur den Timer, den krieg ich einfach nicht hin!
Gast #3936109
Lesenswert?

Dominik Kristen schrieb:
> Also ich arbeite mit AVR Studio 4.18 und WinAVR-20100110 als
> Avr-gcc
> compiler.
> Wo sehe ich die Definitionen denn?

Wenn du beispielsweise mit dem ATMega8 arbeitest, ist dafür ein File 
zuständig, welches "iom8.h" heißt. Dort sind dann unter anderem folgende 
Zeilen drin:
1
/* Timer/Counter0 Overflow */
2
#define TIMER0_OVF_vect_num    9
3
#define TIMER0_OVF_vect      _VECTOR(9)
4
#define SIG_OVERFLOW0      _VECTOR(9)
OP #3936118
Lesenswert?

Ist das krank...
Es funktioniert Karl-Heinz!
Also fast jedenfalls!

WGM01 rausgenommen und die variable D als volatile.
Oh man... was man alles missachten kann! :-S

Aus dem Piezo Speaker kommt jetzt die Sirene! Aber deeeeeeeeeeeeutlich 
leiser als mit dem bascom Code! Warum?
#3936125
Lesenswert?

Dir scheint nicht klar zu sein, wie da offenbar die Tonerzeugung 
funktioniert.

Du hast 2 Pins, PB0 und PB2 an denen der Lautsprecher (oder Summer) 
hängt. Damit sich da an der Membran was tut, müssen die immer 
gegengleich sein. Wenn PB0 auf 1 ist, dann muss PB2 auf 0 sein, damit 
die Membran in die eine Richtung schwingt; wenn PB0 auf 0 ist, dann muss 
PB2 auf 1 sein, damit die Membran in die andere Richtung schwingt.
Durch regelmässiges Umpolen der beiden Leitungen schwingt dann die 
Membran ständig vor und zurück, was den Ton ergibt.

Damit du hier
1
 PORTB ^= ( 1 << PB0 );  // Toggle PB0 z.&nbsp;B. angeschlossene LED
2
 PORTB ^= ( 1 << PB2 );  // Toggle PB0 z.&nbsp;B. angeschlossene LED

aber einfach nur Toggeln brauchst. müssen die beiden Pins von Beginn an 
erst  mal unterschiedlich stehen. Der eine auf 0, der andere auf 1. Nur 
dann ergibt sich dann nach dem Toggler, dass der eine auf 1 steht und 
der andere auf 0; und beim nächsten Durchlauf dann wieder zurück.

Im BASCOM Code ist das hier
1
Portb = &B00000011                                          'Pullup Portb.1; Portb.0=1
am Anfang nach der Initialisierung sicher gestellt.

In deinem Code sehe ich aber nichts dergleichen.
Deine Portpins PB0 und PB2 haben immer den gleichen Pegel. Wodurch an 
der Membran keine DIfferenz entsteht und die Membran sich daher nicht 
rührt.

Wenn sich da überhaupt was rührt, dann ist das die kleine Zeitdifferenz 
zwischen den beiden Portoperationen, die eine winzige Bewegung der 
Membran bewirkt.
OP #3936138
Lesenswert?

Karl Heinz schrieb:
> Dominik Kristen schrieb:
>> hm.. gute Frage.. muss ich da nicht in den CTC Mode?
>
> Verwendet der BASCOM Code den CTC Modus?
> Wenn nein, warum solltest du dann im C Code einen verwenden?

Ich habe früher mit Bascom angefangen.
Wenn ich da heute so drüber nachdenke... oh man!
Da wird der Timer ja nur durch
1
Config Timer0 = Timer, Prescale = 64

definiert. Ich seh da nix mit CTC oder PWM oder sonst was :(

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