Forum: Compiler & IDEs Byte an Pin ausgeben?


von F. H. (at90s1200)


Lesenswert?

Hallo ich möchte ein Byte an BORTB PB0 ausgeben den Takt kann ich dann 
selbst bestimmen.

ATmega644 8MHz
1
#include <stdbool.h>
2
#include <avr/io.h>
3
#include <util/delay.h>
4
5
char Manchester_enCode(unsigned char date);
6
7
8
int main(void)
9
{
10
  
11
  DDRB = (1<<PB0);
12
13
  
14
    while(1)
15
    {
16
    PORTB = Manchester_enCode(PIND);
17
    }
18
}
19
20
char Manchester_enCode(unsigned char date)//OUT gehendes signal an PORT.(empfaenger z.B. PORTx = Pxx) Das ganze braucht 8mSec.
21
{
22
  char code = 0;
23
  char i;
24
  bool takt;
25
  
26
  while(1)
27
  {
28
    _delay_us(250);
29
    ~takt;
30
    
31
    return(1);
32
  }
33
  
34
  code = ~(takt ^ date);
35
  
36
  for (i = 0; i < 7; ++i)
37
  {
38
    _delay_us(500);
39
    
40
    return(code << i);   // Alle 500µSec schieben
41
    
42
  }
43
  
44
}

von Helmut L. (helmi1)


Lesenswert?

F. H. schrieb:
> for (i = 0; i < 7; ++i)
>   {
>     _delay_us(500);
>
>     return(code << i);   // Alle 500µSec schieben
>
>   }

Die Schleife wird exakt 1 mal durchlaufen. Bei return verschwindet die 
in die aufrufende Routine.

F. H. schrieb:
> while(1)
>   {
>     _delay_us(250);
>     ~takt;
>
>     return(1);
>   }

Das gleiche hier auch.

von Rolf M. (rmagnus)


Lesenswert?

Außerdem hat folgendes keinerlei Auswirkung:

F. H. schrieb:
> ~takt;

von Thomas E. (thomase)


Lesenswert?

F. H. schrieb:
> Hallo ich möchte ein Byte an BORTB PB0 ausgeben den Takt kann ich dann
> selbst bestimmen.
Aber so doch nicht. Nach 250µs wird PB0 auf 1 gesetzt. Mehr macht dein 
Programm nicht. Kann man auch einfacher lösen:
1
int main(void)
2
{  
3
  DDRB = (1<<PB0);  
4
  _delay_us(250);
5
  PORTB = (1<<PB0);   
6
  while(1);
7
}

Um in C etwas zu programmieren, brauchst du auch Kenntnisse in C. Deine 
"return-Konstruktionen" zeigen aber, daß diese gegen Null tendieren.
So wird das nichts.

mfg.

von Helmut L. (helmi1)


Lesenswert?

Thomas Eckmann schrieb:
> Um in C etwas zu programmieren, brauchst du auch Kenntnisse in C. Deine
> "return-Konstruktionen" zeigen aber, daß diese gegen Null tendieren.
> So wird das nichts.

Karl Heinz raet ab dann immer dazu sich ein C Buch anzuschaffen.

von F. H. (at90s1200)


Lesenswert?

Hi
Ich habe eure Vorschläge zu herzen genommen und mal einen neuen Ansatz 
versucht, ich benutze jetzt den timerer0 für den Takt.

Das mit dem Pin klappt auch durch   DDRB = (1<<PB0);

leider komme ich so nicht weiter ich denke das ich den Ansatz das mit 
nem XOR umzusetzen nicht gelingt 
http://de.wikipedia.org/wiki/Manchester-Code#Weiteres
Zitat: "Praktisch kann die Codierung und Decodierung durch eine 
invertierte XOR-Verknüpfung des Trägers mit dem Nutzsignal erfolgen."

Ich bitte um Ratschläge und weitere Anstöße.
1
/*
2
 * sender.c
3
 *
4
 * Created: 10.01.2013 19:23:23
5
 *  Author: 
6
 */ 
7
8
#include <stdbool.h>
9
#include <avr/io.h>
10
#include <util/delay.h>
11
#include <avr/interrupt.h>
12
13
14
char Manchester_enCode(unsigned char date);
15
bool takt = true;
16
17
 
18
/*
19
Der Overflow Interrupt Handler
20
wird aufgerufen, wenn TCNT0 von
21
255 auf 0 wechselt (256 Schritte),
22
d.h. ca. alle 2 ms
23
*/
24
#ifndef TIMER0_OVF_vect
25
// Für ältere WinAVR Versionen z.B. WinAVR-20071221 
26
#define TIMER0_OVF_vect TIMER0_OVF0_vect
27
#endif
28
 
