您的位置:首页 > 其它

串口状态机的应用[转载]

2017-05-18 16:20 176 查看
以前并没有发现串口状态机的好处,最近用到了这种指定格式的数据包解析,才发现这东西非常的好用,可以对串口的数据包进行过滤只解出符合协议的数据包。这个呢其实就是一种思想,不仅仅局限于串口之间的数据传输,我认为可以用在很多指定数据协议的数据包传输解析当中。大致代码思想写在下面,希望对大家有帮助。
/* 主要的变量声明在这边 */
/* 串口状态机宏 */
#define DATA_HEAD  3
#define DATA_LEN   4
#define DATA_COM   5
#define DATA_NUM   6
#define DATA_CRC   7
#define DATA_TAIL  8
#define DATA_ADD   9

#define COMMAND_SIZE 20

int g_count = 0;             //状态机缓冲区下标
int g_uart_state = DATA_HEAD;//串口状态机状态标志
unsigned char data;          //串口数据
//状态机缓冲区
unsigned char command_buf[COMMAND_SIZE] = {0};
unsigned char *bufptr = &data;

while (1)
{
/* 从串口中一次只读取一个字符 */
retv = read(fd, bufptr, 1);
if (-1 == retv)
{
printf("read error!\n");
exit(1);
}

/*
---------------- 串口状态机-----------------
数据包格式
BYTE     |  BYTE   |  BYTE  |  BYTE  |   BYTE
包头         长度       命令      数据       包尾
*/
switch (g_uart_state)
{
/* 查找包头状态 */
case DATA_HEAD:
{
/* 找到包头 */
if (data == 包头)
{
/* 将包头存入指令数组 */
command_buf[g_count++] = data;
/* 改变串口状态机状态为长度 */
g_uart_state = DATA_LEN;
}
else
{
//包头匹配错误
g_count = 0;
}
break;
}
/* 检查数据长度 */
case DATA_LEN:
{
if (data == 长度)
{
//长度匹配
command_buf[g_count++] = data;
//改变状态机的状态为命令
g_uart_state = DATA_COM;
}
else
{
//长度匹配错误
g_count = 0;
//改变状态机的状态为包头
g_uart_state = DATA_HEAD;
}
break;
}
/* 检查命令是否合法 */
case DATA_COM:
{
if (data == 命令)
{
//合法存入
command_buf[g_count++] = data;
//改变状态机的状态为数据
g_uart_state = DATA_NUM;
}
else
{
//不合法改变状态机状态为包头
g_count = 0;
g_uart_state = DATA_HEAD;
}
break;
}
/* 检查数据是否合法 */
case DATA_NUM:
{
if (data是合法的数据)
{
//合法存入
command_buf[g_count++] = data;
//改变状态机的状态为包尾
g_uart_state = DATA_TAIL;
}
else
{
//不合法改变状态机状态为包头
g_count = 0;
g_uart_state = DATA_HEAD;
}
break;
}
/* 检查包尾*/
case DATA_TAIL:
{
if (data == 包尾)
{
command_buf[g_count++] = data;
//成功的解析到一个完整的符合传输协议的串口数据
}
/* 完成一次数据包的解析读取 */
g_count = 0;
g_uart_state = DATA_HEAD;
break;
}
default:
{
g_count = 0;
g_uart_state = DATA_HEAD;
memset(command_buf, '\0', sizeof(command_buf));
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息