8 Bit Datenwort Senden

Gast #2003518
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
Angehängte Dateien:
Gast #2029023
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
Gast #2029188
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
Gast #2029285
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.
Gast #2038726
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
}
Gast #2042410
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.

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