Forum: Compiler & IDEs 8 Bit Datenwort Senden


von laiehoch10 (Gast)


Angehängte Dateien:

Lesenswert?

Hallihallöchen,
ich habe ein Problem und komme einfach nicht weiter. Und zwar soll ich 
bei Tastendruck von S1 an X2 ein Signal 01011101 (oder ähnlich) mit 
einer Sendefrequenz von 1,5kHz. Eigentlich wollte ein Bekannter mir das 
Programm schreiben, der kann aber leider im moment nicht. Da ich mich 
nicht wirklich mit C auskenne, ersuche ich euch ob ihr mir nicht 
einwenig helfen könnt.

MfG.: Benjamin

von g457 (Gast)


Lesenswert?

Quick'n'dirty: Siehe [1], im Speziellen die Kapitel 11 'Zugriff auf 
IO-Ports' und 13 'Warteschleifen (delay.h)'.

"Schöner" gehts mit Timern (Kapitel 16 'Timer' und 14 'Programmieren mit 
Interrupts' als Ergänzung zu obigen), aber ob sich der Aufwand lohnt ist 
eine Frage der Anforderungen.

HTH

[1] http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial

von laiehoch10 (Gast)


Lesenswert?

Danke für die Tipps, ich werde mich wohl eher an der "Quick an Dirty" 
Variante versuchen ;)

von laiehoch10 (Gast)


Lesenswert?

Also nach obriger Schaltung habe ich versucht den Code zu schreiben.
Würde es so funktionieren?
1
#include <avr\io.h>
2
#include <avr/delay.h>
3
4
void init (void)
5
{
6
   DDRB  = DDRB  & ~0b00000100;    
7
   PORTB = PORTB | 0b00000100;     
8
9
int main (void)
10
{
11
   unsigned char i;
12
13
   init ();
14
15
   do
16
   {
17
      i = PINB & 0b00000100;      
18
                            
19
     if (i == 0)            
20
        {      
21
      PORTB = 0b00000010;
22
      _delay_us(1);
23
      PORTB = 0b00000010;
24
      _delay_us(1);
25
      PORTB = 0b00000000;
26
      _delay_us(1);
27
      PORTB = 0b00000010;
28
      _delay_us(1);
29
      PORTB = 0b00000010;
30
      _delay_us(1);
31
      PORTB = 0b00000000;
32
      _delay_us(1);
33
      PORTB = 0b00000010;             
34
    }
35
   } while (1);
36
37
  
38
   return 0;
39
}
MfG.: Benjamin

von g457 (Gast)


Lesenswert?

> Würde es so funktionieren?

Geht in die richtige Richtung. Ein paar Punkte stechen sofort ins Auge:

- Das 'Signal' vom ersten Posting ('01011101') hat augenscheinlich 8 
Bit, der Block in main() setzt nur 7 und die sind noch dazu anders.. und 
es sind nur sechs Wartepausen drin
- Warten mit _delay_us(1) führt zu Bitraten in der Größenordnung von 
1e6/s, das ist weit entfernt von den ursprünglich geforderten 1.5kHz
- PORTB = .. setzt immer den ganzen Port - das mag hier funkionieren, 
will man aber der Wiederverwendbarkeit wegen eigentlich vermeiden
- Zuweisungen in Binärschreibweise sind schwer les- und wartbar. Bau Dir 
ein paar Makros, z.B. sowas in der Art:
1
#define SIGNAL           1
2
#define SIGNAL_PORT      PORTB
3
#define SIGNAL_DDR       DDRB
4
#define SIGNAL_OUTPUT()  ( SIGNAL_DDR  |=  _BV(SIGNAL) )
5
#define SIGNAL_HIGH()    ( SIGNAL_PORT |=  _BV(SIGNAL) )
6
#define SIGNAL_LOW()     ( SIGNAL_PORT &= ~_BV(SIGNAL) )
Damit werden dann Initialisierung und Senden zu sowas wie
1
SIGNAL_OUTPUT();
2
SIGNAL_LOW();
3
..
4
if (tastegedrückt)
5
{
6
  SIGNAL_HIGH();
7
  _delay_us(1);
8
  SIGNAL_LOW();
9
  _delay_us(1);
10
  ..
11
}
- Noch schöner lesbar wirds wenn man den Sendeblock gleich in eine 
eigene Routine verpackt, die bekommt dann das zu übertragende Bitmuster 
(und ggf. die Länge des Musters) und erledigt den Rest.

HTH

von laiehoch10 (Gast)


Lesenswert?

Zuerst ein mal, Vielen Dank für deine Antwort.
Also das Signal im ersten Post war nur ein Beispiel, es ist auch 
eigentlich egal. Es sollte eben durch ein weiteres Programm, welches 
vermutlich schwerer zu schreiben sein wird, ausgewertet werden können 
und dann einfach einen Ausgang setzen. Die Sendefrequenz ist eigentlich 
auch nicht so wichtig, denn das Sendemodul kann maximal 2kHz. Und unsere 
Lehrpersonen, die es uns eigentlich bei bringen sollten, haben uns am 
Anfang immer zu Binärschreibweise geraten. Dass ich ein Bit zu senden 
vergessen habe ist mir leider eben passiert und wurde natürlich gleich 
korrigiert :) und der eine delay zum Schluss habe ich auch sofort 
ergänzt. Das mit den Makros werde ich jetzt auch einbauen, sieht 
wirklich viel schöner aus ;) Dafür muss ich mir das noch genauer 
analysieren, da ich noch kein Fachmann für uC's bin.

