Forum: Mikrocontroller und Digitale Elektronik Pulslängeenproblem


von Karl (Gast)


Lesenswert?

Hi Folks,

ich bin dabei ein Modul mit einem ATMEGA8 zu bauen, welches Messdaten 
einließt und sie zu einem anderen myC schickt.
Die Messdaten werden über die Länge eines Pulses codiert (z.B. 
gemessener Wert = 1000 -> Pulslänge = 32ms).
Zum Testen der Sendevorrichtung habe ich beiliegendes Programm 
geschrieben.
Der Ablauf: zunächst wird ein Puls der Länge 2 übertragen, um dem 
Empfänger zu signalisieren, dass gleich Daten kommen (Die Datenimpulse 
sind mindestens 5 "Zyklen" lang).
Dann wird der Datenpuls übertragen. Das wiederholt, wobei die zu sendene
Zahl bei jedem mal inkrementiert wird.

Das klappt soweit alles gut, dass Problem ist, dass ab einer gewissen
Pulslänge die Signale peridoisch um 255 verkleinert gesendet wird (mit 
Oszi nachgemessen). Ich habe gestern lange rumgerätselt aber ich finde 
die Lösung nicht. Vielleicht fällt einem von euch was ein???


Grüße
Karl


Code des Senders:
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <util/delay.h>
4
#define sendPort PORTC
5
#define sendBit PC4
6
7
8
void long_delay(int ms) {
9
  
10
    for(; ms>0; ms--) _delay_ms(1);
11
}
12
13
volatile  int times = 0;
14
15
16
ISR (TIMER0_OVF_vect)
17
{
18
    times--;
19
    
20
}
21
22
 
23
void sendData(unsigned int sig){
24
    times = sig+5;
25
    TCNT0 = 0;
26
    TCCR0 |= (1 << CS00);
27
    sendPort |= (1 << sendBit);
28
    while(times > 0){;}
29
    sendPort &= ~(1 << sendBit);
30
    TCCR0 = 0;
31
    TCNT0 = 0;
32
    _delay_us(10);
33
}
34
35
void sendSync(){
36
    times = 2;
37
                TCNT0 = 0;
38
    sendPort |= (1 << sendBit);
39
    TCCR0 |= (1 << CS00);
40
    while(times > 0){;}
41
    sendPort &= ~(1 << sendBit);
42
    TCCR0 = 0;
43
    TCNT0 = 0;
44
    _delay_us(10);
45
}
46
47
int main(void)
48
{
49
  //Datenleitung
50
  DDRC |= (1 << PC4);
51
  PORTC &= ~(1 << PC4);
52
  
53
  TIMSK |= (1<<TOIE0);
54
  sei();  
55
  
56
  unsigned int a = 0;
57
  while(1 < 2){
58
    
59
    sendSync();
60
    sendData(a);
61
    
62
    a++;
63
    long_delay(100);
64
  }
65
  
66
    
67
//...
68
}

Was beim Empfänger ankommt (bis 253 funktioniert die Übertragung 
tadellos):
246;247;248;249;250;251;252;253;-1;255;256;257;3;259;260;261;7;263;264;2 
65;11;267;268;269;15;271;272;273

von Stefan B. (stefan) Benutzerseite


Lesenswert?

>     times = sig+5;
>    times = 2;
>    while(times > 0){;}

times musst du außerhalb der ISR (TIMER0_OVF_vect) atomar lesen und 
schreiben (Interrupt). times kann als 16-Bit Wert nicht in einer 
ununterbrechbaren Maschineninstruktion gelesen oder manipuliert werden.

times würde ich auch unsigned int machen, sonst kann es bei times = 
sig+5 Probleme mit Überlauf geben (kann es bei unsigned int auch, aber 
bei int wesentlich früher)

von Karl (Gast)


Lesenswert?

Ach logisch!

Ok es funktioniert vielen Dank

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.