Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Assembler in C?

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 < [ 2 ]
000
17.03.2005, 14:34 Uhr
MaddinNeedsHelp



Erstmal ein nettes hallo an alle da draußen

Bin im 6. Semester Bioinformatik und habe folgendes Problem gestellt bekommen, was mir kopfzerbrechen liefert:

ich muss auf eine feste Hardware-Adresse zugreifen und dort register überprüfen, ob sie gesetzt sind oder nicht. Es handelt sich hierbei um eine ISA-Karte und zwar genau um einen A/D-Wandler (Analog/Digital Wandler) welchen ich mit Hilfe eines C-Programmes ansprechen soll. Dazu gehören register setzen und gewisse register löschen.

Ein Kumpel meinte das Ansprechen des Assemblers in C ermögliche es, Hardware adressen anzusprechen.
Sowas hab ich aber noch nie gemacht und keinen peil davon

hab aber glücklicherweise auch ein prog-source was allerdings in basic ist und wo das ansprechen der hardware adresse sauuu einfach ist (ich muss es aber in c schreiben...).

Wäre nett wenn ihr mir helfen könntet


C++:
program DCI14;                    (* AD/DA Wandlung f&#65533;r 14 bit Karte DCI-14 *)

(* AD-Kan&#8222;le dieser Karte ben&#8221;tigen immer einen definierten Spannungspegel,
d.h. offene AD-Eing&#8222;nge bei dieser Karte unbedingt auf Masse (PC-GND) legen,
z.B. &#65533;ber einen Pull-down-Widerstand 1 kOhm bei 5 V max. Eingangsspannung *)

uses Crt;
const
     adr: word = $260;                        (* Basisadresse AD/DA-Wandler *)
     Aufloesung: real = 5/16384;                 (* 5 V / 14 Bit = 305 æV *)
var
   i: byte;
   Wandlerwert: word;
   Spannung,u1,u2: real;

procedure Analog_in (Kanal_Nr: byte);                  (* AD-Kanal einlesen *)
var
   j,k,convert: byte;
begin
     port[adr]:=Kanal_Nr;                         (* Kanal-Nummer &#65533;bergeben *)
     port[adr+1]:=0;                                    (* Register l&#8221;schen *)
     for j:=1 to 8 do         (* AD-Wandlung starten durch Einlese-Schleife *)
     begin
          convert:=port[adr+12];                         (* AD-Wandlung low *)
          for k:=0 to 25 do;                        (* Verz&#8221;gerungsschleife *)
     end;                (* Wandlungs-Delay anpassen: hier f&#65533;r 486DX-40 MHz *)
     for j:=1 to 8 do
     begin
         convert:=port[adr+10];                         (* AD-Wandlung high *)
         for k:=0 to 25 do;                         (* Verz&#8221;gerungsschleife *)
     end;                                       (* Wandlerwert einlesen und *)
     Wandlerwert:=portw[adr+2] and $3FFF;      (* 2 bits im Hi-byte l&#8221;schen *)
     Spannung:=Wandlerwert*Aufloesung;
end;

(* DA-Kan&#8222;le sind nach einem Kaltstart des Rechners auf maximalem Ausgangs-
  spannungspegel ! hier: 5 V  *)

procedure Analog_out (Kanal_Nr: byte; Spannung: real);
begin
     case Kanal_Nr of   (* Spannung umrechnen und 2 bits im Hi-byte l&#8221;schen *)
          1: portw[adr+4]:=Round(Spannung/Aufloesung) and $3FFF;
          2: portw[adr+6]:=Round(Spannung/Aufloesung) and $3FFF;
     end;
end;

begin
     ClrScr; u1:=3.8; u2:=5.0;        (*Hier wird der Wert gesetzt für die beiden Kanäle!!)
     Analog_out(1,u1); Analog_out(2,u2);
     writeln('DA-Kanal 1 : ',u1:4:2,' V');
     writeln('DA-Kanal 2 : ',u2:4:2,' V');
     writeln('Kanal  Wandlerwert  Spannung');
     repeat
           for i:=0 to 15 do
           begin
                Analog_in(i);
                gotoXY(3,4+i);write(i);
                gotoXY(8,4+i);write(Wandlerwert:5);
                gotoXY(23,4+i);write(Spannung:4:2);
           end;
     until keypressed;
     Analog_out(1,0); Analog_out(2,0);
end.



Gruß

Maddin


Bearbeitung von ao:
quote-Tags durch cpp-Tags ersetzt

Dieser Post wurde am 17.03.2005 um 19:20 Uhr von ao editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
17.03.2005, 15:13 Uhr
Th



So wie es aussieht, benötigst du eine Struktur, da auf mehrere Adressen zugegriffen wird.

Generell geschieht ein Zugriff in C auf Hardware-Adressen mittels Zeigern (Pointer), z.B.


C++:
char *pAdr = 0x260;

*pAdr = 0; // setzt das Byte an Adresse 0x260 auf 0



Für Words (2 Byte) solltest du dann den Datentyp short / unsigned short verwenden, also

C++:
short *pAdr = 0x260;

*pAdr = 0xffff; // setze das Lo und Hi-Byte auf 0xff



Um einen Offset zu verwenden, folgende Code verwenden:

C++:
char *pAdr = 0x260;

*(pAdr+10) = 42; // setzt an Adresse 0x260 + 10 = 0x26A den Wert auf 42



Bei short/int beachten, daß der Offset nicht in Bytes sondern in Vielfachen des Datentyps angesehen wird, also

C++:
short *pAdr = 0x260;

*(pAdr + 10) = 100; // setzt an Adresse 0x260 + 2*10 = 0x274 den Wert auf 100 (als 2 Bytes)



Du brauchst also kein Assembler direkt verwenden, außer du mußt spezielle Assembler-Operationen durchführen (scheint hier aber NICHT der Fall zu sein).

Bei Zugriff auf mehrere Werte im Speicher empfielt sich eine Struktur, da die einzelnen Elemente einer Struktur hintereinander im Speicher liegen, z.B

C++:
struct SAdr
{
    char x;      // Offset 0
                   // Offset 1 (anonymes padding-byte)
    short s1;   // Offset 2
    short s2;   // Offset 4
    // ...
};

SAdr *pAdr = 0x260;

pAdr->x = 0;
pAdr->s1 = 0xffff;



Ich hoffe, dies hilft dir weiter...
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
17.03.2005, 15:25 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)


öhm mal ne kleine anmerkung dazu... es ist z.b. nicht garantiert das short 2 byte gross ist
--
...fleißig wie zwei Weißbrote

Dieser Post wurde am 17.03.2005 um 15:25 Uhr von Windalf editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
17.03.2005, 15:36 Uhr
Tommix



Hallo,
unter vielen Systemen kann man so wie Th meint auch nicht auf bestimmte physikalische Speicheradressen zugreifen. Der Adresse nach zu urteilen, sind hier aber sowieso I/O operationen ala _inp, _outp gemeint. Also: Welches OS, welcher Compiler? - Das ganze ist mit reinem ANSI C vermutlich nicht lösbar.

- Tommix
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
17.03.2005, 21:22 Uhr
MaddinNeedsHelp




Zitat von Tommix:
Hallo,
unter vielen Systemen kann man so wie Th meint auch nicht auf bestimmte physikalische Speicheradressen zugreifen. Der Adresse nach zu urteilen, sind hier aber sowieso I/O operationen ala _inp, _outp gemeint. Also: Welches OS, welcher Compiler? - Das ganze ist mit reinem ANSI C vermutlich nicht lösbar.

- Tommix



hmmm, was genau meinst du damit tommix?

@th, danke für dein tips, ich schau mal was ich damit machen kann, ohje da hab ich mir was eingebrockt mit der aufgabe...dachte es wäre einfach und dann sowas

aber ist jetzt die aufgabe einfach zu lösen mit ansi c? weil c++ wollt ich eigentlich nicht verwenden, das ist nicht so mein fall

mit perl ist wohl überhaupt nicht möglich soweit ich das gemerkt habe, das wäre mir eigentlich am liebsten...

Gruß an alle

Maddin
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
18.03.2005, 07:50 Uhr
(un)wissender
Niveauwart


Solange du nichts über dein Zielsystem erzählst kann dir hier keiner helfen.
Läuft das obige Programm denn? Weil normalerweise darfst du nicht einfach auf Port zugreifen. Vermutlich kapselt dieser "port" aber nur irgendwelche BS-Routinen, die du mit c direkt ansprechen musst.
Das was Th beschrieben hat ist Memory Mapped IO.
--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
18.03.2005, 12:20 Uhr
MaddinNeedsHelp



also, das zielsystem spielt eigentlich keine rolle, wie bereits geschrieben ist es eine isa-karte auf der eine fest eingestellte basisadresse (hexa 260) angesprochen werden muss, also auf jedem system, das einen isa-slot besitzt muss dieses programm laufen, zum beispiel läuft das basic programm auf meinem alten pentium II system ohne probleme

oder was genau meinst du mit system?

danke schonmal für eure hilfe!
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
18.03.2005, 12:36 Uhr
Tommix



Ich bin zwar nicht "du" sondern "ich" aber: Wir meinen Betriebssystem. Sowas kann man unter Linux oder Windows XP nicht so lösen, wie unter MS-DOS. Und was mir noch immer nicht klar ist: Ist das eine IO-Adresse, oder eine Speicheradresse?

- Tommix
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
18.03.2005, 14:34 Uhr
MaddinNeedsHelp



also unter windowsxp das anzusprechen soll nicht so einfach sein, ich werde das programm nur unter windows98 rechnern ausführen lassen, d.h ist wohl ein dos-betriebssystem auf dem es funken soll

hmmm, ob das jetzt ein IO-Adresse ist, oder eine Speicheradresse, weiß ich nicht, bin ich überfragt. Ist auf jeden Fall ein Speicher mit einem Register auf der Karte den man über Programme ansteuern kann. Die Basisadresse hex 260 kann man auch mit jumpern auf der A/D-Karte ändern. Ich hoffe das hilft dir weiter...verdammt ich könnt mich ohrfeigen für dieses kack-thema

Gruß

Maddin
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
18.03.2005, 15:02 Uhr
Tommix



Damit sind wir auf jeden Fall außerhalb des Standards, es wird dann wohl irgendwie so gehen:

C++:
#include <conio.h>

const unsigned short adr = 0x0260;

// aus port[adr]:=Kanal_Nr wird z.B:
_outp(adr, Kanal_Nr);
// und aus convert:=port[adr+12]
convert = _inp(adr+12);
// usw.



Gruß, Tommix
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 < [ 2 ]     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: