PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : C-Code mit gcc kompilieren



vb60freak
30-11-2002, 13:56
hi, ich hab ein kleines problem mit der kompilierung von c-code mit dem kompiler gcc. das programm funktioniert so wie es hier ist unter windows einwandfrei (da kompiliert mit MS-VC++ !!) nur unter linux (suse 7.0) macht die kompilierung probleme. das programm steuert ein 2x20 display an. kompilierungsfehler im asm-teilstück...

kann mir da jemand weiterhelfen ?

gruß vb60freak

Quellcode:

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <tchar.h>



unsigned char ContrPort;

void delay(int milliseconds){
int i;
for ( i = 0; i < 40000; i++ )
{}
}

void Out32(short PortAddress,unsigned char Value){
__asm{
push dx
mov dx,PortAddress
mov al,Value
out dx, al
pop dx
}
}

void SendLCD(unsigned char Bit){
//{sequenzielles der 8-bit daten, instructionscodes über Strobe-Leitung (Hardware)
// Zeitverzögerung zur Anpassung des PCs an die Geschwindigkeit des LCD-Displays}
Out32(888,Bit);
delay(1);
Out32(890,ContrPort); //Strobe toggeln
delay(1);
Out32(890,ContrPort+1); //Strobe toggeln
delay(1);
}

void init(void){
//{Initialisierung des Displays}

ContrPort=10; //Commands Set
SendLCD(48); //Set
delay(5); //Warten > 4.1ms
SendLCD(48); //Set
delay(1); //Warten >100us
SendLCD(48); //Set
SendLCD(56); //8 bit
SendLCD(8); //Set_Display + Cursor_Off + Blink_Off
SendLCD(1); //Clear Display
SendLCD(6); //Set_Entry_Mode + Increment_Address + Shift_Display_Off
SendLCD(12); //display ON, cursor OFF, blink Off
ContrPort=14; //Data Set
}


void write(char tl1[40],char tl2[40]){ //Displaydaten aufbereiten > in Variable sammeln und in einzelne Chars vereinzeln
int LCDCode, Zaehler, Zaehler2, tl1len, tl2len ,x;
char LCDDaten[80];
init(); //Initialisierung des Displays
Zaehler = 0;
Zaehler2 = 0;
x=0;
tl1len = strlen( tl1 );
tl2len = strlen( tl2 );
while( Zaehler != (tl1len)) {
LCDDaten[Zaehler] = tl1[Zaehler];
Zaehler++;
}
while( Zaehler != 40) {
LCDDaten[Zaehler] = ' ';
Zaehler++;
}
while( Zaehler2 != (tl2len)) {
LCDDaten[Zaehler] = tl2[Zaehler2];
Zaehler++;
Zaehler2++;
}
while( Zaehler2 != 40) {
LCDDaten[Zaehler] = ' ';
Zaehler2++;
Zaehler++;
}
Zaehler = 0;
while( Zaehler < 80) {
LCDCode = __toascii( LCDDaten[Zaehler] ); //Daten für Display aufbereiten ASCII > 8-bit
SendLCD(LCDCode);
Zaehler++;
}
}

void main(void){

write("Hallo Welt !"," ");
}


[CODE]

nobody0
30-11-2002, 14:43
Assembler ist sehr Plattform- und Compilerspezifisch; das muss immer extra portiert werden und vermutlich liegt es daran.

The Ripper
30-11-2002, 15:44
Das Sprachkonstrukt __asm {} ist eine Microsoft-Erweiterung und steht im gcc nicht zur Verfügung, nachzulesen in der MSDN (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang/html/_langref___asm.asp).
Dürfen Linux-Programme überhaupt Daten an IO-Ports senden (das was die Assemblerroutine macht)?
Lichtblick: Dein Programm scheint die Druckerschnittstelle anzusprechen (888=0x378), das geht unter Linux über die Gerätedateien in /dev/

Die Funktion delay() ist übrigens unvollständig, und eine Schleife ist nicht wirklich dazu geeignet, den Prozess schlafen zu legen, benutze stattdessen nanosleep() ;)

anda_skoa
30-11-2002, 15:51
Original geschrieben von The Ripper

Dürfen Linux-Programme überhaupt Daten an IO-Ports senden (das was die Assemblerroutine macht)?


Mit den nötigen Rechten, ja.




Lichtblick: Dein Programm scheint die Druckerschnittstelle anzusprechen (888=0x378), das geht unter Linux über die Gerätedateien in /dev/


Ich hab mal in einem Labor ein LCD über Parallel Port eines Mikrocontrollers angesprochen.
Auf eine PC sollte es reichen, einzelne Bits am Parallelport zu ändern und dem Treiber zu überlassen, wei er das macht.

Unter Linux kann man sowas zB mit parapin machen: http://www.circlemud.org/~jelson/software/parapin/

Ciao,
_

vb60freak
30-11-2002, 15:54
ne idee, wie ich das programm umändern könnte, wenn ich über die gerätedef. von /dev/lp0 gehe ??

gruß vb60freak

pik7
30-11-2002, 15:58
Auch wenn der Compiler das programm ohne
Fehler durchorglen sollte, wird das nicht funktionieren.

benutze die io Funktionen die man im Userspace
benutzen sollte für solche Sachen.

man ioperm
man outb

gruß

nobody0
30-11-2002, 17:49
Vom Parallelport gibt es mehrere Versionen: EPP, ECP, Standard und die haben jeweils mehrere Register an verschiedenen Adressen. Standard hat man immer.
Wenn man weiss wohin die Daten müssen, kann man die z. B. mit outb(vAlUe,pOrT) schreiben, aber es geht auch mit 16-Bit-Zugriffen auf zwei benachbarte Register gleichzeitig (mit 4 Registern u. 32-Bit-Zugriff müsste es auch gehen).
Unter www.linuxmagazin.de findet man einige Artikel zum Parallelport.