串口发送数据处理——状态机方式

最近在写GPS接收机向PC机发送数据的程序,GPS接收机每1ms产生一个积分数据,然后由ARM把这个积分数据量化为0和1。为了提高数据发送的效率,这里没有采用每1ms发送一个数据的方式,而是采用块发送的方式,采用ARM的串口发送数据块的中断来实现每次发送8字节的数据,发送8字节后,再在缓冲区读取下一个8字节块。

积分数据量化为0和1后,仅仅需要1bit就可以存储了,在发送的时候,需要把8ms的积分数据拼接成一个字节,然后等待凑够8个字节的最低发送块大小时再发送,也就是说,每64ms才发送一次数据,一次就发送8字节。

笔者的处理方式如下:

采用状态机的方式,每1ms根据当前的状态来完成特定的任务,然后更新下一状态。

这里设计两个状态标志,一个是send_chx_data_state,用来记录8个字节中当前处理的字节状态。

另外一个是bits_count,用来记录当前处理字节中的哪一位。

所达到的效果就是,每1ms把1bit的数据放进8字节中的某一位,当达到64bit时候,进行一次块发送。

程序的代码如下:

View Code
  1 uint8 send_chx_data_state = 0;
  2 uint8 bits_count = 0;
  3 uint8 bits = 0;
  4 uint8 bits_tmp = 0;
  5 
  6 void send_chx_data(uint8 chx, uint8 task_enable)
  7 {
  8 
  9     if (task_enable)
 10     {
 11         switch (send_chx_data_state)
 12         {
 13             case 0:
 14                 bits_tmp = (chx_data[chx][1] &0x8000) >> 15;
 15                 bits = bits | (bits_tmp << (7-bits_count));
 16                 bits_count++;
 17                 if (bits_count == 8)
 18                 {
 19                     bits_count = 0;
 20                     chx_send_dat[send_chx_data_state] = bits;
 21                     bits = 0;
 22                     send_chx_data_state++;
 23                 }
 24 
 25                 break;
 26             case 1:
 27                 bits_tmp = (chx_data[chx][1] &0x8000) >> 15;
 28                 bits = bits | (bits_tmp << (7-bits_count));
 29                 bits_count++;
 30                 if (bits_count == 8)
 31                 {
 32                     bits_count = 0;
 33                     chx_send_dat[send_chx_data_state] = bits;
 34                     bits = 0;
 35                     send_chx_data_state++;
 36                 }
 37 
 38                 break;
 39             case 2:
 40                 bits_tmp = (chx_data[chx][1] &0x8000) >> 15;
 41                 bits = bits | (bits_tmp << (7-bits_count));
 42                 bits_count++;
 43                 if (bits_count == 8)
 44                 {
 45                     bits_count = 0;
 46                     chx_send_dat[send_chx_data_state] = bits;
 47                     bits = 0;
 48                     send_chx_data_state++;
 49                 }
 50 
 51                 break;
 52             case 3:
 53                 bits_tmp = (chx_data[chx][1] &0x8000) >> 15;
 54                 bits = bits | (bits_tmp << (7-bits_count));
 55                 bits_count++;
 56                 if (bits_count == 8)
 57                 {
 58                     bits_count = 0;
 59                     chx_send_dat[send_chx_data_state] = bits;
 60                     bits = 0;
 61                     send_chx_data_state++;
 62                 }
 63 
 64                 break;
 65             case 4:
 66                 bits_tmp = (chx_data[chx][1] &0x8000) >> 15;
 67                 bits = bits | (bits_tmp << (7-bits_count));
 68                 bits_count++;
 69                 if (bits_count == 8)
 70                 {
 71                     bits_count = 0;
 72                     chx_send_dat[send_chx_data_state] = bits;
 73                     bits = 0;
 74                     send_chx_data_state++;
 75                 }
 76 
 77                 break;
 78             case 5:
 79                 bits_tmp = (chx_data[chx][1] &0x8000) >> 15;
 80                 bits = bits | (bits_tmp << (7-bits_count));
 81                 bits_count++;
 82                 if (bits_count == 8)
 83                 {
 84                     bits_count = 0;
 85                     chx_send_dat[send_chx_data_state] = bits;
 86                     bits = 0;
 87                     send_chx_data_state++;
 88                 }
 89 
 90                 break;
 91             case 6:
 92                 bits_tmp = (chx_data[chx][1] &0x8000) >> 15;
 93                 bits = bits | (bits_tmp << (7-bits_count));
 94                 bits_count++;
 95                 if (bits_count == 8)
 96                 {
 97                     bits_count = 0;
 98                     chx_send_dat[send_chx_data_state] = bits;
 99                     bits = 0;
100                     send_chx_data_state++;
101                 }
102 
103                 break;
104             case 7:
105                 bits_tmp = (chx_data[chx][1] &0x8000) >> 15;
106                 bits = bits | (bits_tmp << (7-bits_count));
107                 bits_count++;
108                 if (bits_count == 8)
109                 {
110                     bits_count = 0;
111                     chx_send_dat[send_chx_data_state] = bits;
112                     uart_send_buffer(p_uart_buffer, (char*)chx_send_dat, 8);
113                     bits = 0;
114                     send_chx_data_state = 0;
115                 }
116 
117                 break;
118 
119             default:
120                 break;
121 
122         }
123     }
124     else
125     {
126         send_chx_data_state = 0;
127         bits_count = 0;
128     }
129 }

程序每1ms执行一次,每次获取GPS接收机的积分数据并取其最高位,然后把最高位按先后顺序放到一个字节中的每一位。 

总体上,代码量较大,但理解和处理起来非常简洁明了,充分发挥了状态机的优势。

下面带来一个更恐怖的,发送的是8个通道的数据,每次读取8个通道的数据并拼接成一个字节,对于每个数据位,没有采用for循环语句,而是直接展开。

当达到8个字节是,再进行发送,因此看起来代码量很恐怖,但其实执行效率是非常高的,而且每个状态中的大部分代码都是相同的。

View Code
  1 uint8 send_multi_state = 0;
  2 
  3 void send_multi_chx_data(uint8 *chx, uint8 task_enable)
  4 {
  5     uint8 chx_tmp = 0;
  6     if (task_enable)
  7     {
  8         switch (send_multi_state)
  9         {
 10             case 0:
 11                 bits_tmp = (chx_data[chx[0]][1] &0x8000) >> 15;
 12                 bits = bits | (bits_tmp << (7));
 13                 bits_tmp = (chx_data[chx[1]][1] &0x8000) >> 15;
 14                 bits = bits | (bits_tmp << (6));
 15                 bits_tmp = (chx_data[chx[2]][1] &0x8000) >> 15;
 16                 bits = bits | (bits_tmp << (5));
 17                 bits_tmp = (chx_data[chx[3]][1] &0x8000) >> 15;
 18                 bits = bits | (bits_tmp << (4));
 19                 bits_tmp = (chx_data[chx[4]][1] &0x8000) >> 15;
 20                 bits = bits | (bits_tmp << (3));
 21                 bits_tmp = (chx_data[chx[5]][1] &0x8000) >> 15;
 22                 bits = bits | (bits_tmp << (2));
 23                 bits_tmp = (chx_data[chx[6]][1] &0x8000) >> 15;
 24                 bits = bits | (bits_tmp << (1));
 25                 bits_tmp = (chx_data[chx[7]][1] &0x8000) >> 15;
 26                 bits = bits | (bits_tmp << (0));
 27 
 28                 chx_send_dat[send_multi_state] = bits;
 29                 send_multi_state++;
 30                 break;
 31             case 1:
 32                 bits_tmp = (chx_data[chx[0]][1] &0x8000) >> 15;
 33                 bits = bits | (bits_tmp << (7));
 34                 bits_tmp = (chx_data[chx[1]][1] &0x8000) >> 15;
 35                 bits = bits | (bits_tmp << (6));
 36                 bits_tmp = (chx_data[chx[2]][1] &0x8000) >> 15;
 37                 bits = bits | (bits_tmp << (5));
 38                 bits_tmp = (chx_data[chx[3]][1] &0x8000) >> 15;
 39                 bits = bits | (bits_tmp << (4));
 40                 bits_tmp = (chx_data[chx[4]][1] &0x8000) >> 15;
 41                 bits = bits | (bits_tmp << (3));
 42                 bits_tmp = (chx_data[chx[5]][1] &0x8000) >> 15;
 43                 bits = bits | (bits_tmp << (2));
 44                 bits_tmp = (chx_data[chx[6]][1] &0x8000) >> 15;
 45                 bits = bits | (bits_tmp << (1));
 46                 bits_tmp = (chx_data[chx[7]][1] &0x8000) >> 15;
 47                 bits = bits | (bits_tmp << (0));
 48 
 49                 chx_send_dat[send_multi_state] = bits;
 50                 send_multi_state++;
 51                 break;
 52             case 2:
 53                 bits_tmp = (chx_data[chx[0]][1] &0x8000) >> 15;
 54                 bits = bits | (bits_tmp << (7));
 55                 bits_tmp = (chx_data[chx[1]][1] &0x8000) >> 15;
 56                 bits = bits | (bits_tmp << (6));
 57                 bits_tmp = (chx_data[chx[2]][1] &0x8000) >> 15;
 58                 bits = bits | (bits_tmp << (5));
 59                 bits_tmp = (chx_data[chx[3]][1] &0x8000) >> 15;
 60                 bits = bits | (bits_tmp << (4));
 61                 bits_tmp = (chx_data[chx[4]][1] &0x8000) >> 15;
 62                 bits = bits | (bits_tmp << (3));
 63                 bits_tmp = (chx_data[chx[5]][1] &0x8000) >> 15;
 64                 bits = bits | (bits_tmp << (2));
 65                 bits_tmp = (chx_data[chx[6]][1] &0x8000) >> 15;
 66                 bits = bits | (bits_tmp << (1));
 67                 bits_tmp = (chx_data[chx[7]][1] &0x8000) >> 15;
 68                 bits = bits | (bits_tmp << (0));
 69 
 70                 chx_send_dat[send_multi_state] = bits;
 71                 send_multi_state++;
 72                 break;
 73             case 3:
 74                 bits_tmp = (chx_data[chx[0]][1] &0x8000) >> 15;
 75                 bits = bits | (bits_tmp << (7));
 76                 bits_tmp = (chx_data[chx[1]][1] &0x8000) >> 15;
 77                 bits = bits | (bits_tmp << (6));
 78                 bits_tmp = (chx_data[chx[2]][1] &0x8000) >> 15;
 79                 bits = bits | (bits_tmp << (5));
 80                 bits_tmp = (chx_data[chx[3]][1] &0x8000) >> 15;
 81                 bits = bits | (bits_tmp << (4));
 82                 bits_tmp = (chx_data[chx[4]][1] &0x8000) >> 15;
 83                 bits = bits | (bits_tmp << (3));
 84                 bits_tmp = (chx_data[chx[5]][1] &0x8000) >> 15;
 85                 bits = bits | (bits_tmp << (2));
 86                 bits_tmp = (chx_data[chx[6]][1] &0x8000) >> 15;
 87                 bits = bits | (bits_tmp << (1));
 88                 bits_tmp = (chx_data[chx[7]][1] &0x8000) >> 15;
 89                 bits = bits | (bits_tmp << (0));
 90 
 91                 chx_send_dat[send_multi_state] = bits;
 92                 send_multi_state++;
 93 
 94                 break;
 95               case 4:
 96                 bits_tmp = (chx_data[chx[0]][1] &0x8000) >> 15;
 97                 bits = bits | (bits_tmp << (7));
 98                 bits_tmp = (chx_data[chx[1]][1] &0x8000) >> 15;
 99                 bits = bits | (bits_tmp << (6));
100                 bits_tmp = (chx_data[chx[2]][1] &0x8000) >> 15;
101                 bits = bits | (bits_tmp << (5));
102                 bits_tmp = (chx_data[chx[3]][1] &0x8000) >> 15;
103                 bits = bits | (bits_tmp << (4));
104                 bits_tmp = (chx_data[chx[4]][1] &0x8000) >> 15;
105                 bits = bits | (bits_tmp << (3));
106                 bits_tmp = (chx_data[chx[5]][1] &0x8000) >> 15;
107                 bits = bits | (bits_tmp << (2));
108                 bits_tmp = (chx_data[chx[6]][1] &0x8000) >> 15;
109                 bits = bits | (bits_tmp << (1));
110                 bits_tmp = (chx_data[chx[7]][1] &0x8000) >> 15;
111                 bits = bits | (bits_tmp << (0));
112 
113                 chx_send_dat[send_multi_state] = bits;
114                 send_multi_state++;
115                 break;
116             case 5:
117                 bits_tmp = (chx_data[chx[0]][1] &0x8000) >> 15;
118                 bits = bits | (bits_tmp << (7));
119                 bits_tmp = (chx_data[chx[1]][1] &0x8000) >> 15;
120                 bits = bits | (bits_tmp << (6));
121                 bits_tmp = (chx_data[chx[2]][1] &0x8000) >> 15;
122                 bits = bits | (bits_tmp << (5));
123                 bits_tmp = (chx_data[chx[3]][1] &0x8000) >> 15;
124                 bits = bits | (bits_tmp << (4));
125                 bits_tmp = (chx_data[chx[4]][1] &0x8000) >> 15;
126                 bits = bits | (bits_tmp << (3));
127                 bits_tmp = (chx_data[chx[5]][1] &0x8000) >> 15;
128                 bits = bits | (bits_tmp << (2));
129                 bits_tmp = (chx_data[chx[6]][1] &0x8000) >> 15;
130                 bits = bits | (bits_tmp << (1));
131                 bits_tmp = (chx_data[chx[7]][1] &0x8000) >> 15;
132                 bits = bits | (bits_tmp << (0));
133 
134                 chx_send_dat[send_multi_state] = bits;
135                 send_multi_state++;
136                 break;
137             case 6:
138                 bits_tmp = (chx_data[chx[0]][1] &0x8000) >> 15;
139                 bits = bits | (bits_tmp << (7));
140                 bits_tmp = (chx_data[chx[1]][1] &0x8000) >> 15;
141                 bits = bits | (bits_tmp << (6));
142                 bits_tmp = (chx_data[chx[2]][1] &0x8000) >> 15;
143                 bits = bits | (bits_tmp << (5));
144                 bits_tmp = (chx_data[chx[3]][1] &0x8000) >> 15;
145                 bits = bits | (bits_tmp << (4));
146                 bits_tmp = (chx_data[chx[4]][1] &0x8000) >> 15;
147                 bits = bits | (bits_tmp << (3));
148                 bits_tmp = (chx_data[chx[5]][1] &0x8000) >> 15;
149                 bits = bits | (bits_tmp << (2));
150                 bits_tmp = (chx_data[chx[6]][1] &0x8000) >> 15;
151                 bits = bits | (bits_tmp << (1));
152                 bits_tmp = (chx_data[chx[7]][1] &0x8000) >> 15;
153                 bits = bits | (bits_tmp << (0));
154 
155                 chx_send_dat[send_multi_state] = bits;
156                 send_multi_state++;
157                 break;
158             case 7:
159                 bits_tmp = (chx_data[chx[0]][1] &0x8000) >> 15;
160                 bits = bits | (bits_tmp << (7));
161                 bits_tmp = (chx_data[chx[1]][1] &0x8000) >> 15;
162                 bits = bits | (bits_tmp << (6));
163                 bits_tmp = (chx_data[chx[2]][1] &0x8000) >> 15;
164                 bits = bits | (bits_tmp << (5));
165                 bits_tmp = (chx_data[chx[3]][1] &0x8000) >> 15;
166                 bits = bits | (bits_tmp << (4));
167                 bits_tmp = (chx_data[chx[4]][1] &0x8000) >> 15;
168                 bits = bits | (bits_tmp << (3));
169                 bits_tmp = (chx_data[chx[5]][1] &0x8000) >> 15;
170                 bits = bits | (bits_tmp << (2));
171                 bits_tmp = (chx_data[chx[6]][1] &0x8000) >> 15;
172                 bits = bits | (bits_tmp << (1));
173                 bits_tmp = (chx_data[chx[7]][1] &0x8000) >> 15;
174                 bits = bits | (bits_tmp << (0));
175 
176                 chx_send_dat[send_multi_state] = bits;
177 
178                 uart_send_buffer(p_uart_buffer, (char*)chx_send_dat, 8);
179                 send_multi_state = 0;
180                 break;
181             default:
182                 break;
183 
184         }
185     }
186     else
187     {
188         send_multi_state = 0;
189     }
190 }
原文地址:https://www.cnblogs.com/xiangtailiang/p/2693877.html