Hallo,
ich würde gernen in meinem C-Code ein ein Stück Assamblercode einfügen.
Ich will die Bits, die am PINC anliegen in ein Register speichern.
dazu hab ich mir folgendes überlegt:
1
asmvolatile(
2
"in r16, PINC"
3
);
aber das klappt nicht.
Kann mir jemand helfen?
Gruß
Loo
Aber das kunktioniert nicht...
Ich brauche von PINC nur das Bit 5 also PC5. Daher hab ich oben noch ein
maskierbyte.
Wenn ich das array DatenBits auslese, dann stehen da nur Nullen drin,
obwohl an PC5 Daten ankommen.
Bitte um Hilfe
Gruß
Loo
Loo schrieb:
> ich würde gernen in meinem C-Code ein ein Stück> Assamblercode einfügen.
Ist das eine Übung, oder soll das irgendeinen praktischen Nährwert
haben?
Der inline-Assembler vom GCC ist relativ komplex und alles andere
als etwas, was man sich als Anfänger auf die Tagesordnung setzen
sollte. Er ist insbesondere ein nettes Werkzeug für Bibliotheks-
entwickler, die damit plattformspezifische Funktionalität prima
(und vor allem ohne Einbußen bei der restlichen Optimierungsarbeit
des Compilers) integrieren können, aber er lebt natürlich in der
Ebene, in der der Compiler auch optimiert. Von daher muss man ein
wenig verstanden haben, wie der Compiler arbeitet, damit man ihn
auch sinnvoll einsetzen kann.
Für deine Aufgabe sehe ich erst einmal nicht, was dich davon abhält,
das alles in C zu schreiben.
das ist ein atmega8.
DDRC ist für PC5 auf Eingang gesetzt, also 0.
was jtag interface bedeutet weiss ich nicht, aber ist vermutlich
abgeschaltet.
Ist denn der Code soweit OK?
Gruß
Loo
Loo schrieb:
> Also ich muss so schnell wie möglich die Daten am PC5 des uC einlesen.
OK.
> Am besten mit jedem Takt.
Geht nur für eine begrenzte Anzahl, denn in einem Takt lässt sich
nur etwas in ein CPU-Register lesen, mehr nicht. Für eine
begrenzte Anzahl macht auch der Compiler schon das Richtige:
1
#include<avr/io.h>
2
3
int
4
readit(uint8_t*data)
5
{
6
uint8_ta,b,c;
7
8
a=PINC;
9
b=PINC;
10
c=PINC;
11
12
data[0]=a;
13
data[1]=b;
14
data[2]=c;
15
}
compiliert zu:
1
readit:
2
/* prologue: function */
3
/* frame size = 0 */
4
movw r30,r24
5
in r24,51-32
6
in r25,51-32
7
in r18,51-32
8
st Z,r24
9
std Z+1,r25
10
std Z+2,r18
11
/* epilogue start */
12
ret
Für eine Variable Anzahl von Bytes wirst du es in Assembler kaum
schneller bekommen als der Compiler:
1
#include<avr/io.h>
2
3
int
4
readit(uint8_t*data,uint8_tcount)
5
{
6
do{
7
*data++=PINC;
8
}while(--count!=0);
9
}
ergibt:
1
.global readit
2
.type readit, @function
3
readit:
4
/* prologue: function */
5
/* frame size = 0 */
6
movw r30,r24
7
.L2:
8
in r24,51-32
9
st Z+,r24
10
subi r22,lo8(-(-1))
11
brne .L2
12
/* epilogue start */
13
ret
Und was soll das mit der Maske? Die hast du ja dort noch nicht
benutzt.
yamamoto schrieb:
> if(ausblenden=0b00100000){
Das macht vermutlich nicht das, was du willst, das es tut.
> Aber eigentlich Muss ich insgesamt 8 Bit oder 16 Bit direkt hinter> einander einlesen.
Aber du suchst nicht etwa ein SPI-Interface?
Nein, SPI suche ich nicht.
und eigentlich hab ich in der if das stehen:
1
if(ausblenden==32){
Eigentlich müsste das doch so richtig sein.
Ich sende mit einem anderen Flexray-Chip andauernd Nullen und Einsen auf
den Bus.
Aber im Display der Empängers stehen nur Nullen.
Jörg, dein Code kann ich leider im moment nicht ausprobieren. Aber mit
meinem Assamblercode müsste das doch auch klappen?!?
Danke übrigens für die Hilfe!!!!
Du solltest dich mal entscheiden, wann du 0b00100000 und wann 32
schreibst. Am besten machst du ein #define dafür.
> Eigentlich müsste das doch so richtig sein.
Ich blicke immer noch nicht ganz durch, was denn da ausgeblendet
werden soll, aber das doppelte Gleichheitszeichen ist natürlich
erst einmal richtig.
> Ich sende mit einem anderen Flexray-Chip andauernd Nullen und Einsen auf> den Bus.
Hat der denn den gleichen Takt wie der AVR, oder wie soll das
funktionieren?
> Aber mit> meinem Assamblercode müsste das doch auch klappen?!?
Nein, da gibt's einen subtilen Unterschied...
Bei der Benutzung des inline-Assemblers ist es wirklich ratsam, dass
man am Ende nochmal den generierten Assemblercode verifiziert. Ich
mache das immer, indem ich statt mit -c mit -S compiliere: dann legt
der Compiler eine Datei ${dateiname}.s an, die den Assemblercode
enthält. All die Disassembler-Listings finde ich nur halb so
übersichtlich.
>Ich blicke immer noch nicht ganz durch, was denn da ausgeblendet>werden soll
Ich speichere den ganzen PINC, also alle 8 Bit die da rauskommen. Aber
ich brauche nur das Bit-Nr.5...
Daher habe ich erstmal das maskierbyte wo alles Nullen sind außer
Bit-Nr.5.
Dann mache ich eine und-Verknüpfung mit DatenBits. Als Ergebnis lifert
mir diese Operation alle Bits als Nullen weil eben egal ist ob in
"DatenBits" ne 1 oder eine 0 steht, denn die & operation liefert dann
null.
Ausser an der 5.Stelle. Da kommt es darauf an. Wenn da eine eins steht
ist im "ausblenden=0b00100000=32". Sonst ist da eine Null.
>Hat der denn den gleichen Takt wie der AVR, oder wie soll das>funktionieren?
Der Sender-Flexray-Chip wird ebenfalls von einem atmega8 gesteuert.
Der arbeitet mit dem Gleichen takt, also 10Mhz.
In dem Sendercode hab ich ebenfalls ein inline-assamblercode eingebaut,
damit er mit jedem Takt ein Bit auf den Bus sendet.
Es geht mir erstmal darum irgendwie mit jedem Takt daten reinzuholen.
> Der Sender-Flexray-Chip wird ebenfalls von einem atmega8 gesteuert.> Der arbeitet mit dem Gleichen takt, also 10Mhz.
Hm, wie stellst du eigentlich sicher, daß dein AVR erst dann den Eingang
sampelt, wenn der Ausgang der Gegenseite einen stabilen Wert angenommen
hat?
>Hm, wie stellst du eigentlich sicher, daß dein AVR erst dann den Eingang>sampelt, wenn der Ausgang der Gegenseite einen stabilen Wert angenommen>hat?
Das stell ich gar nicht sicher. Mir geht es erstmal darum überhaupt was
zu samplen, egal ob das richtig abgetastet wird oder nicht.
Später will ich dann versuchen langsamer zu senden, um zu gucken, ab
welcher Geschwindigkeit fehler auftreten....
Hat jemand eine Idee wie man das besser machen könnte?
yamamoto schrieb:
> Hat jemand eine Idee wie man das besser machen könnte?
. schnellerer Prozessor
. CPLD zum Sampeln benutzen und dann parallel zum AVR ausgeben
Ne, geht leider nicht.
Das ist genau der Knackpunkt dieser Aufgabe. Ich muss es irgendwie
schaffen mit dieser Hardware eine Abtastung vorzunehmen.
Es muss halt nicht mit maximaler Datenrate sein. Ich wollte erstmal mit
dem obigen Programm grundsätzlich versuchen...
Habt ihr Vorschläge, wie man das im Code realisieren könnte?