www.mikrocontroller.net

Forum: Compiler & IDEs 8 Bit Datenwort Senden


Autor: laiehoch10 (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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

Autor: g457 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: laiehoch10 (Gast)
Datum:

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

Autor: laiehoch10 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also nach obriger Schaltung habe ich versucht den Code zu schreiben.
Würde es so funktionieren?
#include <avr\io.h>
#include <avr/delay.h>

void init (void)
{
   DDRB  = DDRB  & ~0b00000100;    
   PORTB = PORTB | 0b00000100;     

int main (void)
{
   unsigned char i;

   init ();

   do
   {
      i = PINB & 0b00000100;      
                            
     if (i == 0)            
        {      
      PORTB = 0b00000010;
      _delay_us(1);
      PORTB = 0b00000010;
      _delay_us(1);
      PORTB = 0b00000000;
      _delay_us(1);
      PORTB = 0b00000010;
      _delay_us(1);
      PORTB = 0b00000010;
      _delay_us(1);
      PORTB = 0b00000000;
      _delay_us(1);
      PORTB = 0b00000010;             
    }
   } while (1);

  
   return 0;
}
MfG.: Benjamin

Autor: g457 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
#define SIGNAL           1
#define SIGNAL_PORT      PORTB
#define SIGNAL_DDR       DDRB
#define SIGNAL_OUTPUT()  ( SIGNAL_DDR  |=  _BV(SIGNAL) )
#define SIGNAL_HIGH()    ( SIGNAL_PORT |=  _BV(SIGNAL) )
#define SIGNAL_LOW()     ( SIGNAL_PORT &= ~_BV(SIGNAL) )
Damit werden dann Initialisierung und Senden zu sowas wie
SIGNAL_OUTPUT();
SIGNAL_LOW();
..
if (tastegedrückt)
{
  SIGNAL_HIGH();
  _delay_us(1);
  SIGNAL_LOW();
  _delay_us(1);
  ..
}
- 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

Autor: laiehoch10 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: laiehoch10 (Gast)
Datum:

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

Autor: laiehoch10 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Könnte ich hiermit das Signal auswerten?
#include <avr\io.h>
#include <util\delay.h>

void init (void)
{
   DDRB  = DDRB  & ~0b00000011;    // PortA.0 als Eingang
   PORTB = PORTB | 0b00000001;     // PortA.0 mit PullUpWiderstand
}

int main (void)
{

unsigned char i;
int n=0;

   init ();

   do
   {

      i = PINB & 0x01;
    if (i == 0)
     n++;

    _delay_ms(1);  

      i = PINB & 0x01;
    if (i == 0)
     n++;

    _delay_ms(1);

      i = PINB & 0x01;
    if (i != 0)
     n++;

    _delay_ms(1);

    i = PINB & 0x01;
    if (i == 0)
     n++;

     _delay_ms(1);


    i = PINB & 0x01;
    if (i != 0)
     n++;

    _delay_ms(1);

    i = PINB & 0x01;
    if (i == 0)
     n++;

    _delay_ms(1);


    i = PINB & 0x01;
    if (i == 0)
     n++;

    _delay_ms(1);

    if(n == 8)
    {
      PORTB |= 0b00000010;
    _delay_ms(200);
    n=0;
    }      


   } while (1);


  
   return 0;
}

Autor: Walter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
laiehoch10 schrieb:
> Könnte ich hiermit das Signal auswerten?

nein, du musst auf irgendwie auf den stART synchronisieren

Autor: laiehoch10 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Walter schrieb:
> nein, du musst auf irgendwie auf den stART synchronisieren

hättest du da einen vorschlag?

Autor: g457 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
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):
_delay_us(500);
if (!SIGNAL_IS_SET()) {
   // Sonnenwinde..
   $zurück_auf_los/return/break/panic/..
}
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:
uint8_t result = 0;
for (int i = 0; i < 8; i++) {
   result <<= 1;
   result |= SIGNAL_IS_SET() ? 1 : 0;
   _delay_ms(1);
}

Abschließend noch die defines:
#define SIGNAL           1
#define SIGNAL_PIN       PINB
#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.

Autor: laiehoch10 (Gast)
Datum:

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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.