Anzeige:
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 15 von 21

Thema: Software für Schieberegisterschaltung

  1. #1
    narf Avatar von Pinky
    Registriert seit
    Dec 2003
    Ort
    München
    Beiträge
    105

    Software für Schieberegisterschaltung

    Hallo,
    ich bin gerade dabei eine Software für folgende Schaltung zu schreiben:



    hier meine ersten Ansätze:

    Code:
    #include <stdio.h>
    #include <string.h>
    #include <asm/io.h>
    
    #define D_COM1              0x3F8
    /* define D_COM2              0x2F8 */
    
    int main( int argc, char *argv[] )
    {
       if ( ioperm( D_COM1, 6, 1) != 0 ) { /* get IO/perm */
          perror( "ERROR: can´t open COM device for read/write" );
          return(-1);
       }
         outb( 0x00, D_COM1 ); /*alles low*/
            
            outb( 0x0C, D_COM1 ); /* data 1 , clock 1*/
            outb( 0x00, D_COM1 ); /* clock 0*/
           
            outb( 0x08, D_COM1 ); /data 0 , clock 1*/
            outb( 0x00, D_COM1 ); /*clock0 */
                        
            outb( 0x0C, D_COM1 ); /*data 1 clock 1*/
            outb( 0x00, D_COM1 ); /* clock 0*/
    
            outb( 0x40, D_COM1 ); /*strobe 1*/
            outb( 0x00, D_COM1 ); /*strobe 0 */
                                       
       return( 0 );
    }
    ich denke der Code erklärt sich von selbst.

    Nun das Problem: Wenn ich das Programm mit gcc -o test test.c -O2 kompiliere und ausführe tut sich leider an LEDs überhaupt nichts. Ich hoffe ihr könnt mir sagen , warum sich nichts tut.

    Gruß
    Michi

  2. #2
    Registrierter Benutzer
    Registriert seit
    Oct 1999
    Ort
    Kiel
    Beiträge
    1.798
    Hi

    laut wahrheitstabelle braust du auf strope ein high-signal damit sich die parallelen ausgänge ändern.

    und mit einer 5 V versorgung könnten die ströme für die leds zu gering sein .

    Code:
    IOL LOW Level  VDD = 5.0V, VO = 0.4V      0.44  0.88  mA
    
    IOH HIGH Level VDD = 5.0V, VO = 4.6V     -0.44  0.88  mA
    bei 13.5 V oder 9.5 V sollten die leds schon leuchten

    gruss
    christoph

  3. #3
    Benutzter Registrierer
    Registriert seit
    Feb 2004
    Beiträge
    2.281
    Moin,

    Jepp, Strobe sollte High sein, damit die Ausgangsbuffer aktiviert werden, die Ausgaenge koennen tatsaechlich lt. Datenblatt recht wenig Strom treiben, es muesste aber bei 5V ausreichen, damit LEDs geradeso erkennbar ein bisschen funzeln, aber Vorwiderstaende sollten da auf jeden Fall eingebaut sein, denn sonst koennte sich das Schiebereg. auf den Schlips getreten fuehlen. Wenn die Versorgungsspannung erhoeht wird, muessen auch andere Zenerdioden eingebaut werden, sonst ist logisches Hi nicht mehr Hi genug
    Der Hauptknackpunkt scheint mir aber die SW zu sein; ein serieller Port ist kein Parallelport - d.h. die 3 Ausgaenge werden grundsaetzlich anders angesteuert. Guck' dir mal das Datenblatt vom 16550 an.
    So wie's aussieht, schreibst du die ganzen Bytes lediglich ins Senderegister, d.h. du laesst die TxD Leitung dadurch ein bisschen wackeln, aber eigentlich auch das nicht richtig, weil du nicht wartest, bis der Sendepuffer leer ist - der eigebaute Fifo rettet dir zwar da diesesmal deinen Hals, aber auch nur wenn du die SW nicht zu haeufig hintereinander aufrufst - Aber es kann ja eh' nix passieren, weil die beiden Handshakeleitungen nix mit dem Senderegister zu tun haben. Die liegen in irgendnem andern Register, das du nicht programmierst...

    Gruss
    WK
    Das ist aber zu viel zum Lesen und ich will, dass er einfach kompeliert!

  4. #4
    narf Avatar von Pinky
    Registriert seit
    Dec 2003
    Ort
    München
    Beiträge
    105
    Zitat Zitat von derguteweka
    Jepp, Strobe sollte High sein, damit die Ausgangsbuffer aktiviert werden, die Ausgaenge koennen tatsaechlich lt. Datenblatt recht wenig Strom treiben, es muesste aber bei 5V ausreichen, damit LEDs geradeso erkennbar ein bisschen funzeln, aber Vorwiderstaende sollten da auf jeden Fall eingebaut sein, denn sonst koennte sich das Schiebereg. auf den Schlips getreten fuehlen. Wenn die Versorgungsspannung erhoeht wird, muessen auch andere Zenerdioden eingebaut werden, sonst ist logisches Hi nicht mehr Hi genug
    Leider kenn ich mich nicht so gut in Sachen Elektronik aus, deshalb versuche ich jetzt mal einen kleinen Lösungsansatz zu erstellen.
    1. Ich erhöhe die Spannungsversorgung auf 12V
    2. Die 4,7V Z-Dioden tausche ich durch 12V Z-Dioden aus
    3. Passende Vorwiderstände werden vor die Leds geschaltet, damit die Leds nicht über den Jorden gehen.
    4. die Software sieht jetzt folgendermaßen aus:

    Code:
            outb( 0x40, D_COM1 ); /*trobe 1*/
            
            outb( 0x4C, D_COM1 ); /* data 1 , clock 1 strobe 1*/
            outb( 0x40, D_COM1 ); /* clock 0 strobe1*/
           
            outb( 0x48, D_COM1 ); /data 0 , clock 1 strobe1*/
            outb( 0x40, D_COM1 ); /*clock0 strobe1*/
                        
            outb( 0x4C, D_COM1 ); /*data 1 clock 1 strobe1*/
            outb( 0x40, D_COM1 ); /* clock 0 strobe1*/
    
            outb( 0x00, D_COM1 ); /*strobe 0 */
    Der Hauptknackpunkt scheint mir aber die SW zu sein; ein serieller Port ist kein Parallelport - d.h. die 3 Ausgaenge werden grundsaetzlich anders angesteuert. Guck' dir mal das Datenblatt vom 16550 an.
    So wie's aussieht, schreibst du die ganzen Bytes lediglich ins Senderegister, d.h. du laesst die TxD Leitung dadurch ein bisschen wackeln, aber eigentlich auch das nicht richtig, weil du nicht wartest, bis der Sendepuffer leer ist - der eigebaute Fifo rettet dir zwar da diesesmal deinen Hals, aber auch nur wenn du die SW nicht zu haeufig hintereinander aufrufst - Aber es kann ja eh' nix passieren, weil die beiden Handshakeleitungen nix mit dem Senderegister zu tun haben. Die liegen in irgendnem andern Register, das du nicht programmierst...
    Damit kann ich leider überhaupt nichts anfangen , sorry.

  5. #5
    Benutzter Registrierer
    Registriert seit
    Feb 2004
    Beiträge
    2.281
    Moin,

    Zitat Zitat von Pinky
    Leider kenn ich mich nicht so gut in Sachen Elektronik aus, deshalb versuche ich jetzt mal einen kleinen Lösungsansatz zu erstellen....
    Nee, lass' den Loetkolben erstmal aus und die Schaltung so wie sie ist, wenn du keine Sonnenbrille aufhast, wirst du die LEDs auch an 5V leuchten sehen.
    Zitat Zitat von Pinky
    Damit kann ich leider überhaupt nichts anfangen , sorry.
    Hmm, das ist aber schlecht Wenn du Bausteine (hier den UART) auf Registerebene programmieren willst, dann musst du doch wissen, fuer was welches Register und welches Bit darin gut sind...Du schreibst alles in den Port D_COM1, beim Schreiben ist das das Senderegister des UARTs; beim Lesen das Empfangsregister. Um aber z.b. die Handshakeleitungen zu setzen, ist aber das Modemkontrollregister zustaendig, das waere dann unter D_COM1+4 zu finden. Dann ist es sinnvoll fuer diese Anwendung den FIFO zu disablen (D_COM+2). Wenn das FIFO disabled ist, musst du aber vor jedem Schreiben ins Senderegister mal nachgucken, ob das ueberhaupt schon frei ist, sonst wird das letzt Byte, dass da vorher reingeschrieben wurde, der Chance beraubt, ins finale Schieberegister zu gelangen und damit den Baustein via TxD Leitung verlassen zu koennen...
    Also: Vertiefe dich in's Datenblatt des 16550.

    Gruss
    WK
    Das ist aber zu viel zum Lesen und ich will, dass er einfach kompeliert!

  6. #6
    narf Avatar von Pinky
    Registriert seit
    Dec 2003
    Ort
    München
    Beiträge
    105
    Code:
    #include <stdio.h>
    #include <string.h>
    #include <asm/io.h>
    
    #define D_COM1              0x3F8
    #define D_MODEM_CTRL(_port) (_port+4))
    /* define D_COM2              0x2F8 */
    
    int main( int argc, char *argv[] )
    {
       if ( ioperm( D_COM1, 6, 1) != 0 ) { /* get IO/perm */
          perror( "ERROR: can´t open COM device for read/write" );
          return(-1);
       }
            outb( 0x40, D_COM1 ); /*trobe 1*/
            
            outb( 0x4C, D_MODEM_CTRL(3F8)); /* data 1 , clock 1 strobe 1*/
            outb( 0x40, D_MODEM_CTRL(3F8)); /* clock 0 strobe1*/
           
            outb( 0x48, D_MODEM_CTRL(3F8)); /data 0 , clock 1 strobe1*/
            outb( 0x40, D_MODEM_CTRL(3F8)); /*clock0 strobe1*/
                        
            outb( 0x4C, D_MODEM_CTRL(3F8)); /*data 1 clock 1 strobe1*/
            outb( 0x40, D_MODEM_CTRL(3F8)); /* clock 0 strobe1*/
    
            outb( 0x00, D_MODEM_CTRL(3F8)); /*strobe 0 */
                                       
       return( 0 );
    }
    macht das nun Sinn ?

    nun zum Senderegisterprüfen :
    kann ich das so machen ?
    #define D_MODEM_STATUS(_port) (_port+6)
    inb(D_MODEM_STATUS(3F8));

  7. #7
    Benutzter Registrierer
    Registriert seit
    Feb 2004
    Beiträge
    2.281
    Moin,

    Zitat Zitat von Pinky
    macht das nun Sinn ?
    Nee, leider ueberhaupt nicht. Das will ja noch nichtmal kompilieren...
    Wie waers n mit sowas:
    Code:
    #define D_COM1              0x3F8
    #define RBRTHR   (D_COM1+0x0)
    #define IER        (D_COM1+0x1)
    #define IIR_FCR (D_COM1+0x2)
    #define LCR (D_COM1+0x3)
    ....
    #define LSR (D_COM1+0x5)
    ...
    #define BLUBB_REG (D_COM1 + N)
    Zitat Zitat von Pinky
    nun zum Senderegisterprüfen :
    kann ich das so machen ?
    #define D_MODEM_STATUS(_port) (_port+6)
    inb(D_MODEM_STATUS(3F8));
    Mach' sowas in der Art:
    Code:
    if (inb(LSR) & 0x20) { blupp(); }
    oder eben zum warten (Achtung: unclevere programmiermethode, aber fuer den Anfang halt):
    Code:
    while (inb(LSR) & 0x20);
    Aber nagel mich jetzt nicht drauf fest, ich weiss nicht auswendig, welches der Bits in welchem Register fuer was gut sind, und ob's active high oder low ist. -> Wiegesagt: Datenblatt lesen; irgendwo muessten da alle Register mit allen Bits verzeichnet sein, sind ja afaik bloss hoechstens 8 Byte Addressspace, die der 16550 braucht.

    Gruss
    WK
    Das ist aber zu viel zum Lesen und ich will, dass er einfach kompeliert!

  8. #8
    narf Avatar von Pinky
    Registriert seit
    Dec 2003
    Ort
    München
    Beiträge
    105
    du meinst diese Tabelle ?



    Wozu dient Scratch ?

    Wozu dient das Blubb Register
    Geändert von Pinky (28.08.05 um 14:02 Uhr)

  9. #9
    Benutzter Registrierer
    Registriert seit
    Feb 2004
    Beiträge
    2.281
    Moin,

    Zitat Zitat von Pinky
    du meinst diese Tabelle ?
    Wozu dient Scratch ?
    Wozu dient das Blubb Register
    Ja, fast - jetzt hab' ich mal nach 16550 gegoogled und der erste Treffer ist:
    http://byterunner.com/16550.html
    Genau so ne Tabelle habbich gemeint...Danach kommt anscheinend auch noch erklaerendes Gesabbel.
    Der dritte Treffer ist dann ein "richtiges" Datenblatt www.national.com/ds/PC/PC16550D.pdf
    Dort ist dann die erwaehnte Tabelle auf Seite 14. Auf Seite 19 oben links steht dann auch wasses mit dem Scratch-Register aufsich hat. Das Blubb-Register ist ein undokumentiertes Geheimfeature; das befindet sich auch nur in jedem 7. Ei, aeh UART

    Gruss
    WK
    Das ist aber zu viel zum Lesen und ich will, dass er einfach kompeliert!

  10. #10
    narf Avatar von Pinky
    Registriert seit
    Dec 2003
    Ort
    München
    Beiträge
    105
    neuer Versuch:

    Code:
    #include <asm/io.h>
    
    #define D_COM1           0x3F8
    #define RBRTHR          (D_COM1+0x0)
    #define IER             (D_COM1+0x1)
    #define IIR_FCR         (D_COM1+0x2)
    #define LCR             (D_COM1+0x3)
    #define MCR             (D_COM1+0x4)
    #define LSR             (D_COM1+0x5)
    #define MSR             (D_COM1+0x6)
    #define SCRATCH         (D_COM1+0x7)
    
    #define DATA_REG (D_COM1 + N)
    
    int main( int argc, char *argv[] )
    {
            if ( ioperm( D_COM1, 6, 1) != 0 ) { /* get IO/perm */
                    perror( "ERROR: can´t open COM device for read/write" );
                    return(-1);
            }
            outb( 0x02 ,IIR_FCR); /*disable FIFO*/
            outb( 0x03 ,LCR); /* set Word lenght 8*/
            outb( 0xff ,SCRATCH); /* 255 Scratch*/
            if (inb(LSR) & 0x20) {
                    printf("transmitter ready");
                    outb( 0x40 , MCR); /*strobe 1 on MCR*/
    
                    outb( 0x04 , DATA_REG); /*Data 1 on Com 1*/
                    outb( 0x48 , MCR); /*strobe 1 clock 1 on MCR*/
                    outb( 0x40 , MCR); /* strobe 1 clock 0 on MCR*/
    
                    outb( 0x04 , DATA_REG); /*Data 1 on Com 1*/
                    outb( 0x48 , MCR); /*strobe 1 clock 1 on MCR*/
                    outb( 0x40 , MCR); /* strobe 1 clock 0 on MCR*/
    
                    outb( 0x00 , MCR); /* strobe 0 on MCR*/
    
            }
            return( 0 );
    }

  11. #11
    Benutzter Registrierer
    Registriert seit
    Feb 2004
    Beiträge
    2.281
    Moin,

    Also, was mir und meinem gcc zuerst auffaellt:
    Code:
    bla.c:28: error: `N' undeclared (first use in this function)
    Dieses olle Register gibts nicht...braucht auch keiner.
    Dann brauchste das scratchpad nicht zu beschreiben und die wordlength ist eigentlich auch wurscht. Hab' mir nochmal deine Schaltung angeguckt, da haengt TxD ja am Data Eingang des Schieberegisters. Du benutzt TxD also nicht, wie eigentlich von den Erfindern des 16550 vorgesehen, sondern mehr nur so als simplen Ausgang. Das geht mit Hilfe von Bit6 im LCR. Damit kannst du TxD, was im Normalfall (wenn du nichts ins Senderegister schreibst) logisch 1 also -12V ist, auf logisch 0 - sprich +12V setzen. In RS-232-sprech heisst das "Break Condition". Das hat den Vorteil, dass dir der Zustand des Senderegisters voellig wurst sein kann, weil du eh' nie was ueber das senderegister sendest.

    Also, wuerd' ich sagen, mach dir mal n paar Makros in der Art:
    Code:
    #define TXD_HI outb (inb(LCR) | 0x40 , LCR)
    #define TXD_LO outb (inb(LCR) & ~0x40 , LCR)
    analog dazu das selbe Spiel mit RTS und DTR. Dann haste 6 verschiedene Makros, mit denen du dann an deinen 3 Ausgangsbits der seriellen Schnittstelle wackeln kannst.
    Die Makros kannste dann schonmal ueberpruefen, indem du eine LED + Vorwiderstand + eine normale Diode in Reihe zwischen die entsprechende Serielle Leitung und GND legst (dabei ruhig die ganze Schieberegisterschaltung erstmal weglassen).
    Das ganze in einer Simpel-1bit-Version und einer SW, die nicht ganz so lowlevel-registermaessig ist, wie sie bei dir dann sein muss, habbich hier beschrieben:
    http://www.linuxforen.de/forums/showthread.php?t=193255
    Damit kannst du zumindest mal die einzelnen Bits, die aus deiner Seriellen kommen sollen, testen.

    Wenn das dann funktioniert, d.h. wenn du definiert deine 3 Leitungen auf Hi und Lo setzen kannst, wie du es willst - dann kannste deine Schieberegisterschaltung wieder dranhaengen, und dir mal (mittels kariertem Papier + Stift + Datenblatt des 4094) ueberlegen, wie die 3 Signale im zeitlichen Ablauf aussehen muessen, damit du irgendwelche Werte in dein Schieberegister reinkriegst - du musst ja insgesamt 16 Taktzyklen erzeugen und dabei immer die richtigen Datenbits in die Schieberegister reinschieben und wenn der ganze Zauber dann drinnen ist, das dann in den Ausgangslatches einspeichern, damit du dann irgendwann die naechsten 16 bit nachschieben kannst.

    Gruss
    WK
    Das ist aber zu viel zum Lesen und ich will, dass er einfach kompeliert!

  12. #12
    narf Avatar von Pinky
    Registriert seit
    Dec 2003
    Ort
    München
    Beiträge
    105
    Hallo, ich messe gerade die Spannungen an den Ports. Dazu habe ich eine kleine Testsoftware geschrieben welche , TXD im Sekundentakt auf HI und LO W setzt. Leider ist die Spannung auf PIN 3 (TXD) immer auf ca. 11V +

    hier die der Code:

    Code:
    #include <sys/ioctl.h>
    #include <asm/io.h>
    
    #define D_COM1           0x3F8
    
    #define RBRTHR          (D_COM1+0x0)
    #define IER             (D_COM1+0x1)
    #define IIR_FCR         (D_COM1+0x2)
    #define LCR             (D_COM1+0x3)
    #define MCR             (D_COM1+0x4)
    #define LSR             (D_COM1+0x5)
    #define MSR             (D_COM1+0x6)
    #define SCRATCH         (D_COM1+0x7)
    
    #define TXD_HI outb (inb(LCR) | 0x40 , LCR)
    #define TXD_LO outb (inb(LCR) & ~0x40 , LCR)
    
    int main( int argc, char *argv[] )
    {
            if ( ioperm( D_COM1, 6, 1) != 0 ) { /* get IO/perm */
                    perror( "ERROR: can´t open COM device for read/write" );
                    return(-1);
            }
    
            while(1) {
                    TXD_HI;
                    sleep(1);
                    TXD_LO;
    
            }
            
            return( 0 );
    }

  13. #13
    Benutzter Registrierer
    Registriert seit
    Feb 2004
    Beiträge
    2.281
    Moin,

    Dann bau' halt mal noch n sleep(1) nach dem TXD_LO ein

    Gruss
    WK
    Das ist aber zu viel zum Lesen und ich will, dass er einfach kompeliert!

  14. #14
    narf Avatar von Pinky
    Registriert seit
    Dec 2003
    Ort
    München
    Beiträge
    105
    wie setze ich RTS und DTR im ModemKontrollRegister auf LO und Hi ?

    mit outb( 0x40 , MCR); funktioniert es nicht

  15. #15
    Benutzter Registrierer
    Registriert seit
    Feb 2004
    Beiträge
    2.281
    Moin,

    Zitat Zitat von Pinky
    wie setze ich RTS und DTR im ModemKontrollRegister auf LO und Hi ?

    mit outb( 0x40 , MCR); funktioniert es nicht
    Wieso sollte es auch? RTS und DTR liegen lt. Datenblatt auf den beiden LSBs in diesem Register...

    Gruss
    WK
    Das ist aber zu viel zum Lesen und ich will, dass er einfach kompeliert!

Ähnliche Themen

  1. dhcpd lässt sich nicht starten!
    Von BlackWizard im Forum Linux als Server
    Antworten: 16
    Letzter Beitrag: 08.01.05, 13:10
  2. Einführung in die "Open Source Philosophie"
    Von CrazieJ im Forum Meldungen und Mitglieder
    Antworten: 0
    Letzter Beitrag: 14.12.04, 00:59
  3. Referat über freie Software
    Von Nicolas im Forum Meldungen und Mitglieder
    Antworten: 18
    Letzter Beitrag: 01.03.04, 16:17
  4. Installation von Software aus Quellarchiven
    Von Ulli Ivens im Forum Hier Suchen und Finden, Links, Tutorials
    Antworten: 2
    Letzter Beitrag: 31.05.03, 12:49
  5. freie Software (!)= kostenlose Software
    Von cybercrow im Forum Meldungen und Mitglieder
    Antworten: 13
    Letzter Beitrag: 07.06.02, 18:27

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •