Forum: Mikrocontroller und Digitale Elektronik Bascom Timer to C Problem


von Kilo K. (kilo81)


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?? :(

von npn (Gast)


Lesenswert?

Dominik Kristen schrieb:
> ISR (TIM0_OVF_vect) /* veraltet: SIGNAL(SIG_OVERFLOW0) */

TIM0 existiert nicht, versuchs mal mit TIMER0_OVF_vect.
Wo kommt die Variable D her und was macht sie?
Was du zeigst, ist nicht das ganze Programm...

von Kilo K. (kilo81)


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

von Karl H. (kbuchegg)


Lesenswert?

Dominik Kristen schrieb:

> Ok, ich versuch es mal mit TIMER0_OVF_vect

Nicht 'versuchen'.

Wenn der Name der ISR nicht koscher ist, dann gibt es vom Compiler eine 
Warnung. Die darfst du nicht einfach ignorieren. Kommt vom Compiler
1
'xyz' appears to be a misspelled signal handler
dann ist er das auch - invalid!

von npn (Gast)


Lesenswert?

Karl Heinz schrieb:
> Nicht 'versuchen'.

War vielleicht meine Schuld. Ich hatte oben geschrieben:

npn schrieb:
> TIM0 existiert nicht, versuchs mal mit TIMER0_OVF_vect.

War mißverständlich ausgedrückt...

von Kilo K. (kilo81)


Lesenswert?

ö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!?!?!

von npn (Gast)


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...

von Kilo K. (kilo81)


Lesenswert?

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

von Kilo K. (kilo81)


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!

von Karl H. (kbuchegg)


Lesenswert?

TIM0_OVF_vect is korrekt.

Schau in den Solution Explorer unter 'Dependencies'. Dort ist ein File 
iotn13.h aufgeführt. Dort stehen unter anderem die Namen aller Interrupt 
Vektoren drinn.

ok. falscher Name wars nicht.
Das ganze Programm bitte und nicht nur Ausschnitte.

von STK500-Besitzer (Gast)


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?

von Karl H. (kbuchegg)


Lesenswert?

Dominik Kristen schrieb:

> Wie gesagt, der Bascom Code gibt ein Martinshorn wieder!

Das mag schon sein. Nur interessiert der BASCOM Code nicht mehr. Der C 
Code ist interessant. Und zwar der vollständige.

von Kilo K. (kilo81)


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!

: Bearbeitet durch User
von npn (Gast)


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)

von Karl H. (kbuchegg)


Lesenswert?

Dominik Kristen schrieb:

> int A, B, C, D;

da fehlt zumindest für D ein volatile

>     TCCR0B |= (1<<CS01) | (1<<CS00);
>
>   TCCR0A |= (1<<WGM01);

Aha!
Darf man fragen, warum du da WGM01 setzt?

von Kilo K. (kilo81)


Lesenswert?

hm.. gute Frage.. muss ich da nicht in den CTC Mode?

von npn (Gast)


Lesenswert?

npn schrieb:
> Wenn du beispielsweise mit dem ATMega8 arbeitest,

Ich sehe gerade, du hast einen Tiny13. Dann heißt das File "iotn13.h".

von Kilo K. (kilo81)


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?

von npn (Gast)


Lesenswert?

Karl Heinz schrieb:
> TIM0_OVF_vect is korrekt.

Hallo Karl Heinz,
stimmt, beim Tiny13 steht das so drin. Aber bei allen ioxx.h die ich 
habe, steht nicht "TIM0_..._vect" sondern "TIMER0_..._vect". Die 
Schreibweise mit "TIM0" kenne ich gar nicht. Ist da mal was geändert 
worden?

von Karl H. (kbuchegg)


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.

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

npn schrieb:
> Karl Heinz schrieb:
>> TIM0_OVF_vect is korrekt.
>
> Hallo Karl Heinz,
> stimmt, beim Tiny13 steht das so drin. Aber bei allen ioxx.h die ich
> habe, steht nicht "TIM0_..._vect" sondern "TIMER0_..._vect". Die
> Schreibweise mit "TIM0" kenne ich gar nicht. Ist da mal was geändert
> worden?

Atmel ist da leider nicht einheitlich.

von Kilo K. (kilo81)


Lesenswert?

Karl-Heinz, du bist ein Teufelskerl!
Danke, das wars!!
Ich Depp hab das total überlesen, da ich nur auf Pullup Portb.1 geachtet 
habe, was im Bascom Code ja der Schalter ist. Oh man! Kopfklatsch

Übrigens schön erklärt! So versteht das jeder!
Danke!

von Karl H. (kbuchegg)


Lesenswert?

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?

von Route_66 H. (route_66)


Lesenswert?

Hallo!
Hängt der Piezo zwischen PB.0 und PB.2?
Dann musst Du in der Initialisierung für die richtige Anfangsbelegung 
sorgen:

PORTB = 0x03

von Karl H. (kbuchegg)


Lesenswert?

Dominik Kristen schrieb:
> Karl-Heinz, du bist ein Teufelskerl!
> Danke, das wars!!
> Ich Depp hab das total überlesen, da ich nur auf Pullup Portb.1 geachtet
> habe,

Was lernen wir daraus:
Kommentare sind Schall und Rauch. Was zählt ist der Code und was er 
bewirkt.

von Kilo K. (kilo81)


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 :(

von npn (Gast)


Lesenswert?

Karl Heinz schrieb:
> Atmel ist da leider nicht einheitlich.

Ja, ich seh's gerade. Scheinbar habe ich bis jetzt nur mit µC 
gearbeitet, wo "TIMER0..." gültig ist. Danke für die Aufklärung :-)

von Route_66 H. (route_66)


Lesenswert?

Zu lange getippt.

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.