📄 seriallcd.cs
字号:
using System;
using System.IO;
using System.IO.Ports;
using System.Diagnostics;
using System.Threading;
using System.Collections.Generic;
namespace SerialTest
{
public enum LCDKey
{
None,
Up,
Down,
Left,
Right,
Enter,
Exit
}
public class SerialLCD
{
private const int READ_BUFFER_SIZE = 128;
private const int MAX_DATA_LENGTH = 16;
private const int MAX_RESPONSE_TIME = 250;
private const int LINE_LENGTH = 16;
private const int MAX_PACKET_LENGTH = MAX_DATA_LENGTH + 4;
private const byte NORMAL_RESPONSE = 0x40;
private const byte NORMAL_REPORT = 0x80;
private const byte ERROR_RESPONSE = 0xC0;
private const byte KEY_ACTIVITY_REPORT = 0x80;
private const byte FAN_SPEED_REPORT = 0x81;
private const byte TEMPATURE_SENSOR_REPORT = 0x82;
ushort CRC_SEED = 0xFFFF;
private byte[] packetRcvBuffer;
private byte[] packetXMitBuffer;
private bool _timedOut;
private Thread receiveThread;
private Thread eventThread;
private LCDPacket responsePacket;
private Queue<LCDPacket> reportQueue;
private Object responseSignal;
private Object reportSignal;
private LCDKey _key;
public enum CursorStyle { NoCusrsor = 0, BlinkingBlockCursor = 1, UnderscoreCursor = 2, BlinkingBlockUnderscoreCursor = 3 };
[FlagsAttribute]
public enum Fans { Fan1 = 1, Fan2 = 2, Fan3 = 4, Fan4 = 8 };
private byte fan1Power, fan2Power, fan3Power, fan4Power;
public delegate void KeyActivityEventHandler(Object sender, EventArgs e);
// comPort
private SerialPort com;
public SerialLCD()
{
// comPort
com = new SerialPort("COM1", 19200);
com.ReadTimeout = 3000;
com.WriteTimeout = 3000;
com.Open();
packetRcvBuffer = new byte[MAX_PACKET_LENGTH];
packetXMitBuffer = new byte[MAX_PACKET_LENGTH];
fan1Power = fan2Power = fan3Power = fan4Power = (byte)0;
reportQueue = new Queue<LCDPacket>();
responseSignal = new Object();
reportSignal = new Object();
eventThread = new Thread(new ThreadStart(ReportEventHandler));
eventThread.Start();
receiveThread = new Thread(new ThreadStart(Receive));
receiveThread.Start();
}
public bool TimedOut { get { return _timedOut; } set { _timedOut = value; } }
public byte[] Ping(byte[] data)
{
byte type = 0;
if (16 < data.Length)
{
throw new ArgumentException("data", "must have 16 items or less");
}
return SendReturnData(type, (byte)data.Length, data);
}
public byte[] GetHardwareFirmwareVersion()
{
byte type = 1;
return SendReturnData(type, 0, null);
}
public bool WriteUserFlashArea(byte[] data)
{
byte type = 2;
data = CreateByteArrayOfLength(data, 16);
return SendReturnBool(type, 16, data);
}
public byte[] ReadUserFlashArea()
{
byte type = 3;
return SendReturnData(type, 0, null);
}
public bool SaveState()
{
byte type = 4;
return SendReturnBool(type, 0, null);
}
public bool Clear()
{
byte type = 6;
return SendReturnBool(type, 0, null);
}
public bool WriteLine1(string line)
{
byte type = 7;
return WriteLine(type, line);
}
public bool WriteLine1(byte[] data)
{
byte type = 7;
data = CreateByteArrayOfLength(data, 16);
return SendReturnBool(type, 16, data);
}
public bool WriteLine2(string line)
{
byte type = 8;
return WriteLine(type, line);
}
public bool WriteLine2(byte[] data)
{
byte type = 8;
data = CreateByteArrayOfLength(data, 16);
return SendReturnBool(type, 16, data);
}
private bool WriteLine(byte type, string line)
{
line = CreateStringOfLength(line, LINE_LENGTH);
return SendReturnBool(type, 16, System.Text.Encoding.ASCII.GetBytes(line.ToCharArray()));
}
public bool SetCursorPosition(int column, int row)
{
byte type = 11;
byte[] data = new byte[2];
if (15 < column || 0 > column)
{
throw new ArgumentOutOfRangeException("column", "must be 0-15");
}
if (1 < column || 0 > column)
{
throw new ArgumentOutOfRangeException("row", "must be 0-1");
}
data[0] = (byte)column;
data[1] = (byte)row;
return SendReturnBool(type, 2, data);
}
private bool SetCursorStyle(CursorStyle cursorStyle)
{
byte type = 12;
byte[] data = new byte[1];
if (0 > (int)cursorStyle || 3 < (int)cursorStyle)
{
throw new ArgumentOutOfRangeException("cursorStyle", "must be a valid value in the enum");
}
data[0] = (byte)cursorStyle;
return SendReturnBool(type, 1, data);
}
//0-50(0=light 50= very dark)
public bool SetLCDContrast(int contrastValue)
{
byte type = 13;
byte[] data = new byte[1];
if (0 > contrastValue || 50 < contrastValue)
{
throw new ArgumentOutOfRangeException("contrastValue", "must be 0 -50");
}
data[0] = (byte)contrastValue;
return SendReturnBool(type, 1, data);
}
//0-100(0= 0ff 100=on)
public bool SetLCDBacklight(int backlightValue)
{
byte type = 14;
byte[] data = new byte[1];
if (0 > backlightValue || 100 < backlightValue)
{
throw new ArgumentOutOfRangeException("backlightValue", "must be 0 -50");
}
data[0] = (byte)backlightValue;
return SendReturnBool(type, 1, data);
}
public byte[] GetLastFanPulse()
{
byte type = 15;
return SendReturnData(type, 0, null);
}
public bool SetupFanReporting(Fans fans)
{
byte type = 16;
byte[] data = new byte[1];
if ((int)fans < (int)Fans.Fan1 || (int)(Fans.Fan1 | Fans.Fan2 | Fans.Fan3 | Fans.Fan4) < (int)fans)
{
throw new ArgumentOutOfRangeException("backlightValue", "must be 0 -50");
}
data[0] = (byte)fans;
return SendReturnBool(type, 1, data);
}
public bool SetFan1Power(int fan1)
{
return SetFanPower(fan1, fan2Power, fan3Power, fan4Power);
}
public bool SetFan2Power(int fan2)
{
return SetFanPower(fan1Power, fan2, fan3Power, fan4Power);
}
public bool SetFan3Power(int fan3)
{
return SetFanPower(fan1Power, fan2Power, fan3, fan4Power);
}
public bool SetFan4Power(int fan4)
{
return SetFanPower(fan1Power, fan2Power, fan3Power, fan4);
}
public bool SetFanPower(int fan1, int fan2, int fan3, int fan4)
{
byte type = 17;
byte[] data = new byte[4];
if (fan1 < 0 || 100 < fan1)
throw new ArgumentOutOfRangeException("fan1", "must be 0-100");
if (fan2 < 0 || 100 < fan2)
throw new ArgumentOutOfRangeException("fan2", "must be 0-100");
if (fan3 < 0 || 100 < fan3)
throw new ArgumentOutOfRangeException("fan3", "must be 0-100");
if (fan4 < 0 || 100 < fan4)
throw new ArgumentOutOfRangeException("fan4", "must be 0-100");
data[0] = fan1Power = (byte)fan1;
data[1] = fan2Power = (byte)fan2;
data[2] = fan3Power = (byte)fan3;
data[3] = fan4Power = (byte)fan4;
return SendReturnBool(type, 4, data);
}
private string CreateStringOfLength(string s, int length)
{
if (length < s.Length)
s = s.Substring(length);
else if (length > s.Length)
{
s = s + (new String(' ', length - s.Length));
}
return s;
}
private byte[] CreateByteArrayOfLength(byte[] bArray, int length)
{
if (length != bArray.Length)
{
int dataLength = bArray.Length > length ? length : bArray.Length;
byte[] newbArray = new byte[length];
Array.Copy(bArray, newbArray, dataLength);
bArray = newbArray;
}
return bArray;
}
private LCDPacket Send(byte type, byte dataLength, byte[] data)
{
ushort crc;
if ((null == data && dataLength != 0) || dataLength > data.Length)
throw new ArgumentException("data");
packetXMitBuffer[0] = type;
packetXMitBuffer[1] = dataLength;
if (0 != dataLength)
Array.Copy(data, 0, packetXMitBuffer, 2, dataLength);
crc = CRCGenerator.GenerateCRC(packetXMitBuffer, dataLength + 2, CRC_SEED);
packetXMitBuffer[2 + dataLength + 1] = (byte)(crc >> 8);
packetXMitBuffer[2 + dataLength] = (byte)crc;
lock (responseSignal)
{
responsePacket = null;
// comPort
com.Write(packetXMitBuffer, 0, dataLength + 4);
if (Monitor.Wait(responseSignal, MAX_RESPONSE_TIME))
{
return responsePacket;
}
}
return null;
}
private byte[] SendReturnData(byte type, byte dataLength, byte[] data)
{
LCDPacket packet = Send(type, dataLength, data);
if (null != packet)
{
return packet.Data;
}
else
{
return null;
}
}
private bool SendReturnBool(byte type, byte dataLength, byte[] data)
{
LCDPacket packet = Send(type, dataLength, data);
if (null != packet)
{
return (type == (packet.Type & 0x0F) && LCDPacket.LCDPacketType.NORMAL_RESPONSE == responsePacket.PacketType);
}
else
{
return false;
}
}
private void Receive()
{
try
{
byte[] receiveBuffer = new byte[128];
int bytesRead = 0;
int bufferIndex = 0;
int startPacketIndex = 0;
int expectedPacketLength = -1;
bool expectedPacketLengthIsSet = false;
int numBytesToRead = receiveBuffer.Length;
while (true)
{
if (expectedPacketLengthIsSet || 1 >= bytesRead)
{
//If the expectedPacketLength has been or no bytes have been read
//This covers the case that more then 1 entire packet has been read in at a time
// comPort
try
{
bytesRead += com.Read(receiveBuffer, bufferIndex, numBytesToRead);
bufferIndex = startPacketIndex + bytesRead;
}
catch (TimeoutException)
{
_timedOut = true;
}
}
if (1 < bytesRead)
{
//The buffer has the dataLength for the packet
if (!expectedPacketLengthIsSet)
{
//If the expectedPacketLength has not been set for this packet
expectedPacketLength = receiveBuffer[(1 + startPacketIndex) % receiveBuffer.Length] + 4;
expectedPacketLengthIsSet = true;
}
if (bytesRead >= expectedPacketLength)
{
//The buffer has atleast as many bytes for this packet
AddPacket(receiveBuffer, startPacketIndex);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -