Serieller COM-Port mit 76800 Baud

Hardware- und Elektronikbasteleien, Ansteuerung von Schnittstellen und Peripherie.
Fragen zu "Consumer"-Problemen kommen in Offtopic.
Benutzeravatar
Helle
Beiträge: 566
Registriert: 11.11.2004 16:13
Wohnort: Magdeburg

Beitrag von Helle »

Mein Asus-Motherboard mit dem Super-I/O-Chip Winbond W83627DHG könnte die 76800 Baud, PB kann damit Com1 aber trotzdem nicht bereitstellen. Mit API müsste es mal ausprobiert werden.
Die max.Baudrate lässt sich übrigens so ermitteln:

Code: Alles auswählen

ComP.COMMPROP
RS232 = CreateFile_("Com1", #GENERIC_READ | #GENERIC_WRITE, 0, #Null, #OPEN_EXISTING, #Null, #Null)
GetCommState_(RS232, @ComP)
Debug ComP\dwMaxBaud
CloseHandle_(RS232)
Gruß
Helle
Langstein
Beiträge: 13
Registriert: 25.09.2008 18:29

Beitrag von Langstein »

Ich habe es mit 38400 versucht. Da gehts hervorragend. Mit 76800 geht es nicht. Meldung: "Can't open the serial port: "

Da in der Hilfe 76800 nicht aufgefürt ist habe ich das so interpretiert, das dies von der Lib nicht unterstützt ist. Da ich auf dem Computer eine Software verwende, die mit 76800 arbeitet habe ich das auf die Lib geschoben.

Ist der Rückschluß vielleicht grundsätzlich falsch?
Benutzeravatar
Falko
Admin
Beiträge: 3531
Registriert: 29.08.2004 11:27
Computerausstattung: PC: MSI-Z590-GC; 32GB-DDR4, ICore9; 2TB M2 + 2x3TB-SATA2 HDD; Intel ICore9 @ 3600MHZ (Win11 Pro. 64-Bit),
Acer Aspire E15 (Win11 Home X64). Purebasic LTS 6.0
Kontaktdaten:

Beitrag von Falko »

Helle hat geschrieben:Mein Asus-Motherboard mit dem Super-I/O-Chip Winbond W83627DHG könnte die 76800 Baud, PB kann damit Com1 aber trotzdem nicht bereitstellen. Mit API müsste es mal ausprobiert werden.
Die max.Baudrate lässt sich übrigens so ermitteln:

Code: Alles auswählen

ComP.COMMPROP
RS232 = CreateFile_("Com1", #GENERIC_READ | #GENERIC_WRITE, 0, #Null, #OPEN_EXISTING, #Null, #Null)
GetCommState_(RS232, @ComP)
Debug ComP\dwMaxBaud
CloseHandle_(RS232)
Gruß
Helle
Interessant:
1249536
Hier noch ein Beispiel mit Werten aus dem Gerätemanager und 67800 baud. Bei kleinen Baudwerten kann man trotzdem verschiedene andere Werte eintragen, aber über 9600baud, geht das nicht mit Zwischenwerten. Vielleicht ist die Lib abhängig von den Werten die im Gerätemanager ermittelt werden.

Code: Alles auswählen

;
; ------------------------------------------------------------
;
;   PureBasic - SerialPort example file
;
;    (c) Fantaisie Software
;
; ------------------------------------------------------------
;


Port$ = "COM1"
;Erster Baudwert lt. Gerätemanager = 57600
If OpenSerialPort(0, Port$,57600, #PB_SerialPort_NoParity, 8, 1, #PB_SerialPort_NoHandshake, 1024, 1024)

	MessageRequester("Information", "SerialPort opened with 57600 baud")
  CloseSerialPort(0)
Else
	MessageRequester("Error", "Can't open the serial port: "+Port$)
EndIf



;Eigener Baudwert frei eingestellt und nicht im Gerätemanager vorhanden = 76800
If OpenSerialPort(0, Port$, 76800, #PB_SerialPort_NoParity, 8, 1, #PB_SerialPort_NoHandshake, 1024, 1024)

	MessageRequester("Information", "SerialPort opened with 76800 baud")

  CloseSerialPort(0)
Else
	MessageRequester("Error", "Can't open the serial port: "+Port$)
EndIf



;letzter Baudwert lt. Gerätemanager = 115200
If OpenSerialPort(0, Port$, 115200, #PB_SerialPort_NoParity, 8, 1, #PB_SerialPort_NoHandshake, 1024, 1024)

	MessageRequester("Information", "SerialPort opened with 115200 baud")
  CloseSerialPort(0)
Else
	MessageRequester("Error", "Can't open the serial port: "+Port$)
EndIf
Gruß
Falko
Bild
Win10 Pro 64-Bit, PB_5.4,GFA-WinDOS, Powerbasic9.05-Windows, NSBasic/CE, NSBasic/Desktop, NSBasic4APP, EmergenceBasic
smiley46
Beiträge: 7
Registriert: 14.09.2008 22:01
Wohnort: Geiziger Süddeutscher

Beitrag von smiley46 »

Hallo

Das ist ein code, welchen ich hier irgendwo gefunden habe. Ich hab lediglich kleine Änderungen gemacht, damit es mit der Version 4.20 funktioniert.
Wenn sich die Schnittstelle mit der entsprechenden Baudrate starten lässt, muss im Debug Fenster "SetCommState=1" erscheinen.
Bei mir lässt sich COM1 nicht mit 76800 starten, jedoch der virtuelle COM Port des FT232 funktioniert.

Code: Alles auswählen

; German forum: 
; http://www.purebasic.fr/german/archive/viewtopic.php?t=3435
; ComPort (RS232) example , Write and Read-data, timer driven
; good for a small terminal or a modem-configurator
; Windows only, done on january, 14th. 2004
; Copyright 2004 Siegfried Rings (CodeGuru)
;
OnErrorGoto(?Errorhandling) ;Enable Errorhandling (enable Linenumbering!)

;User Structure for all the ComPort-Stuff
Structure structComport
 Port.l
 Inbuffersize.l
 OutBuffersize.l
 Handle.l
 ct.COMMTIMEOUTS
 dcb.DCB
 Receivebuffer.l
 ReceivebufferLength.l
EndStructure

Enumeration
 #Gadget_TextSend
 #Gadget_TextReceive
 #Gadget_ButtonSend
 #Gadget_ButtonReceive
EndEnumeration

#Win=1
;#ReceiveSendbuffer=1
#MaxReceiveBuffer=1024


Procedure.l SR_OpenComPort(*RS232.structComport)
 *RS232\Handle =0
 Device.s="COM"+Str(*RS232\Port)+":"
 Result = CreateFile_(@Device, $C0000000, 0, 0, 3, 0, 0); create and open a existing device/file ;)
 If Result = #INVALID_HANDLE_VALUE
  MessageRequester("info", "Com Port " + Str(*RS232\Port) + " not available. Use Serial settings (on the main menu) To setup your ports.", 48)
  ProcedureReturn 0
 EndIf
 If Result
  *RS232\Handle=Result
  mydcb.DCB
  Result = GetCommState_(*RS232\Handle, @mydcb) ;First retrieve the Settings from ComPort
  If Result

   ;Set Baudrate etc.
   mydcb\Baudrate=*RS232\dcb\Baudrate ;Change the Settings to our needs
   mydcb\Bytesize=*RS232\dcb\Bytesize
   mydcb\Parity=*RS232\dcb\Parity
   mydcb\StopBits=*RS232\dcb\StopBits
   Result=SetCommState_(*RS232\Handle, @mydcb) ;and write them back to Comport
   Debug "SetCommState="+Str(Result)   
   Result=SetCommTimeouts_(*RS232\Handle,*RS232\ct) ;set the Timeouts set longer for problems :)

   ;Set In/Outbuffers
   If result
    Result=SetupComm_(*RS232\Handle,*RS232\Inbuffersize,*RS232\Outbuffersize)
   EndIf
  EndIf
 Else
  CloseHandle_(Result)
 EndIf
 ProcedureReturn *RS232\Handle
EndProcedure

Procedure SR_CloseComPort(*RS232.structComport)
 If *RS232\Handle
  CloseHandle_(*RS232\Handle)
  *RS232\Handle=0
 EndIf
EndProcedure

Procedure SR_WriteComPort(*RS232.structComport,Rawdata.l,RawDataLength.l)
 If *RS232\Handle=0
  ProcedureReturn
 EndIf
 Written.l
 Result=WriteFile_(*RS232\Handle,RawData,RawDataLength,@Written,0)  ;WriteData now to ComPort
 FlushFileBuffers_(*RS232\Handle);Release buffer directly
 ProcedureReturn written
EndProcedure

Procedure SR_ReadComPort(*RS232.structComport)
 If *RS232\Handle=0
  ProcedureReturn
 EndIf
 Repeat
  Result=ReadFile_(*RS232\Handle , *RS232\Receivebuffer+Offset, 256, @RetBytes, 0) ;Read content
  If RetBytes>0
   Offset=Offset+RetBytes
  EndIf
 Until RetBytes=0 Or Offset>#MaxReceiveBuffer
 *RS232\ReceivebufferLength=Offset
; FlushFileBuffers_(*RS232\Handle);Release buffer directly
 ProcedureReturn Offset
EndProcedure


;- Begin of MainCode

 MyRS232.structComport ;set my own Structure For all the ComPorthandling
 MyRS232\Port=1
 MyRS232\dcb\Baudrate=57600;76800
 MyRS232\dcb\Bytesize=8
 MyRS232\dcb\StopBits=#ONESTOPBIT
 MyRS232\dcb\Parity=#NOPARITY
 
 MyRS232\Inbuffersize=256 ;size is enough
 MyRS232\OutBuffersize=256
 
 MyRS232\ct\ReadIntervalTimeOut =200; in milliseconds '#MAXDWORD
 MyRS232\ct\ReadTotalTimeoutMultiplier = 1
 MyRS232\ct\ReadTotalTimeoutConstant = 1
 MyRS232\ct\WriteTotalTimeoutConstant = 10
 MyRS232\ct\WriteTotalTimeoutMultiplier = 1
   
 MyRS232\Receivebuffer = AllocateMemory(#MaxReceiveBuffer) ;Reserve mem For it
 MyRS232\ReceivebufferLength=0


;- Open Window
hwnd=OpenWindow(#Win, 1, 300, 400, 400, "PureBasic Window", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)
If hwnd
 If CreateGadgetList(WindowID(#Win))

  ;- CreateGadgets
  StringGadget(#Gadget_TextSend, 5, 5, 200, 20, "AT")
  StringGadget(#Gadget_TextReceive, 5, 55, 390, 340, "")
  ButtonGadget(#Gadget_ButtonSend,210,5,90,20,"Send")
  ButtonGadget(#Gadget_ButtonReceive,305,5,90,20,"Receive")

  ;- Setup Timer
  Result=SetTimer_(hwnd,1,100,0) ;Setup our timer For receiveing Data every 100 msecs

  ;- Setup and Open Comport
  Result=SR_OpenComPort(MyRS232)
 
 
  ;- Eventloop
  Repeat
   EventID.l = WaitWindowEvent()
 
   ;- Timer-Routine to read Data from ComPort
   If EventID =#WM_TIMER
     If MyRS232\Handle<>0
       Readed=SR_ReadComPort(MyRS232)
      If MyRS232\ReceiveBufferlength>0
        Buffer.s=Buffer.s+PeekS(MyRS232\ReceiveBuffer,MyRS232\ReceiveBufferlength)
        SetGadgetText(#Gadget_TextReceive,Buffer.s)
        MyRS232\ReceiveBufferlength=0
      EndIf
     EndIf
   EndIf
 
   If EventID =#PB_Event_Gadget
     GadgetNR = EventGadget()
     
     ;- Send Data to Comport
     If GadgetNR =#Gadget_ButtonSend
      SendText.s=GetGadgetText(#Gadget_TextSend) + Chr(13) ;add a CarriageReturn to send to modem
      ;Debug SendText
      Buffer.s=""
      SetGadgetText(#Gadget_TextReceive,Buffer.s);Reset inbuffer gadget
      Result=SR_WriteComPort(MyRS232,@SendText.s,Len(SendText.s)); Check Modem
      Debug "Characters sended:"+Str(Result)
     EndIf

     ;- Read Data from Comport
     If GadgetNR=#Gadget_ButtonReceive
      Readed=SR_ReadComPort(MyRS232) ; Read Incoming
      If Readed
       Debug "Characters readed="+Str(Readed)
       Buffer.s=Buffer.s+PeekS(MyRS232\ReceiveBuffer,MyRS232\ReceiveBufferlength)
       SetGadgetText(#Gadget_TextReceive,Buffer.s)
       MyRS232\ReceiveBufferlength=0 ;Shorten buffer now
      EndIf
     EndIf
   EndIf
   
  Until EventID = #PB_Event_CloseWindow
 EndIf
EndIf
SR_CloseComPort(MyRS232) ;Comport Close
End 

;- Error-handler
Errorhandling:
 MessageRequester("Error","in line "+Str(GetErrorLineNR() ),0)
End
smiley46
Beiträge: 7
Registriert: 14.09.2008 22:01
Wohnort: Geiziger Süddeutscher

Beitrag von smiley46 »

Hier nochmal reduziert aufs Minimum

Code: Alles auswählen

RS232 = CreateFile_("Com1", #GENERIC_READ | #GENERIC_WRITE, 0, #Null, #OPEN_EXISTING, #Null, #Null)

mydcb.DCB
Result = GetCommState_(RS232, @mydcb) ; first retrieve the settings from ComPort
Debug "GetCommState="+Str(Result)   

mydcb\Baudrate = 57600
Result = SetCommState_(RS232, @mydcb) ; and write them back to Comport
Debug "SetCommState="+Str(Result)   

CloseHandle_(RS232) 
Graffiti
Beiträge: 173
Registriert: 30.08.2004 08:34
Wohnort: Thailand

Beitrag von Graffiti »

Es gibt noch eine andere Lösung, da brauchst du aber einen Lötkolben
und eine Com Steckkarte.

die PCI-Karten haben alle einen Quarz drauf den musst du gegen einen austauschen der den Wert / 1,5 hat
z.B. 20 MHz sind drin dann brauchst du 13,33 MHz und stellst 115200 ein

oder du stellst 57600 ein dann musst du den Quarz x 1,3333 nehmen

du musst nur beachten das du nicht mehr als 2% Abweichung hast sonst gehts nicht.

das selbe verfahren benutze ich für Midianwendungen, die haben auch eine krumme Einstellung die keine Com-Karte kann.
Antworten