29
ISR (TIMER0_OVF_vect)
30
{
31
  /* Interrupt Aktion alle
32
  (1000000/8)/256 Hz = 488,28125 Hz
33
  bzw.
34
  1/488,28125 s = 2,048 ms  
35
  */
36
  
37
  ~takt;  
38
  
39
}
40
41
42
43
int main(void)
44
{
45
  
46
  // Timer 0 konfigurieren
47
  TCCR0B = (1<<CS01); // Prescaler 8
48
  
49
  // Overflow Interrupt erlauben
50
  TIMSK0 |= (1<<TOIE0);
51
  
52
  // Global Interrupts aktivieren
53
  sei();
54
  
55
  
56
  DDRB = (1<<PB0);
57
58
  
59
    while(1)
60
    {
61
     Manchester_enCode(0x0f);
62
    }
63
}
64
65
char Manchester_enCode(unsigned char date)//OUT gehendes signal an PORT.(empfaenger z.B. PORTx = Pxx) Das ganze braucht 8mSec.
66
{
67
  char code = 0;
68
  char i;
69
  
70
  
71
  
72
  code = ~(takt ^ date);
73
  
74
  for (i = 0; i < 7; ++i)
75
  {
76
    _delay_us(500);
77
    
78
    PORTB = (code << i);   // Alle 500µSec schieben
79
    
80
  }
81
  
82
}

von Andreas B. (andreas_b77)


Lesenswert?

Die Interrupt-Routine macht überhaupt nichts. Wozu überhaupt diese 
Aufteilung? Wenn die Bits mit einem bestimmten Timing ausgegeben werden 
sollen, dann gehört das Pinwackeln auch in den Timer-Interrupt.

Dann wird das niedrigwertigste Bit von date invertiert, und dieser Wert 
soll dann an die 8 Pins von Port B 7 mal nacheinander ausgegeben werden, 
jeweils um eine Stelle nach links geschoben? Das macht alles keinen 
Sinn, mit Manchester-Code hat das auch überhaupt nichts zu tun.

von Rolf M. (rmagnus)


Lesenswert?

F. H. schrieb:
> Ich habe eure Vorschläge zu herzen genommen

Meinen aber nicht, denn das hier:

F. H. schrieb:
> ~takt;

hat immer noch keinen Effekt.

von F. H. (at90s1200)


Lesenswert?

Hi

Ja da hast du recht, ich habs gleich mal getestet und es hat wirklich 
keine aus Wirkung.

Ich habe nun ein bisschen Rum gespielt, nun sehe ich auch was auf dem 
oszi nur sind die Rechtecke immer gleichlang und der Abstand zueinander 
ist auch immer gleich, nur die posizionen wandern es rutscht nach vorne 
und nach hinten.
1
/*
2
 * sender.c
3
 *
4
 * Created: 10.01.2013 19:23:23
5
 *  Author: 
6
 */ 
7
8
#include <stdbool.h>
9
#include <avr/io.h>
10
#include <util/delay.h>
11
#include <avr/interrupt.h>
12
13
14
char Manchester_enCode(unsigned char date);
15
16
 
17
int main(void)
18
{
19
  
20
  DDRB = (1<<PB0);
21
  char i;
22
  
23
    while(1)
24
    {
25
    for (i = 0; i < 127; ++i){  }//Schleife, um zu testen, was für Unterschiede bei unterschiedlichen werten auftreten. 
26
      
27
     Manchester_enCode(i);
28
    }
29
}
30
31
char Manchester_enCode(unsigned char date)//OUT gehendes Signal an PORT.(empfaenger z.B. PORTx = Pxx) das Ganze braucht 8mSec.
32
{
33
  char code = 0;
34
  char i;
35
  
36
  
37
  
38
  code = ~(date ^ 0x55); //Manchester-Code Umwandlung
39
  
40
  for (i = 0; i < 7; ++i) //Schleife, um an einem Pin ein Byte aus zu geben, schieben mit der maximal Frequenz nicht mehr als 2kHz
41
  {
42
    _delay_us(500);
43
    
44
    PORTB = (code << i);   // Alle 500µSec schieben und ausgeben
45
    
46
  }
47
  
48
}

Danke !!

von Walter S. (avatar)


Lesenswert?

F. H. schrieb:
> PORTB = (code << i);   // Alle 500µSec schieben und ausgeben

das ist Käse,
zum einen warum den ganzen Port setzen?
zum anderen wird beim erstem Mal das unterste Bite ausgegeben,
dann 7x die 0!

von F. H. (at90s1200)


Lesenswert?

Nun wie könnte man das machen?

von Karl H. (kbuchegg)


Lesenswert?

F. H. schrieb:
> Nun wie könnte man das machen?


SChau dir halt mal die WIkipedia dazu an.

Ein 0 Bit wird übertragen, in dem die Leitung auf 0 startet und nach der 
CLockzeit auf 1 wechselt.
Ein 1 Bit wird übertragen, in dem die Leitung auf 1 startet und nach der 
Clockzeit auf 0 wechselt.


Ist doch nicht so schwer. Das Diagramm auf Wikipedia zeigt ganz klar, 
wie Manchester-Code funktioniert.


Deine 'Takt-Geschichte', an der du dich aufgehängt hast, die ist für den 
Empfänger relevant, bzw. wenn du den Manchester Code in Hardware anhand 
eines vorgegebenen Taktsignals erzeugen müsstest.

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.