最近在写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时候,进行一次块发送。
程序的代码如下:
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 else125 {126 send_chx_data_state = 0;127 bits_count = 0;128 }129 }
程序每1ms执行一次,每次获取GPS接收机的积分数据并取其最高位,然后把最高位按先后顺序放到一个字节中的每一位。
总体上,代码量较大,但理解和处理起来非常简洁明了,充分发挥了状态机的优势。
下面带来一个更恐怖的,发送的是8个通道的数据,每次读取8个通道的数据并拼接成一个字节,对于每个数据位,没有采用for循环语句,而是直接展开。
当达到8个字节是,再进行发送,因此看起来代码量很恐怖,但其实执行效率是非常高的,而且每个状态中的大部分代码都是相同的。
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 else187 {188 send_multi_state = 0;189 }190 }