将串口DB9中的RTS和CTS、DSR、DTR引脚用作一般的IO口来控制继电器/LED或者其他硬件
By
admin
at 2024-02-21 • 0人收藏 • 414人看过
以前用串口从来只接了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
登录后方可回帖