-
April 15th, 2004, 07:56 AM
#1
Controlling DTR line of serial port
Hi,
I have connected a led to the DTR line of the serial port just for testing purposes.
Turning the led on/off works just fine with the EscapeCommFunction() function which sets or clears the DTR line.
However, there is a problem. As soon as the serial port is opened with CreateFile(), there is a short pulse on the DTR line which causes the led to blink very shortly. Does someone knows how to prevent this startup pulse to occur?
Thanks in advance.
Code:
m_hPort = CreateFile(
portName, // Pointer to the name of the port
GENERIC_READ | GENERIC_WRITE, // Access (read/write) mode
0, // 0, serial ports can not be shared
NULL, // Pointer to the security attribute
OPEN_EXISTING, // How to open the serial port
0, // Port attributes
NULL); // Handle to port with attribute to copy
// If it fails to open the port, return false.
if (m_hPort == INVALID_HANDLE_VALUE)
return false;
return true;
Time is fun when you're having flies
-
April 15th, 2004, 10:05 AM
#2
Hey, great question.
I've got a very similar problem on a embeddded device under WinCE (where the DTR/DSR lines are missued as additional control lines for a RS485-communication ...)
If you find a solution please let me know here in the thread ...
-
April 16th, 2004, 01:54 AM
#3
It seems that the DTR line output is standard set (+10V) when the port is opened. When the DTR line is cleared, a voltage of
-10V is measured. This means current flows from GND to DTR.
When DTR is positive:
DTR o-------|>|-------o GND
When DTR is negative:
DTR o-------|<|-------o GND
So, now i connect the LED with its anode to GND and kathode to DTR, which ensures that the LED stays off when opening the port.
An other possibility is to invert the DTR signal.
Last edited by hmc; April 16th, 2004 at 02:00 AM.
Time is fun when you're having flies
-
April 16th, 2004, 06:48 AM
#4
What is the setting of the fDtrControl member of the DCB struct?
If you set it to DTR_CONTROL_ENABLE it will enable the DTR line when the port is opened and leave it on.
For the DTR line, enabled or "set" means a logic 0. In RS-232 voltage levels a logic 0 is between +3 and +15 volts DC. The DTR line is "asserted" (on, set, enabled....etc) when it is "low" or logic 0 or +3 to +15 volts DC in RS-232 which is 0.0 to 0.7 volts in TTL logic levels.
Does that make sense?
Originally posted by hmc
It seems that the DTR line output is standard set (+10V) when the port is opened. When the DTR line is cleared, a voltage of
-10V is measured. This means current flows from GND to DTR.
From that behavior I can be reasonably certain that you are not setting the fDtrControl member of the DCB struct to DTR_CONTROL_ENABLE before opening the port. On my system the DTR signal is cleared (-3 to -15 volts DC) when the port is closed regargless of the setting of fDtrControl. If I set the fDtrControl to DTR_CONTROL_ENABLE and then open the serial port the DTR signal goes to (+3 to +15 volts DC) when the port is opened and stays there. This is the "set" state for the DTR line.
So I think you just need to set the fDtrControl member of the DCB struct to DTR_CONTROL_ENABLE before opening the serial port and the DTR line should go to the set state and stay in the set state while the serial port remains open.
RS-232D is a little confusing, just remember that a "logic 1" is between -3 and -15 volts DC and a logic 0 is between +3 and +15 volts DC. To be compatible with TTL you need a level converter like a MAX-232. This chip will invert the signal and brings the logic levels to TTL levels (0 to +5 volts).
The data signals (TX and RX) assert high (logic 1) and the flow control lines (DTR,RTS,DSR and CTS) assert low (logic 0).
TDM
Last edited by TDM; April 16th, 2004 at 06:58 AM.
-
April 16th, 2004, 06:59 AM
#5
From that behavior I can be reasonably certain that you are not setting the fDtrControl member of the DCB struct to DTR_CONTROL_ENABLE before opening the port. On my system the DTR signal is cleared (-3 to -15 volts DC) when the port is closed regargless of the setting of fDtrControl. If I set the fDtrControl to DTR_CONTROL_ENABLE and then open the serial port the DTR signal goes to (+3 to +15 volts DC) when the port is opened and stays there. This is the "set" state for the DTR line.
How can i set the fDtrControl member in the DCB struct without opening the port. I used SetCommState(), but this function requires a handle to the port which can only be passed after opening the port. Please correct me if i am wrong.
Time is fun when you're having flies
-
April 16th, 2004, 07:13 AM
#6
Before calling SetCommState, modify the fDtrControl of the DCB struct. You can set the members of the DCB struct to whatever values you want before opening the serial port. One example might be:
Code:
FillMemory(m_dcb, sizeof(DCB), 0);
m_dcb->DCBlength = sizeof(DCB);
m_dcb->fAbortOnError=TRUE;
m_dcb->fBinary=TRUE;
m_dcb->EvtChar='\xD';
m_dcb->EofChar='\x1A';
m_dcb->ErrorChar=(BYTE)'¿';
m_dcb->fErrorChar=1;
m_dcb->Parity=NOPARITY;
m_dcb->BaudRate=CBR_9600;
m_dcb->ByteSize=8;
m_dcb->StopBits=ONESTOPBIT;
m_dcb->fNull=0;
m_dcb->fParity=0;
m_dcb->XonChar='\x11';
m_dcb->XoffChar='\x13';
m_dcb->fDsrSensitivity=0;
m_dcb->fOutxCtsFlow=0;
m_dcb->fOutxDsrFlow=0;
m_dcb->fDtrControl=DTR_CONTROL_ENABLE;
m_dcb->fRtsControl=RTS_CONTROL_DISABLE;
m_dcb->fTXContinueOnXoff=0;
m_dcb->fOutX=0;
m_dcb->fInX=0;
m_dcb->XonLim=512;
m_dcb->XoffLim=512;
h_Port = CreateFile(m_PortName,GENERIC_READ | GENERIC_WRITE,0,0,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,0);
SetupComm(h_Port,4096,4096);
if (!SetCommState(h_Port,m_dcb))
{
MessageBox("Open serial port failed");
return 0;
}
TDM
-
April 16th, 2004, 07:33 AM
#7
But modifying the DCB struct does not have any effect until you call SetCommState(), which is after you opened the port.
This means the DTR line has a predefined state which is caused by the hardware of the port.
Time is fun when you're having flies
-
April 16th, 2004, 07:35 AM
#8
The previous post is a little bit of overkill. You could just use:
Code:
h_Port = CreateFile(m_PortName,GENERIC_READ | GENERIC_WRITE,0,0,OPEN_EXISTING,0,0);
GetCommState(h_Port,&m_dcb);
m_dcb->fDtrControl=DTR_CONTROL_ENABLE;
SetupComm(h_Port,4096,4096);
if (!SetCommState(h_Port,m_dcb))
{
MessageBox("Open serial port failed");
return 0;
}
I actually use property sheet/pages to allow the user to modify all member of the DCB. I just close the port when the property sheet is opened and then re-open the serial port with the new DCB when the property sheet is closed.
TDM
-
April 16th, 2004, 07:46 AM
#9
Originally posted by hcm
But modifying the DCB struct does not have any effect until you call SetCommState(), which is after you opened the port.
Yes the serial port is opened at create file but the parameters for the hardware are applied when you call SetCommState.
TDM
Last edited by TDM; April 16th, 2004 at 09:34 AM.
-
April 26th, 2004, 04:26 PM
#10
Sorry, that doesn't hit the point.
A call to CreateFile opens the COM port. At that time the DTR signal will be DISABLED for a short time (we measured 100ms on a strongarm system / WinCE 4.1 ).
If you don't use the serial port the "normal way" that could be a problem. (we "missuse" the DTR for a control line. in our case that "little switch time" could lead to serious damage of our hardware (some parts of the system are powered up before the control hardware is online).
The point that it i exactly 100ms looks to me that this is a behaviour by design. I took a look into the COM driver routines in the BSP and the MS common soruces but couldn't locate the source of that 100ms switch there. But I'm not very used to that kind of code...
-
April 26th, 2004, 05:25 PM
#11
I would STRONGLY consider using a digital I/O board rather than mis-using the Serial port. The only other choice for 100% of what you want is to totally bypass the windows code and write your own driver.
I have developed a number of commercial drivers for exactly this purpose. Unfortunately they are not trival, or open source...
TheCPUWizard is a registered trademark, all rights reserved. (If this post was helpful, please RATE it!)
2008, 2009,2010
In theory, there is no difference between theory and practice; in practice there is.
* Join the fight, refuse to respond to posts that contain code outside of [code] ... [/code] tags. See here for instructions
* How NOT to post a question here
* Of course you read this carefully before you posted
* Need homework help? Read this first
-
April 26th, 2004, 06:06 PM
#12
Yes, Since my original responses in this thread I have investigated different serial ports and different operating systems. The behavior of the DTR line differed with different UARTS and operating systems. The correct behavior would be for the DTR line to be cleared whenever the port is not open because the data terminal is not ready to receive data. It is completely understandable that there will be a short perfiod between the opening of the port and the setting of the DTR line. Perhaps I spoke too quickly in my previous posts before considering the nature of the problem.
That is a pretty ugly failure mode if your hardware gets smoked from such a short delay in the activation of the DTR line. Any method for sourcing the signal, DIO card or otherwise, would be subject to such a failure mode. Maybe consider a redesign of the hardware(if that is an option) where there is a delay or make the hardware remain in standby until the DTR signal is set.
TDM
Last edited by TDM; April 26th, 2004 at 08:36 PM.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|