- 浏览: 16711421 次
- 性别:
- 来自: 济南
-
最新评论
-
wu1236:
ef0793cd94337324b6fefc4c9474af5 ...
Android ApiDemos示例解析(87):Media->MediaPlayer -
77219634:
0127bf2236bee4dd1f632ce430f1af1 ...
本博客文章都为转载,没有任何版权! -
77219634:
0127bf2236bee4dd1f632ce430f1af1 ...
VPLEX - EMC的RAC -
77219634:
0127bf2236bee4dd1f632ce430f1af1 ...
qTip2 Show -
77219634:
0127bf2236bee4dd1f632ce430f1af1 ...
SecureCRT中文乱码、复制粘贴乱码解决办法(修改版)
状态机
1.发送数据和接收数据用2个状态机实现;
2.增加了当数据发送以后指定的间隔内连续发送3次,如果没有收到下位机的回复则放弃;
3.取消使用定时器Timer类,自己写定时器;
using System;
using System.Collections;
using
System.Threading;
using System.Xml;
using NLog;
using
System.Timers;
using System.IO;
using
System.Runtime.InteropServices;
using MSCommLib;
namespace equipment
{
/// <summary>
///
Desc:还书箱模块(用2个状态机实现)
/// Author:周陶
///
Date:2006-9-11
/// Version:1.0
///
</summary>
public class RestoreBook :
ThreadBase,EquipmentIF
{
#region
配置文件
private const string m_config_file =
"..//configure//equipment//RestoreBook_config.xml";
private const
string m_const_node_name =
"/configure/restorebooks/restorebook";
private const string
m_const_comport =
"/configure/restorebooks/restorebook/communication";
private
static Logger logger =
LogManager.GetCurrentClassLogger();
#endregion
#region 指令
private const string TCU_BOX_STATUS =
"41";
private const string TCU_BOOK_STATUS =
"40";
private const string TCU_CHECKMAG_STATUS =
"42";
private const string TCU_DOOR_STATUS =
"43";
private const string TCU_BOOK_MOVE =
"23";
private const string TCU_RUN = "22";
private
const string TCU_RESET = "21";
private const string TCU_END =
"26";
private const string TCU_CHECK_STATE =
"24";
#endregion
#region 响应码
private const string CE_OK =
"0";
private const string CE_CHECKERROR =
"1";
private const string CE_BADCOMMAND = "2";
//命令错误
private const string CE_BADPARAM = "3";
//参数错误
private const string CE_EXECUTE = "4";
//执行命令条件不足
private const string CE_UNKNOWN =
"5";
private const string CE_NOCOMM =
"6";
#endregion
#region 维护门状态
private const string TCU_DOOR_OPENED
= "1";
private const string TCU_DOOR_CLOSED =
"0";
#endregion
#region 检磁
private const string E_ERROR =
"1";
private const string E_OK =
"0";
#endregion
#region 书运行位置状态
private const string
E_READER_POSITION = "1";
private const string E_WITHDRAW =
"2";
private const string E_READY_WITHDRAW =
"3";
private const string E_FORWARD = "4";
private
const string E_BOOK_ENTRY_ALL = "5";
private const string
E_BLOCK_BEFORE_READER = "11";
private const string
E_BLOCK_BEFORE_BOX = "12";
private const string
E_TIMEOUT_READER_POSITION = "13";
private const string
E_TIMEOUT_WAITING_ENTRY = "14";
private const string
E_TIMEOUT_ENTRY = "15";
#endregion
#region 还书箱状态
private const string E_BOX_FULL =
"1";
private const string E_BOX_OK =
"0";
#endregion
/*****************************************************************************/
MSCommLib.MSCommClass
mc = new MSCommLib.MSCommClass();
ArrayList m_bytelist = new ArrayList();
byte[]
m_data = new
byte[11];
/*****************************************************************************/
/*****************************系统定时器**************************************/
private
bool IS_RESPONSED = true;//是否已经应答
private
int m_counter =
0;//用于计算3次消息发送
private string
m_name =
"";//响应指令名称
/*****************************************************************************/
/******************************自定义定时器***********************************/
BatchTimer
t_time =
null;//分片定时器
ResponseTimer
m_responsetimer =
null;//响应定时器
/*****************************************************************************/
/****************************状态机*******************************************/
#region
接收数据状态机
private const string R_WAITING =
"等待";
private const string R_RECEIVING =
"接收中";
private const string R_RECEIVEALL =
"全部接收";
private const string R_BATCHTIMEOUT =
"分片超时";
private const string R_RESPONSETIMEOUT =
"响应超时";
private const string R_ERRORCOMMAND =
"错误命令";
private const string R_ERRORSTATUS =
"错误状态";
#endregion
#region 发送数据状态机
private const string S_WAITING =
"等待";
private const string S_RECEIVEALL =
"全部接收";
private const string S_RESPONSETIMEOUT =
"响应超时";
private const string S_SEND =
"已发送";
private const string S_RESEND =
"重复发送";
private const string S_SENDCOUNT =
"超过3次发送次数";
private const string S_BATCHTIMEOUT =
"分片超时";
#endregion
/*****************************************************************************/
/****************************初始化状态机状态*********************************/
string
state1=S_WAITING,state2=R_WAITING;
byte [] m_byte = new
byte[11];
/*****************************************************************************/
[DllImport("user32.dll",EntryPoint="MessageBox")]
public
static extern void MsgBox(int hWnd,String text,String caption,uint type);
/// <summary>
/// 构造函数
///
</summary>
/// <param
name="i_name"></param>
public RestoreBook(string
i_name):base(i_name)
{
this.InitCommonPort();
t_time
= new BatchTimer();
m_responsetimer = new
ResponseTimer();
}
/// <summary>
///
从配置文件中读取配置端口号
/// </summary>
/// <param
name="t_config"></param>
///
<returns></returns>
private string
getComPortConfig(string
t_config)
{
XmlTextReader reader = new
XmlTextReader(m_config_file);
XmlDocument xmldoc = new
XmlDocument();
xmldoc.Load(reader);
reader.Close();
XmlNode t_node = xmldoc.SelectSingleNode(t_config);
string port = t_node.InnerText;
return
port;
}
///
<summary>
/// 取出指定长度的数据
///
</summary>
/// <param
name="o_bytelist"></param>
/// <param
name="length"></param>
private void GetReceiveData(ref
byte[] o_bytelist,int length)
{
for(int
i=0;i<length;i++)
{
o_bytelist[i]
=
(byte)m_bytelist[i];
}
m_bytelist.RemoveRange(0,length);
}
/// <summary>
///
接收MCU主动发送的消息、解析、封装成对象消息发送给Session层
///
</summary>
protected override void
process()
{
//以40,41,42,43开头的指令属于主动上报状态的命令
int
count = 0;
lock(state2)//接收数据状态机
{
switch(state2)
{
#region
接收中
case
R_RECEIVING:
{
count
= m_bytelist.Count;//计算缓冲区中接收到的数据长度
if(count ==
0)
{
state2
=
R_WAITING;
}
else
if(count < 11)//如果长度<11
接收不完整,启动分片定时器
{
#region
分片定时器
if(!t_time.IsStart)
{
t_time.Start();
t_time.Intenal
=
2000;
logger.Debug("\n分片定时器已启动!");
}
else
{
if(t_time.IsTimeOut)
{
state1
=
S_BATCHTIMEOUT;
}
}
#endregion
}
else
if(count >=
11)
{
this.GetReceiveData(ref
m_byte,11);
byte t_command = m_byte[2];//获得消息的命令用来判断是主动上报消息还是响应消息
if(m_byte[0] ==
0x82)
{
if(m_byte[10]
==
0x83)
{
if(verifyCRC(m_byte))
{
if(t_command
== 0x40 || t_command == 0x41 || t_command == 0x42 || t_command ==
0x43)
{
logger.Debug("\n正确的状态指令
: [" + Utilities.ByteArrayToHexString(m_byte) +
"]");
}
else
{
logger.Debug("\n正确的响应指令
: [" + Utilities.ByteArrayToHexString(m_byte) +
"]");
m_counter
=
0;
m_responsetimer.Stop();
}
state1
=
S_RECEIVEALL;//将发送状态机状态改为全部接收
state2
=
R_RECEIVING;//将接收状态机状态改为接收中
}
else
{
if(t_command
== 0x40 || t_command == 0x41 || t_command == 0x42 || t_command ==
0x43)
{
state2
=
R_ERRORSTATUS;
}
else
{
state2
=
R_ERRORCOMMAND;
}
}
}
else
{
if(t_command
== 0x40 || t_command == 0x41 || t_command == 0x42 || t_command ==
0x43)
{
state2
=
R_ERRORSTATUS;
}
else
{
state2
=
R_ERRORCOMMAND;
}
}
}
else
{
if(t_command
== 0x40 || t_command == 0x41 || t_command == 0x42 || t_command ==
0x43)
{
state2
=
R_ERRORSTATUS;
}
else
{
state2
=
R_ERRORCOMMAND;
}
}
}
break;
}
#endregion
#region
接收命令错误
case
R_ERRORCOMMAND:
{
state2
=
R_RECEIVING;//接收中
logger.Debug("\n响应命令格式错误!["
+ Utilities.ByteArrayToHexString(m_byte) +
"]");
this.clearArray(ref
m_byte);
break;
}
#endregion
#region
接收状态错误
case
R_ERRORSTATUS:
{
state2
=
R_RECEIVING;//接收中
logger.Debug("\n接收状态格式错误!
[" + Utilities.ByteArrayToHexString(m_byte) +
"]");
this.clearArray(ref
m_byte);
break;
}
#endregion
}
}
lock(state1)//发送数据状态机
{
switch(state1)
{
#region
已发送
case
S_SEND:
{
if(!m_responsetimer.IsStart)
{
m_responsetimer.Start();
m_responsetimer.Intenal
= 3000;
IS_RESPONSED =
false;
logger.Debug("\n响应超时定时器已启动!");
}
break;
}
#endregion
#region
接收完毕并通过验证
case
S_RECEIVEALL:
{
sendMail(m_byte);//通知上层
state1
= S_WAITING;
logger.Debug("\n已接收 : " +
Utilities.ByteArrayToHexString(m_byte) +
"]");
this.clearArray(ref
m_byte);
break;
}
#endregion
#region
重复发送3次
case
S_RESEND:
{
Thread.Sleep(1000);
mc.Output
= m_data;
state1 =
S_WAITING;
logger.Debug("\n重复发送指令 : [" +
Utilities.ByteArrayToHexString(m_data) + "]
"+m_counter+"次!");
break;
}
#endregion
#region
响应超时
case
S_RESPONSETIMEOUT:
{
state1
=
S_WAITING;
m_responsetimer.Stop();
m_counter
= 0;
IS_RESPONSED =
true;
this.clearArray(ref
m_data);
logger.Debug("\n响应已超时!");
break;
}
#endregion
#region
发送次数超过3次
case
S_SENDCOUNT:
{
m_counter
=
0;
m_responsetimer.Stop();
IS_RESPONSED
= true;
state1 =
S_WAITING;//将状态设为等待状态
logger.Debug("命令无应答,定时器已停止!");
MsgBox(0,"命令无应答!","提醒",0);
break;
}
#endregion
#region
分片超时
case
S_BATCHTIMEOUT:
{
state1
=
S_WAITING;//将接收状态机改为等待状态
this.GetReceiveData(ref
m_byte,count);
//m_bytelist.RemoveRange(0,count);//清除缓冲区
IS_RESPONSED
=
true;
t_time.Stop();
logger.Debug("\n不完整的"+m_name+"响应指令
: ["+Utilities.ByteArrayToHexString(m_byte) +
"],分片定时器已停止!");
this.clearArray(ref
m_byte);
break;
}
#endregion
}
}
#region 响应定时器
if(IS_RESPONSED ==
false)//没有响应
{
if(m_responsetimer.IsStart)//超时定时器已启动
{
if(m_counter
<
3)//发送次数小于3
{
if(m_responsetimer.IsTimeOut)//超时
{
state1
=
S_RESPONSETIMEOUT;//通知发送状态机响应超时
}
else//没有超时但没有收到响应
{
state1
=
S_RESEND;//通知发送状态机再发一次
m_counter
++;//次数+1
}
}
else//超过3次
{
state1
=
S_SENDCOUNT;//通知发送状态机停止发送,关闭定时器
}
}
}
#endregion
}
/// <summary>
///
check the data CRC
/// </summary>
///
<returns></returns>
private bool verifyCRC(byte[]
i_byte)
{
#region 接收
byte t1 = i_byte[8];
byte t2 =
i_byte[9];
byte [] data =
{0x08,i_byte[2],i_byte[4],i_byte[5],i_byte[6],i_byte[7]};
byte
[] crcData =
Utilities.CRC(data,data.Length);
if(t1==crcData[0]
&&
t2==crcData[1])
{
return
true;
}
else
{
return
false;
}
#endregion
}
///
<summary>
/// clear array
///
</summary>
/// <param
name="o_data"></param>
private void clearArray(ref
byte[]o_data)
{
for(int
i=0;i<o_data.Length;i++)
{
o_data[i]
=0;
}
}
/// <summary>
/// send mail
to session
/// </summary>
/// <param
name="inData"></param>
private void sendMail(byte[]
inData)
{
//构造命令
Mail
t_mail = null;
MailHandlerIF t_mail_handler = new RestoreBookMailHandler();
string t_cmd =
inData[2].ToString("X");//指令
string
t_paramter = inData[7].ToString("X");//参数
#region
switch(t_cmd)
{
case
TCU_BOX_STATUS: //主 动 上 报 回 收 箱 状
态
{
#region
switch(t_paramter)
{
case
E_BOX_FULL:
{
//箱满
t_mail =
t_mail_handler.CreateMail(MailInfo.Type.RestoreBook,MailInfo.Name.E_TCU_BOX_STATUS,this.m_send_mailbox,this.m_receive_mailbox,MailInfo.E_TCU_Parameter.E_BOX_FULL);
response("BOX",E_BOX_FULL);
break;
}
case
E_BOX_OK:
{
//正常
t_mail =
t_mail_handler.CreateMail(MailInfo.Type.RestoreBook,MailInfo.Name.E_TCU_BOX_STATUS,this.m_send_mailbox,this.m_receive_mailbox,MailInfo.E_TCU_Parameter.E_BOX_OK);
response("BOX",E_BOX_OK);
break;
}
}
this.m_send_mailbox.delivery(t_mail);
break;
#endregion
}
case
TCU_BOOK_STATUS: //TCU 主 动 上 报 书 运 行 位 置 状
态
{
#region
switch(t_paramter)
{
case
E_READER_POSITION:
{
//书已到读卡位置
t_mail = t_mail_handler.CreateMail(MailInfo.Type.RestoreBook,MailInfo.Name.E_TCU_BOOK_STATUS,this.m_send_mailbox,this.m_receive_mailbox,MailInfo.E_TCU_Parameter.E_READER_POSITION);
response("BOOK_STATUS",E_READER_POSITION);
break;
}
case
E_WITHDRAW:
{
//书已经从入口被取走
t_mail
=
t_mail_handler.CreateMail(MailInfo.Type.RestoreBook,MailInfo.Name.E_TCU_BOOK_STATUS,this.m_send_mailbox,this.m_receive_mailbox,MailInfo.E_TCU_Parameter.E_WITHDRAW);
response("BOOK_STATUS",E_WITHDRAW);
break;
}
case
E_READY_WITHDRAW:
{
//书已在入口处等待被取走
t_mail =
t_mail_handler.CreateMail(MailInfo.Type.RestoreBook,MailInfo.Name.E_TCU_BOOK_STATUS,this.m_send_mailbox,this.m_receive_mailbox,MailInfo.E_TCU_Parameter.E_READY_WITHDRAW);
response("BOOK_STATUS",E_READY_WITHDRAW);
break;
}
case
E_FORWARD:
{
//书已收入回收箱
t_mail
=
t_mail_handler.CreateMail(MailInfo.Type.RestoreBook,MailInfo.Name.E_TCU_BOOK_STATUS,this.m_send_mailbox,this.m_receive_mailbox,MailInfo.E_TCU_Parameter.E_FORWARD);
response("BOOK_STATUS",E_FORWARD);
break;
}
case
E_BOOK_ENTRY_ALL:
{
//书完全进入
t_mail
=
t_mail_handler.CreateMail(MailInfo.Type.RestoreBook,MailInfo.Name.E_TCU_BOOK_STATUS,this.m_send_mailbox,this.m_receive_mailbox,MailInfo.E_TCU_Parameter.E_BOOK_ENTRY_ALL);
response("BOOK_STATUS",E_BOOK_ENTRY_ALL);
break;
}
case
E_BLOCK_BEFORE_READER:
{
//读卡位置到入口之间发生堵塞故障
t_mail =
t_mail_handler.CreateMail(MailInfo.Type.RestoreBook,MailInfo.Name.E_TCU_BOOK_STATUS,this.m_send_mailbox,this.m_receive_mailbox,MailInfo.E_TCU_Parameter.E_BLOCK_BEFORE_READER);
response("BOOK_STATUS",E_BLOCK_BEFORE_READER);
break;
}
case
E_BLOCK_BEFORE_BOX:
{
//读卡位置到回收箱之间发生堵塞故障
t_mail =
t_mail_handler.CreateMail(MailInfo.Type.RestoreBook,MailInfo.Name.E_TCU_BOOK_STATUS,this.m_send_mailbox,this.m_receive_mailbox,MailInfo.E_TCU_Parameter.E_BLOCK_BEFORE_BOX);
response("BOOK_STATUS",E_BLOCK_BEFORE_BOX);
break;
}
case
E_TIMEOUT_READER_POSITION:
{
//读卡位置等待超时
t_mail =
t_mail_handler.CreateMail(MailInfo.Type.RestoreBook,MailInfo.Name.E_TCU_BOOK_STATUS,this.m_send_mailbox,this.m_receive_mailbox,MailInfo.E_TCU_Parameter.E_TIMEOUT_READER_POSITION);
response("BOOK_STATUS",E_TIMEOUT_READER_POSITION);
break;
}
case
E_TIMEOUT_WAITING_ENTRY:
{
//书等待进入超时
t_mail =
t_mail_handler.CreateMail(MailInfo.Type.RestoreBook,MailInfo.Name.E_TCU_BOOK_STATUS,this.m_send_mailbox,this.m_receive_mailbox,MailInfo.E_TCU_Parameter.E_TIMEOUT_WAITING_ENTRY);
response("BOOK_STATUS",E_TIMEOUT_WAITING_ENTRY);
break;
}
case
E_TIMEOUT_ENTRY:
{
//书在入口处等待超时
t_mail =
t_mail_handler.CreateMail(MailInfo.Type.RestoreBook,MailInfo.Name.E_TCU_BOOK_STATUS,this.m_send_mailbox,this.m_receive_mailbox,MailInfo.E_TCU_Parameter.E_TIMEOUT_ENTRY);
response("BOOK_STATUS",E_TIMEOUT_ENTRY);
break;
}
}
this.m_send_mailbox.delivery(t_mail);
break;
#endregion
}
case
TCU_CHECKMAG_STATUS: //主 动 上 报 检 磁 状
态
{
#region
switch(t_paramter)
{
case
E_ERROR:
{
//检磁失败
t_mail =
t_mail_handler.CreateMail(MailInfo.Type.RestoreBook,MailInfo.Name.E_TCU_CHECKMAG_STATUS,this.m_send_mailbox,this.m_receive_mailbox,MailInfo.E_TCU_Parameter.E_ERROR);
response("CHECKMAG",E_ERROR);
break;
}
case
E_OK:
{
//检磁成功
t_mail
=
t_mail_handler.CreateMail(MailInfo.Type.RestoreBook,MailInfo.Name.E_TCU_CHECKMAG_STATUS,this.m_send_mailbox,this.m_receive_mailbox,MailInfo.E_TCU_Parameter.E_OK);
response("CHECKMAG",E_OK);
break;
}
}
this.m_send_mailbox.delivery(t_mail);
break;
#endregion
}
case
TCU_DOOR_STATUS: //主 动 上 报 维 护 门 状
态
{
#region
switch(t_paramter)
{
case
TCU_DOOR_OPENED:
{
//门被打开
t_mail =
t_mail_handler.CreateMail(MailInfo.Type.RestoreBook,MailInfo.Name.E_TCU_DOOR_STATUS,this.m_send_mailbox,this.m_receive_mailbox,MailInfo.E_TCU_Parameter.E_DOOR_OPEN);
response("DOOR_STATUS",TCU_DOOR_OPENED);
break;
}
case
TCU_DOOR_CLOSED:
{
//门关闭
t_mail =
t_mail_handler.CreateMail(MailInfo.Type.RestoreBook,MailInfo.Name.E_TCU_DOOR_STATUS,this.m_send_mailbox,this.m_receive_mailbox,MailInfo.E_TCU_Parameter.E_DOOR_CLOSE);
response("DOOR_STATUS",TCU_DOOR_CLOSED);
break;
}
}
this.m_send_mailbox.delivery(t_mail);
break;
#endregion
}
case
TCU_BOOK_MOVE: //指 导 书 运 行 状
态
{
#region
switch(t_paramter)
{
case
CE_OK://正常
{
t_mail
=
t_mail_handler.CreateMail(MailInfo.Type.RestoreBook,MailInfo.Name.E_TCU_BOOK_MOVE,this.m_send_mailbox,this.m_receive_mailbox,MailInfo.ErrorParameter.E_TCU_OK);
break;
}
case
CE_CHECKERROR://校验错误
{
t_mail
=
t_mail_handler.CreateMail(MailInfo.Type.RestoreBook,MailInfo.Name.E_TCU_BOOK_MOVE,this.m_send_mailbox,this.m_receive_mailbox,MailInfo.ErrorParameter.E_TCU_CHECKERROR);
break;
}
case
CE_BADCOMMAND://命令错误
{
t_mail
=
t_mail_handler.CreateMail(MailInfo.Type.RestoreBook,MailInfo.Name.E_TCU_BOOK_MOVE,this.m_send_mailbox,this.m_receive_mailbox,MailInfo.ErrorParameter.E_TCU_BADCOMMAND);
break;
}
case
CE_BADPARAM://参数错误
{
t_mail
=
t_mail_handler.CreateMail(MailInfo.Type.RestoreBook,MailInfo.Name.E_TCU_BOOK_MOVE,this.m_send_mailbox,this.m_receive_mailbox,MailInfo.ErrorParameter.E_TCU_BADPARAM);
break;
}
case
CE_EXECUTE://命令执行条件不足
{
t_mail
=
t_mail_handler.CreateMail(MailInfo.Type.RestoreBook,MailInfo.Name.E_TCU_BOOK_MOVE,this.m_send_mailbox,this.m_receive_mailbox,MailInfo.ErrorParameter.E_TCU_EXECUTE);
break;
}
case
CE_UNKNOWN://其他错误
{
t_mail
=
t_mail_handler.CreateMail(MailInfo.Type.RestoreBook,MailInfo.Name.E_TCU_BOOK_MOVE,this.m_send_mailbox,this.m_receive_mailbox,MailInfo.ErrorParameter.E_TCU_UNKNOWN);
break;
}
case
CE_NOCOMM://通讯故障
{
t_mail
=
t_mail_handler.CreateMail(MailInfo.Type.RestoreBook,MailInfo.Name.E_TCU_BOOK_MOVE,this.m_send_mailbox,this.m_receive_mailbox,MailInfo.ErrorParameter.E_TCU_NOCOMM);
break;
}
}
this.m_send_mailbox.delivery(t_mail);
break;
#endregion
}
case
TCU_RUN:
//登 陆 成
功
{
#region
switch(t_paramter)
{
case
CE_OK://正常
{
t_mail
=
t_mail_handler.CreateMail(MailInfo.Type.RestoreBook,MailInfo.Name.E_TCU_RUN,this.m_send_mailbox,this.m_receive_mailbox,MailInfo.ErrorParameter.E_TCU_OK);
this.m_send_mailbox.delivery(t_mail);
break;
}
}
break;
#endregion
}
case
TCU_RESET:
//复
位
{
#region
switch(t_paramter)
{
case
CE_OK://正常
{
t_mail
=
t_mail_handler.CreateMail(MailInfo.Type.RestoreBook,MailInfo.Name.E_TCU_RESET,this.m_send_mailbox,this.m_receive_mailbox,MailInfo.ErrorParameter.E_TCU_OK);
this.m_send_mailbox.delivery(t_mail);
break;
}
}
break;
#endregion
}
case
TCU_END:
//结
束
{
#region
switch(t_paramter)
{
case
CE_OK://正常
{
t_mail
=
t_mail_handler.CreateMail(MailInfo.Type.RestoreBook,MailInfo.Name.E_TCU_END,this.m_send_mailbox,this.m_receive_mailbox,MailInfo.ErrorParameter.E_TCU_OK);
this.m_send_mailbox.delivery(t_mail);
break;
}
}
break;
#endregion
}
case
TCU_CHECK_STATE://检 查 设 备 状
态
{
byte p4 =
inData[7];
if((p4 & 0x02) ==
0)
{
t_mail
=
t_mail_handler.CreateMail(MailInfo.Type.RestoreBook,MailInfo.Name.E_TCU_CHECK_STATE,this.m_send_mailbox,this.m_receive_mailbox,MailInfo.E_TCU_Parameter.E_BOX_COVER);
this.m_send_mailbox.delivery(t_mail);
}
if((p4
& 0x04) ==
0)
{
t_mail
=
t_mail_handler.CreateMail(MailInfo.Type.RestoreBook,MailInfo.Name.E_TCU_CHECK_STATE,this.m_send_mailbox,this.m_receive_mailbox,MailInfo.E_TCU_Parameter.E_DOOR_COVER);
this.m_send_mailbox.delivery(t_mail);
}
if((p4
& 0x08) ==
0)
{
t_mail
=
t_mail_handler.CreateMail(MailInfo.Type.RestoreBook,MailInfo.Name.E_TCU_CHECK_STATE,this.m_send_mailbox,this.m_receive_mailbox,MailInfo.E_TCU_Parameter.E_CHECKMAG_CONVER);
this.m_send_mailbox.delivery(t_mail);
}
if((p4
& 0x10) ==
0)
{
t_mail
=
t_mail_handler.CreateMail(MailInfo.Type.RestoreBook,MailInfo.Name.E_TCU_CHECK_STATE,this.m_send_mailbox,this.m_receive_mailbox,MailInfo.E_TCU_Parameter.E_READER_CONVER);
this.m_send_mailbox.delivery(t_mail);
}
if((p4
& 0x20) ==
0)
{
t_mail
=
t_mail_handler.CreateMail(MailInfo.Type.RestoreBook,MailInfo.Name.E_TCU_CHECK_STATE,this.m_send_mailbox,this.m_receive_mailbox,MailInfo.E_TCU_Parameter.E_BOX_ENTRY1_CONVER);
this.m_send_mailbox.delivery(t_mail);
}
if((p4
& 0x40) ==
0)
{
t_mail
=
t_mail_handler.CreateMail(MailInfo.Type.RestoreBook,MailInfo.Name.E_TCU_CHECK_STATE,this.m_send_mailbox,this.m_receive_mailbox,MailInfo.E_TCU_Parameter.E_BOX_ENTRY2_COVER);
this.m_send_mailbox.delivery(t_mail);
}
break;
}
}
#endregion
//发送命令
//this.m_send_mailbox.delivery(t_mail);
}
/// <summary>
/// init
com
/// </summary>
private void
InitCommonPort()
{
try
{
string
[] t_comport =
this.getComPortConfig(m_const_comport).Split(':');
mc.CommPort
= Convert.ToInt16( t_comport[0].Substring(3,1)
);//4
mc.Settings = t_comport[1]
;//38400,n,8,1
mc.RThreshold
=
1;//每接收一个字符则激发OnComm()事件
mc.DTREnable
= true;
mc.Handshaking =
MSCommLib.HandshakeConstants.comNone;
mc.InputMode =
MSCommLib.InputModeConstants.comInputModeBinary;
//二进制
mc.InBufferSize =
1024;
mc.InputLen =
0;//决定每次Input读入的字符个数,缺省为0,表示读取接收缓冲区的全部内容
//mc.InputLen
=
1;//一次读取一个
mc.NullDiscard
= false;
mc.OnComm +=new
MSCommLib.DMSCommEvents_OnCommEventHandler(mc_OnComm);//注册一个OnComm事件
try
{
mc.PortOpen
= true;
//打开串口
logger.Debug("串口已打开!");
}
catch
{
logger.Debug("串口打开失败!");
}
}
catch(Exception
ex)
{
logger.Debug(ex.Message);
}
}
/// <summary>
/// release
resource
/// </summary>
public override void
shutDown()
{
if(mc.PortOpen)
mc.PortOpen
= false;
}
/// <summary>
/// receive the data from
session layer then parse、create com data and send to MCU
///
</summary>
/// <param
name="i_mail"></param>
protected override void
commonMailArriveProcess(Mail
i_mail)
{
MailInfo.Name t_mail_name =
i_mail.m_mail_name; //mail
name(command)
string t_book_parameter
= (string)i_mail.m_parameter; //parameter
byte [] data =
{0x08,0x00,0x00,0x00,0x00,0x00};
byte [] outData =
{0x02,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03};
byte
[] crcData = null;
byte [] cData = null;
#region
switch(t_mail_name)
{
case
MailInfo.Name.E_TCU_RESET:
//复位
{
#region
data[1]
= 0x21;
crcData =
Utilities.CRC(data,data.Length);
outData[2]
= 0x21;
outData[8] =
crcData[0];
outData[9] =
crcData[1];
mc.Output =
outData;
logger.Debug("\n复位 : [" + Utilities.ByteArrayToHexString(outData) + "]");
break;
#endregion
}
case
MailInfo.Name.E_TCU_RUN:
//登陆成功
{
#region
data[1] =
0x22;
crcData =
Utilities.CRC(data,data.Length);
outData[2] =
0x22;
outData[8] =
crcData[0];
outData[9] = crcData[1];
mc.Output = outData;
m_name =
"登陆成功";
logger.Debug("\n发送登陆成功指令 : [" +
Utilities.ByteArrayToHexString(outData) + "]");
/***********************************************************************************/
outData.CopyTo(m_data,0);//将消息复制到全局变量数组中,以后用来判断改消息是否回复
state1
=
S_SEND;//将发送状态机的状态改为已发送
/***********************************************************************************/
break;
#endregion
}
case
MailInfo.Name.E_TCU_CHECK_STATE:
//检查设备状态
{
#region
data[1]
= 0x24;
crcData =
Utilities.CRC(data,data.Length);
outData[2] =
0x24;
outData[8] =
crcData[0];
outData[9] =
crcData[1];
mc.Output =
outData;
m_name =
"检查设备状态";
logger.Debug("\n检查设备状态 : [" +
Utilities.ByteArrayToHexString(outData) + "]");
/************************************************************************************/
outData.CopyTo(m_data,0);//将消息复制到全局变量数组中,以后用来判断改消息是否回复
state1
=
S_SEND;//将发送状态机的状态改为已发送
/************************************************************************************/
break;
#endregion
}
case
MailInfo.Name.E_TCU_BOOK_MOVE:
//指导书运动
{
#region
switch(t_book_parameter)
{
case
"E_BACK":
//书已退到入口
{
#region
data[1]
= 0x23;
data[5] =
0x01;
crcData =
Utilities.CRC(data,data.Length);
outData[2]
= 0x23;
outData[7] =
0x01;
outData[8] =
crcData[0];
outData[9] =
crcData[1];
logger.Debug("\n书已退到入口 : ["+ Utilities.ByteArrayToHexString(outData) + "]");
break;
#endregion
}
case
"E_FORWARD": //收入回收箱
{
#region
data[1]
= 0x23;
data[5] =
0x02;
crcData =
Utilities.CRC(data,data.Length);
outData[2]
= 0x23;
outData[7] =
0x02;
outData[8] =
crcData[0];
outData[9] =
crcData[1];
logger.Debug("\n收入回收箱 : ["+ Utilities.ByteArrayToHexString(outData) + "]");
break;
#endregion
}
}
mc.Output
= outData;
/************************************************************************************/
outData.CopyTo(m_data,0);//将消息复制到全局变量数组中,以后用来判断改消息是否回复
state1 =
S_SEND;//将发送状态机的状态改为已发送
/************************************************************************************/
break;
#endregion
}
case
MailInfo.Name.E_TCU_BOOK_STATUS:
//主动上报书运行位置状态
{
#region
switch(t_book_parameter)
{
case
"E_READER_POSITION"://书已到读卡位置
{
#region
data[1]
= 0x40;
data[5] =
0x01;
cData =
Utilities.CRC(data,data.Length);
outData[0] =
0x82;
outData[2] =
0x40;
outData[7] =
0x01;
outData[8] =
cData[0];
outData[9] =
cData[1];
outData[10] = 0x83;
logger.Debug("\n书已到读卡位置 : [" + Utilities.ByteArrayToHexString(outData) + "]");
break;
#endregion
}
case
"E_WITHDRAW"://书已从入口被取走
{
#region
data[1]
= 0x40;
data[5] =
0x02;
cData =
Utilities.CRC(data,data.Length);
outData[0] =
0x82;
outData[2] =
0x40;
outData[7] =
0x02;
outData[8] =
cData[0];
outData[9] =
cData[1];
outData[10] = 0x83;
logger.Debug("\n书已从入口被取走 : [" + Utilities.ByteArrayToHexString(outData) + "]");
break;
#endregion
}
case
"E_READY_WITHDRAW"://书已在入口处等待被取走
{
#region
data[1]
= 0x40;
data[5] =
0x03;
cData =
Utilities.CRC(data,data.Length);
outData[0] =
0x82;
outData[2] =
0x40;
outData[7] =
0x03;
outData[8] =
cData[0];
outData[9] =
cData[1];
outData[10] = 0x83;
logger.Debug("\n书已在入口处等待被取走 : [" + Utilities.ByteArrayToHexString(outData) +"]");
break;
#endregion
}
case
"E_FORWARD"://书已收入回收箱
{
#region
data[1]
= 0x40;
data[5] =
0x04;
cData =
Utilities.CRC(data,data.Length);
outData[0] =
0x82;
outData[2] =
0x40;
outData[7] =
0x04;
outData[8] =
cData[0];
outData[9] =
cData[1];
outData[10] = 0x83;
logger.Debug("\n书已收入回收箱 : [" + Utilities.ByteArrayToHexString(outData) +"]");
break;
#endregion
}
case
"E_BLOCK_BEFORE_READER"://读卡位置到入口之间发生堵塞故障
{
#region
data[1]
= 0x40;
data[5] =
0x011;
cData =
Utilities.CRC(data,data.Length);
outData[0] =
0x82;
outData[2] =
0x40;
outData[7] =
0x11;
outData[8] =
cData[0];
outData[9] =
cData[1];
outData[10] = 0x83;
logger.Debug("\n读卡位置到入口之间发生堵塞故障 :
[" + Utilities.ByteArrayToHexString(outData)
+"]");
break;
#endregion
}
case
"E_BLOCK_BEFORE_BOX"://读卡位置到回收箱之间发生堵塞故障
{
#region
data[1]
= 0x40;
data[5] =
0x12;
cData =
Utilities.CRC(data,data.Length);
outData[0] =
0x82;
outData[2] =
0x40;
outData[7] =
0x12;
outData[8] =
cData[0];
outData[9] =
cData[1];
outData[10] = 0x83;
logger.Debug("\n读卡位置到回收箱之间发生堵塞故障 : [" + Utilities.ByteArrayToHexString(outData) +"]");
break;
#endregion
}
case
"E_TIMEOUT_READER_POSITION":
//读卡位置等待超时
{
#region
data[1]
= 0x40;
data[5] =
0x13;
cData =
Utilities.CRC(data,data.Length);
outData[0] =
0x82;
outData[2] =
0x40;
outData[7] =
0x13;
outData[8] =
cData[0];
outData[9] =
cData[1];
outData[10] = 0x83;
logger.Debug("\n读卡位置等待超时 : [" + Utilities.ByteArrayToHexString(outData)+"]");
break;
#endregion
}
case
"E_TIMEOUT_WAITING_ENTRY"://书等待进入超时
{
#region
data[1]
= 0x40;
data[5] =
0x14;
cData =
Utilities.CRC(data,data.Length);
outData[0] =
0x82;
outData[2] =
0x40;
outData[7] =
0x14;
outData[8] =
cData[0];
outData[9] =
cData[1];
outData[10] = 0x83;
logger.Debug("\n书等待进入超时 : [" + Utilities.ByteArrayToHexString(outData)+"]");
break;
#endregion
}
case
"E_TIMEOUT_ENTRY"://书在入口处等待超时
{
#region
data[1]
= 0x40;
data[5] =
0x15;
cData =
Utilities.CRC(data,data.Length);
outData[0] =
0x82;
outData[2] =
0x40;
outData[7] =
0x15;
outData[8] =
cData[0];
outData[9] =
cData[1];
outData[10] = 0x83;
logger.Debug("\n书在入口处等待超时 : [" + Utilities.ByteArrayToHexString(outData) + "]");
break;
#endregion
}
default://书已进入还书箱
{
#region
data[1]
= 0x23;
cData =
Utilities.CRC(data,data.Length);
outData[2] =
0x23;
outData[8] =
cData[0];
outData[9] =
cData[1];
logger.Debug("\n书已进入还书箱 : [" + Utilities.ByteArrayToHexString(outData) + "]");
break;
#endregion
}
}
mc.Output =
outData;
break;
#endregion
}
case
MailInfo.Name.E_TCU_END:
//结束
{
#region
data[1] =
0x26;
crcData =
Utilities.CRC(data,data.Length);
outData[2] =
0x26;
outData[8] =
crcData[0];
outData[9] = crcData[1];
mc.Output = outData;
m_name =
"结束";
logger.Debug("\n结束
: [" + Utilities.ByteArrayToHexString(outData) + "]");
/*************************************************************************************/
outData.CopyTo(m_data,0);//将消息复制到全局变量数组中,以后用来判断改消息是否回复
state1
=
S_SEND;//将发送状态机的状态改为已发送
/*************************************************************************************/
break;
#endregion
}
}
#endregion
}
/// <summary>
///
对下位机主动发送的命令的响应
/// </summary>
/// <param
name="command">命令</param>
/// <param
name="parameter">参数</param>
private void response(string
command,string parameter)
{
byte [] crcData
= null;//校验码
byte [] data =
null;//参与计算校验码值参数
byte [] outData =
null;//响应消息
switch(command)
{
case
"BOX"://还书箱状态
{
switch(parameter)
{
#region
case
E_BOX_FULL://还书箱已满
{
data
= new
byte[]{0x08,0x41,0x00,0x00,0x00,0x00};
crcData
=
Utilities.CRC(data,data.Length);
outData
= new
byte[]{0x02,0x08,0x41,0x00,0x00,0x00,0x00,0x00,crcData[0],crcData[1],0x03};
break;
}
case
E_BOX_OK://还书箱正常
{
data
= new
byte[]{0x08,0x41,0x00,0x00,0x00,0x00};
crcData
=
Utilities.CRC(data,data.Length);
outData
= new
byte[]{0x02,0x08,0x41,0x00,0x00,0x00,0x00,0x00,crcData[0],crcData[1],0x03};
break;
}
#endregion
}
break;
}
case
"BOOK_STATUS"://书运行状态
{
switch(parameter)
{
#region
case
E_READER_POSITION://书已到读卡位置
{
data
= new
byte[]{0x08,0x40,0x00,0x00,0x00,0x00};
crcData
=
Utilities.CRC(data,data.Length);
outData
= new
byte[]{0x02,0x08,0x40,0x00,0x00,0x00,0x00,0x00,crcData[0],crcData[1],0x03};
break;
}
case
E_WITHDRAW://书从入口被取走
{
data
= new
byte[]{0x08,0x40,0x00,0x00,0x00,0x00};
crcData
=
Utilities.CRC(data,data.Length);
outData
= new
byte[]{0x02,0x08,0x40,0x00,0x00,0x00,0x00,0x00,crcData[0],crcData[1],0x03};
break;
}
case
E_READY_WITHDRAW://书已在入口处被等待取走
{
data
= new
byte[]{0x08,0x40,0x00,0x00,0x00,0x00};
crcData
=
Utilities.CRC(data,data.Length);
outData
= new
byte[]{0x02,0x08,0x40,0x00,0x00,0x00,0x00,0x00,crcData[0],crcData[1],0x03};
break;
}
case
E_FORWARD://书已进入回收箱
{
data
= new
byte[]{0x08,0x40,0x00,0x00,0x00,0x00};
crcData
=
Utilities.CRC(data,data.Length);
outData
= new
byte[]{0x02,0x08,0x40,0x00,0x00,0x00,0x00,0x00,crcData[0],crcData[1],0x03};
break;
}
case
E_BOOK_ENTRY_ALL://书已完全进入
{
data
= new
byte[]{0x08,0x40,0x00,0x00,0x00,0x00};
crcData
=
Utilities.CRC(data,data.Length);
outData
= new
byte[]{0x02,0x08,0x40,0x00,0x00,0x00,0x00,0x00,crcData[0],crcData[1],0x03};
break;
}
case
E_BLOCK_BEFORE_READER://读卡位置到入口之间发生堵塞故障
{
data
= new
byte[]{0x08,0x40,0x00,0x00,0x00,0x00};
crcData
=
Utilities.CRC(data,data.Length);
outData
= new
byte[]{0x02,0x08,0x40,0x00,0x00,0x00,0x00,0x00,crcData[0],crcData[1],0x03};
break;
}
case
E_BLOCK_BEFORE_BOX://读卡位置到回收箱之间发生堵塞故障
{
data
= new
byte[]{0x08,0x40,0x00,0x00,0x00,0x00};
crcData
=
Utilities.CRC(data,data.Length);
outData
= new
byte[]{0x02,0x08,0x40,0x00,0x00,0x00,0x00,0x00,crcData[0],crcData[1],0x03};
break;
}
case
E_TIMEOUT_READER_POSITION://读卡位置等待超时
{
data
= new
byte[]{0x08,0x40,0x00,0x00,0x00,0x00};
crcData
=
Utilities.CRC(data,data.Length);
outData
= new
byte[]{0x02,0x08,0x40,0x00,0x00,0x00,0x00,0x00,crcData[0],crcData[1],0x03};
break;
}
case
E_TIMEOUT_WAITING_ENTRY://书等待进入超时
{
data
= new
byte[]{0x08,0x40,0x00,0x00,0x00,0x00};
crcData
=
Utilities.CRC(data,data.Length);
outData
= new
byte[]{0x02,0x08,0x40,0x00,0x00,0x00,0x00,0x00,crcData[0],crcData[1],0x03};
break;
}
case
E_TIMEOUT_ENTRY://书在入口处等待超时
{
data
= new
byte[]{0x08,0x40,0x00,0x00,0x00,0x00};
crcData
=
Utilities.CRC(data,data.Length);
outData
= new
byte[]{0x02,0x08,0x40,0x00,0x00,0x00,0x00,0x00,crcData[0],crcData[1],0x03};
break;
}
#endregion
}
break;
}
case
"CHECKMAG"://检磁状态
{
switch(parameter)
{
#region
case
E_ERROR:
{
data
= new
byte[]{0x08,0x42,0x00,0x00,0x00,0x00};
crcData
=
Utilities.CRC(data,data.Length);
outData
= new
byte[]{0x02,0x08,0x42,0x00,0x00,0x00,0x00,0x00,crcData[0],crcData[1],0x03};
break;
}
case
E_OK:
{
data
= new
byte[]{0x08,0x42,0x00,0x00,0x00,0x00};
crcData
=
Utilities.CRC(data,data.Length);
outData
= new
byte[]{0x02,0x08,0x42,0x00,0x00,0x00,0x00,0x00,crcData[0],crcData[1],0x03};
break;
}
#endregion
}
break;
}
case
"DOOR_STATUS"://维护门状态
{
switch(parameter)
{
#region
case
TCU_DOOR_OPENED:
{
data
= new
byte[]{0x08,0x43,0x00,0x00,0x00,0x00};
crcData
=
Utilities.CRC(data,data.Length);
outData
= new
byte[]{0x02,0x08,0x43,0x00,0x00,0x00,0x00,0x00,crcData[0],crcData[1],0x03};
break;
}
case
TCU_DOOR_CLOSED:
{
data
= new
byte[]{0x08,0x43,0x00,0x00,0x00,0x00};
crcData
=
Utilities.CRC(data,data.Length);
outData
= new
byte[]{0x02,0x08,0x43,0x00,0x00,0x00,0x00,0x00,crcData[0],crcData[1],0x03};
break;
}
#endregion
}
break;
}
}
mc.Output = outData;
}
/// <summary>
///
receive data from com
/// </summary>
private
void mc_OnComm()
{
byte [] t_byte =
(byte[])mc.Input;//接收数据清空缓冲区
for(int i =
0;i<t_byte.Length;i++)
{
Monitor.Enter(m_bytelist);
m_bytelist.Add(t_byte[i]);
Monitor.Exit(m_bytelist);
}
lock(state2)
{
if(t_byte.Length
> 0)
{
state2 =
R_RECEIVING;//有数据到达把状态改成正在接收
}
}
}
}
}
相关推荐
状态机是一种设计模式,常用于控制系统的流程或行为,它定义了一组状态以及在不同条件下的状态转换。在8051单片机上实现状态机,可以有效地组织程序结构,提高代码的可读性和可维护性。Keil是常用的8051单片机开发...
C# 状态机 Stateless 详解 C# 状态机 Stateless 是一种轻量级的状态机库,能够帮助开发者轻松地创建状态机,实现状态之间的切换。下面是对 C# 状态机 Stateless 的详细介绍。 什么是状态机? 状态机(Finite ...
StateMachine 状态机机制深入解析 StateMachine 状态机机制是指在软件开发中,使用状态机来描述和处理复杂的业务流程。状态机机制可以帮助开发者简化状态机的开发过程,并且可以提高代码的可读性和维护性。在 ...
状态机在单片机编程中扮演着至关重要的角色,它是一种设计模式,广泛应用于各种编程语言,包括C语言。状态机的核心概念在于通过定义不同状态、条件、动作和次态来组织程序逻辑,使得程序执行更加高效、可读性强且...
在这个名为“状态机实验报告1”的实验中,我们关注的是状态机的设计和实现,特别是Moore型和Mealy型状态机的区别与应用。 Moore状态机与Mealy状态机是状态机的两种基本类型。Moore状态机的输出只取决于当前状态,而...
通用有限状态机(FSM: Finite-state machine)自动代码生成器. 可以根据配置文件,自动生成状态机代码(C++)。配置文件中只需要定义状态,跃迁条件。然后完善每个状态的动作即可。省去开发过程中手写状态机的麻烦。...
### VHDL中的有限状态机设计概述 #### 一、有限状态机(FSM)的重要性与优点 有限状态机(Finite State Machine, FSM)是一种被广泛应用于数字逻辑设计中的模型,尤其在VHDL语言中有着非常重要的地位。在设计复杂的...
在这个项目中,“简单状态机控制步进电机”是利用状态机的设计思想来实现对步进电机的精确控制。状态机是一种用于描述系统行为的模型,它按照预定义的一系列状态进行转换,每个状态对应于特定的操作或行为。 首先,...
在编程领域,状态机是一种非常重要的设计模式,它被广泛应用于各种复杂的逻辑控制流程中。在C#中,我们可以利用面向对象的特性来实现状态机,以管理对象在不同状态之间的转换。本篇将深入探讨如何在C#中实现状态机,...
状态机是一种设计模式,常用于处理具有多个状态和转换规则的系统。在嵌入式开发中,它尤其重要,因为这种简洁的模型可以帮助管理复杂的控制流程,提高代码的可读性和可维护性。本资源“C语言嵌入式状态机架构(含C...
在数字系统设计中,状态机是一种非常重要的构造模块,它用于控制系统的流程和行为。VHDL(Very High-Speed Integrated Circuit Hardware Description Language)是用于硬件描述的语言,常用于FPGA和ASIC设计。本篇...
在IT领域,有限状态机(Finite State Machine, FSM)是一种重要的设计模式,它在软件工程、计算机科学以及许多其他领域都有广泛的应用。本主题“一个有趣的有限状态机的JAVA实现”将带你探索如何利用Java语言构建一...
可通信状态机(CSM)是一个基于JKI状态机(JKISM)的LabVIEW应用框架。它遵循 JKISM 的模式,扩展了关键词以描述模块之间的消息通信,包括同步消息、异步消息、状态订阅/取消订阅等概念! 可通信状态机(CSM)是一个...
《C语言高效有限状态机(FSM)详细设计说明书》 有限状态机(Finite State Machine, FSM)是一种模型理论,它将一个系统的行为描述为一系列可切换的状态,以及这些状态之间的转换。这种模型在IT领域中广泛应用,特别...
状态机在计算机科学中是一种建模工具,常用于描述系统的行为和状态转换。在TCP/IP协议栈中,状态机被广泛应用于理解网络连接的不同阶段,如TCP连接的三次握手和四次挥手过程。TCP(传输控制协议)是互联网协议的一...
### 状态机知识与C语言实现详解 #### 一、状态机基础知识 **状态机**(Finite State Machine, FSM)在软件工程中是一种重要的抽象模型工具,它被广泛应用于各种场景中,例如用户界面的设计、协议栈的开发以及游戏AI...
而"钟桦VHDL第一次作业课件.pdf"则可能是钟教授关于VHDL状态机设计的课件,可能涵盖了状态机的基本概念,如何描述状态机,以及如何实现序列检测器的具体步骤。 通过学习这部分内容,学生不仅能掌握VHDL的基础知识,...
单片机多按键状态机的实现是嵌入式系统中常用的一种处理多个按键输入的方法,尤其在资源有限的环境中,如消费电子产品、智能家居设备等。本文将深入探讨如何设计和实现一个这样的系统。 首先,我们需要了解单片机。...
JTAG TAP 状态机解析 JTAG 协议是目前应用最广泛的下载和仿真协议,对协议的最初缔造者来说,这也许有点无心插柳柳成荫的感觉——最初的 JTAG 协议只是用来辅助专门的硬件质检部门对印刷电路进行检测的。这些老账现...
状态机是一种重要的设计模式,广泛应用于软件工程、计算机科学、电子工程和其他领域。它通过定义一组状态以及在这些状态之间转换的规则来描述系统的行为。理解标准状态机的概念及其应用对于开发高效、可靠且可维护的...