von laiehoch10 (Gast)


Lesenswert?

Sodala, das Sendeprogramm steht und funktioniert. Nun bräuchte ich eure 
Hilfe beim Empfängerprogramm, wie stelle ich das am besten an?

von laiehoch10 (Gast)


Lesenswert?

Könnte ich hiermit das Signal auswerten?
1
#include <avr\io.h>
2
#include <util\delay.h>
3
4
void init (void)
5
{
6
   DDRB  = DDRB  & ~0b00000011;    // PortA.0 als Eingang
7
   PORTB = PORTB | 0b00000001;     // PortA.0 mit PullUpWiderstand
8
}
9
10
int main (void)
11
{
12
13
unsigned char i;
14
int n=0;
15
16
   init ();
17
18
   do
19
   {
20
21
      i = PINB & 0x01;
22
    if (i == 0)
23
     n++;
24
25
    _delay_ms(1);  
26
27
      i = PINB & 0x01;
28
    if (i == 0)
29
     n++;
30
31
    _delay_ms(1);
32
33
      i = PINB & 0x01;
34
    if (i != 0)
35
     n++;
36
37
    _delay_ms(1);
38
39
    i = PINB & 0x01;
40
    if (i == 0)
41
     n++;
42
43
     _delay_ms(1);
44
45
46
    i = PINB & 0x01;
47
    if (i != 0)
48
     n++;
49
50
    _delay_ms(1);
51
52
    i = PINB & 0x01;
53
    if (i == 0)
54
     n++;
55
56
    _delay_ms(1);
57
58
59
    i = PINB & 0x01;
60
    if (i == 0)
61
     n++;
62
63
    _delay_ms(1);
64
65
    if(n == 8)
66
    {
67
      PORTB |= 0b00000010;
68
    _delay_ms(200);
69
    n=0;
70
    }      
71
72
73
   } while (1);
74
75
76
  
77
   return 0;
78
}

von Walter (Gast)


Lesenswert?

laiehoch10 schrieb:
> Könnte ich hiermit das Signal auswerten?

nein, du musst auf irgendwie auf den stART synchronisieren

von laiehoch10 (Gast)


Lesenswert?

Walter schrieb:
> nein, du musst auf irgendwie auf den stART synchronisieren

hättest du da einen vorschlag?

von g457 (Gast)


Lesenswert?

> hättest du da einen vorschlag?

Ich misch mir mal wieder ein: Nimm ein Startsymbol (dazu), z.B. eine '1' 
[*] vorne dran. Dann heisst das für den Empfänger: Solange am Eingang 
eine '0' ankommt, sendet das Gegenüber nix - Zeit zum Nasebohr^Wnixtun:
1
while (!SIGNAL_IS_SET()) ;
Irgendwann kommt dann mal was an (dann wird obige Schleife beendet), 
sicherheitshalber überprüfst Du das Startbit nach einer halben 
Signaldauer nochmals (könnte ja auch eine Störung auf der Leitung 
gewesen sein):
1
_delay_us(500);
2
if (!SIGNAL_IS_SET()) {
3
   // Sonnenwinde..
4
   $zurück_auf_los/return/break/panic/..
5
}
Ab jetzt kannst Du (behelfsmäßig.. für die paar Bits sollte die 
Genauigkeit langen) die Bits Busy-wartend auslesen - noch immer 
(absichtlich) eine halbe Signallänge 'phasenverschoben' damit man nicht 
auf der Signalflanke landet:
1
uint8_t result = 0;
2
for (int i = 0; i < 8; i++) {
3
   result <<= 1;
4
   result |= SIGNAL_IS_SET() ? 1 : 0;
5
   _delay_ms(1);
6
}

Abschließend noch die defines:
1
#define SIGNAL           1
2
#define SIGNAL_PIN       PINB
3
#define SIGNAL_IS_SET()  ( SIGNAL_PIN & _BV(SIGNAL) )

Noch ein bisschen umsortieren und verpacken dann feddisch.

HTH

[*] Oder eine '0', ggf. mit Pullup oder -down an der Leitung, oder wie 
im Ursprungsposting angedeutet mit einem Push-Pull-Ausgang.

von laiehoch10 (Gast)


Lesenswert?

Vielen Dank g457... das hat mich jetzt wieder ein ganzes Sück nach vorn 
gebracht :)

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.