将串口DB9中的RTS和CTS、DSR、DTR引脚用作一般的IO口来控制继电器/LED或者其他硬件
By
admin
at 2024-02-21 • 0人收藏 • 669人看过
以前用串口从来只接了235脚, 其他脚没去留意过.
这次有个特殊需求, 正常情况下需要一个外部IO口控制一个设备的开关断 , 如果是之前我会弄个单片机或者从其他地方引根线过来用.
这次搜索发现串口其他脚太浪费了, 搜索才知道还可以当io用啊

具体一点就是:
Rts 和 Dtr 引脚可以用作 输出 功能
Dsr 和 Cts 引脚可以用作 输入 功能
在c#中代码控制代码如下:
serialPort1.RtsEnable = true;//将 RTS 输出高电平 serialPort1.DtrEnable = true;//将 DTR 输出高电平 var dSr_Staus = serialPort1.DsrHolding;//获取 DSR 输入高低电平状态 var cTs_Staus = serialPort1.CtsHolding;//获取 CTS 输入高低电平状态
我这里做了个简单的控制led灯的示意图.

控制程序如下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
serialPort1.PortName = textBox1.Text;
serialPort1.BaudRate = 115200;
serialPort1.Open();
}
private void button2_Click(object sender, EventArgs e)
{
serialPort1.RtsEnable = true;
}
private void button3_Click(object sender, EventArgs e)
{
serialPort1.RtsEnable = false;
}
}
}RtsEnable就是控制IO的高低电平的, 电压是看串口的芯片的, ft232好像是±7V , PL2303是±9V输出.
视频如下:
另外, 这些引脚状态也是可以监听的, 有相应的回调事件,
可以参考文章: C# SerialPinChange A ring indicator was detected. (demo2s.com)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.IO.Ports;
using System.IO.Pipes;
namespace SerialPortPushButton
{
class Program
{
static SerialPort p; static StreamWriter sw; static string version; static bool prevState; static void Main(string[] args)
{
version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
NamedPipeClientStream pipeClient = new NamedPipeClientStream(".", "TIMclk", PipeDirection.Out);
Console.Write("Attempting to connect to pipe... ");
pipeClient.Connect();
Console.WriteLine("Connected to pipe.");
Console.WriteLine("There are currently {0} pipe server instances open.", pipeClient.NumberOfServerInstances); if (pipeClient.IsConnected == false)
{
Console.WriteLine("Pipe is not connected. Aborting. Please start Server first."); return;
}
sw = new StreamWriter(pipeClient);
sw.AutoFlush = true; try
{
string sendtext = "SPPB-HELO:Serial Port Push Button Client version " + version;
Console.WriteLine(sendtext);
sw.WriteLine(sendtext);
}
catch (IOException e)
{
Console.WriteLine("ERROR: {0}", e.Message);
}
p = new SerialPort("COM10", 9600, Parity.None, 8, StopBits.One);
p.RtsEnable = true;
p.PinChanged += new SerialPinChangedEventHandler(myPinChanged); try
{
p.Open();
}
catch (Exception e)
{
Console.WriteLine("Cannot open Port. Try again. (Press Enter to quit) ...");
Console.ReadLine(); return;
}
Console.WriteLine("Connected to COM1.");
Console.ReadLine();
}
static void myPinChanged(object sender, SerialPinChangedEventArgs e)
{
TimeSpan tsNow = DateTime.Now.TimeOfDay; string info = string.Empty; switch (e.EventType)
{
case SerialPinChange.Break:
info = string.Format("Break detected. BreakState = {0}", p.BreakState); break;
case SerialPinChange.CDChanged:
info = string.Format("Carrier Detect (CD) signal changed state. CD State = {0}", p.CDHolding); break;
case SerialPinChange.CtsChanged:
info = string.Format("Clear to Send (CTS) signal changed state. CTS State = {0}", p.CtsHolding); break;
case SerialPinChange.DsrChanged:
string statstr = p.DsrHolding == true ? "ON" : "OFF"; string writestr = "SPPB-EV:001 " + statstr + " " + tsNow.ToString(@"hh\:mm\:ss\,fff"); try
{
sw.WriteLine(writestr);
Console.WriteLine(writestr);
}
catch (Exception ex)
{
Console.WriteLine("ERROR ON: " + writestr);
Console.WriteLine(ex.ToString());
}
break;
case SerialPinChange.Ring:
info = "Ring detected";
break;
default: break;
}
Console.WriteLine(info); bool thisState = p.CDHolding; if (thisState == true && prevState == false)
{
}
}
}
}
2 个回复 | 最后更新于 2024-03-01
登录后方可回帖



