1、什么是韦根信号
韦根信号是两根数据线传输二进制数据,在空闲时端,两线的对0V的电源都为TTL电平的水平,也就是5V,一般通过5K电阻上拉,当有数据传输时,两根线交替地发送400uS低脉冲,当Data0线发脉冲时,数据是0;当Data1发脉冲时,发送的数据是1,不能两根线同时发脉冲。脉冲的间隔时间是1mS。
韦根的数据格式一般是由三部分组成:校验位、出厂码和数据位。不同的韦根格式有不同的组成。如26Bit格式,其第一位和第二十六位是校验位,2-9位是厂家码,10-25位是卡号位。
2、什么是韦根协议
Wiegand协议是国际上统一的标准,是由摩托罗拉公司制定的一种通讯协议,适用于门禁控制系统的读卡器和卡片的许多特性。
Wiegand协议很多格式,最常用的格式是26bit,即韦根26,此外还有34bit、32bit、36bit、37bit、42bit、44bit等格式。标准26-bit 格式是一个开放式的格式,他是广泛使用的工业标准,几乎所有的门禁控制系统都接受标准的26-Bit格式。
Wiegand协议并没有定义通讯的波特率、也没有定义数据长度,韦根格式主要定义数据传输方式:Data0和Data1两根数据线分别传输二进制数据0和二进制数据1。
3、标准Wiegand协议
Wiegand 26格式:
![20191022111812599.png](20191022111812599.png)
各数据位的含义:
第 1 位: 为输出数据2—13位的偶校验位
第 2 - 9 位: ID卡的HID码的低8位
第10 - 25位: ID卡的PID号码
第 26 位: 为输出数据14-25位的奇校验位
检验位1为偶校验位:对于WG26来说,如果前2-13位有偶数个1,那么检验位1=0,反之为1
检验位2为奇校验位:对于WG26来说,如果后14-25位有奇数个1,那么检验位2=0,反之为1
数据输出顺序:
HID码和PID码均为高位在前,低位在后
例:一张ID卡内容为:
HID:32769 PID:34953 ( 卡面印:2147584137 001, 34953 )
相应的二进制为:
HID:1000 0000 0000 0001 ( 只输出低8位 )
PID:1000 1000 1000 1001
输出如下:
0 0 0 0 0 0 0 0 1 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 1 1
偶校验 |
HID |
PID |
奇校验 |
0 |
0 0 0 0 0 0 0 1 |
1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 1 |
1 |
Wiegand 34格式:
![20191022113152698.png](20191022113152698.png)
各数据位的含义:
第 1 位: 为输出第2—17位的偶校验位
第 2-17 位: ID卡的HID码
第18-33位: ID卡的PID号码
第 34 位: 为输出第18-33位的奇校验位
检验位1为偶校验位:对于WG34来说,如果前16位有偶数个1,那么检验位1=0,反之为1
检验位2为奇校验位:对于WG34来说,如果前16位有奇数个1,那么检验位2=0,反之为1
数据输出顺序:
HID码和PID码均为高位在前,低位在后
例:一张ID卡内容为:
HID:32769 PID:34953 ( 卡面印:2147584137 001, 34953 )
相应的二进制为:
HID:1000 0000 0000 0001
PID:1000 1000 1000 1001
输出如下:
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 1 0
偶校验 |
HID |
PID |
奇校验 |
0 |
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 |
1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 1 |
0 |
4、韦根数据接收
韦根的接收对时间的实时性要求比较高,如果用查询的方法接收会出现丢帧的现象:假设查询到 DATA0为 0 时主程序正在指向其他任务,等主程序执行完该任务时 DATA0 已经变为 1 了,那么这样就导致了一个 0 bit 丢了,这样读出的卡号肯定奇偶校验通不过,所以表现出 CPU 接收不到 ID 模块发送的卡号了。
唯一的办法是在外部中断里接收每个 bit。 (仅仅在中断里获得开始接收 wiegand 数据还不行,因为这是尽管给开始接收 wiegand数据标志位置位了,但是主程序还在执行其他代码而没有到达查询开始接收 wiegand 数据标志位这条指令)。
韦根连续发送两张卡的电平最小时间间隔T为0.25s,因此如果要连续接收多张电子卡数据时,可判断脉冲间隔T是否大于240ms,以此判断前一张卡片数据是否已经接收完成,韦根的接收程序一般是用中断方式完成,然后使用定时器进行计数以判断是否接受完一帧数据。
下图所示为,韦根时序图。
![20190215134104563.png](20190215134104563.png)
5、韦根接口定义
Wiegand接口由三条导线组成:
DATA0——简称D0,韦根信号0,通常使用线的颜色为:绿色/兰色。
DATA1——简称D1,韦根信号1,通常使用线的颜色:白色。
Data return(GND)——韦根信号地,通常为黑色。
D0,D1在没有数据输出时都保持+5V高电平;若输出为0,则D0拉低一段时间(负脉冲);若输出为1,则D1拉低一段时间(负脉冲)。
D0,D1不能两根线同时发脉冲,脉冲的间隔时间是1ms。
输出‘0’时:DATA0 线上出现负脉冲;
输出‘1’时:DATA1 线上出现负脉冲;
负脉冲宽度 TP=100~200 微秒;周期 TW=1000~3000 微秒
6、韦根信号线建议使用线缆
韦根信号线除了必须使用的三条导线:D0、D1、GND外,通常还需考虑韦根设备供电:Vcc(一般为红色线)。
此外可能还需要传输 LED、蜂鸣器等信号。
所以韦根信号线至少需要使用4芯电缆,最多需使用6芯电缆,一般情况下建议使用5芯电缆就可以了。
建议使用线缆型号:
最低4芯:RVVP4*0.5成束全屏蔽电缆(平行非双绞)
扩展4+1芯:RVVP5*0.5成束全屏蔽电缆(平行非双绞)
扩展4+2芯:RVVP6*0.5成束全屏蔽电缆(平行非双绞)
![RVV6_0](20170924164381568156.jpg)
7、韦根信号线传输距离
为保障韦根传输距离,建议使用标准线缆,韦根信号线传输距离一般在150 米左右,考虑到设备、线缆、现场环境等因素,建议敷设线缆长度控制在80米以下。
8、参考程序
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
|
void delay_100us(void) { TR0 = 0; TH0 = (65536 - 78)/256; TL0 = (65536 - 78)%256; TF0 = 0; ET0 = 0; TR0 = 1; while (!TF0) { ;} } void delay_1500us(void) { TR0 = 0; TH0 = (65536 - 1382)/256; TL0 = (65536 - 1382)%256; TF0 = 0; ET0 = 0; TR0 = 1; while (!TF0) { ;} } void WG_send_bit_1(void) { WG_DATA1 = 0; delay_100us(); WG_DATA1 = 1; delay_1500us(); } void WG_send_bit_0(void) { WG_DATA0 = 0; delay_100us(); WG_DATA0 = 1; delay_1500us(); } void send_wiegand26(uchar *str) { uchar data i; uchar data check_temp; bit data even; bit data odd; uchar data wiegand[3]; P3M0 = 0x00; P3M1 = 0x00; wiegand[0] = wiegand[0]|((*str)<<4); wiegand[0] = wiegand[0]|(*(str+1)&0x0f); wiegand[1] = wiegand[1]|(*(str+2)<<4); wiegand[1] = wiegand[1]|(*(str+3)&0x0f) wiegand[2] = wiegand[2]|(*(str+4)<<4); wiegand[2] = wiegand[2]|(*(str+5)&0x0f); check_temp = wiegand[1]&0xf0; check_temp ^= wiegand[0]; check_temp ^= check_temp>>4; check_temp ^= check_temp>>2; check_temp ^= check_temp>>1; even=!(check_temp&1); check_temp = wiegand[1]&0x0f; check_temp ^= wiegand[2]; check_temp ^= check_temp>>4; check_temp ^= check_temp>>2; check_temp ^= check_temp>>1; odd=check_temp&1; WG_DATA0 = 1; WG_DATA1 = 1; if(even) { WG_send_bit_1(); } else { WG_send_bit_0(); } for(i = 0;i<24;i++) { if((wiegand[0])&0x80) { WG_send_bit_1(); } else { WG_send_bit_0(); } (*(long*)&wiegand[0]) <<= 1; } if(odd) { WG_send_bit_1(); } else { WG_send_bit_0(); } }
|
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 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
|
void send_wiegand26(uchar * str) { uchar data i; static uchar data one_num; uchar data check_temp; bit data even; bit data odd; static uchar data wiegand[3]; P3M0 = 0x00; P3M1 = 0x00; wiegand[0] = wiegand[0] | (( * str) << 4); wiegand[0] = wiegand[0] | ( * (str + 1) & 0x0f); check_temp = wiegand[0]; for (i = 0; i < 8; i++) { if (check_temp & 0x01) { one_num++; } check_temp >>= 1; } wiegand[1] = wiegand[1] | ( * (str + 2) << 4); check_temp = wiegand[1]; for (i = 0; i < 4; i++) { if (check_temp & 0x80) { one_num++; } check_temp <<= 1; } one_num % 2 == 0 ? (even = 0) : (even = 1); one_num = 0;
wiegand[1] = wiegand[1] | ( * (str + 3) & 0x0f); check_temp = wiegand[1]; for (i = 0; i < 4; i++) { if (check_temp & 0x01) { one_num++; } check_temp >>= 1; } wiegand[2] = wiegand[2] | ( * (str + 4) << 4); wiegand[2] = wiegand[2] | ( * (str + 5) & 0x0f); check_temp = wiegand[2]; for (i = 0; i < 8; i++) { if (check_temp & 0x01) { one_num++; } check_temp >>= 1; } one_num % 2 == 0 ? (odd = 1) : (odd = 0); one_num = 0;
WG_DATA0 = 1; WG_DATA1 = 1; if (even) { WG_DATA1 = 0;
TR0 = 0; TH0 = (65536 - 78) / 256; TL0 = (65536 - 78) % 256; TF0 = 0; ET0 = 0; TR0 = 1; while (!TF0) {; }
TF0 = 0; WG_DATA1 = 1; } else { WG_DATA0 = 0; TR0 = 0; TH0 = (65536 - 78) / 256; TL0 = (65536 - 78) % 256; TF0 = 0; ET0 = 0; TR0 = 1; while (!TF0) {; }
TF0 = 0; WG_DATA0 = 1; } TR0 = 0; TH0 = (65536 - 1382) / 256; TL0 = (65536 - 1382) % 256; TF0 = 0; ET0 = 0; TR0 = 1; while (!TF0) {; }
TF0 = 0; for (i = 0; i < 24; i++) { WG_DATA0 = 1; WG_DATA1 = 1; if ((wiegand[0]) & 0x80) { WG_DATA1 = 0;
TR0 = 0; TH0 = (65536 - 78) / 256; TL0 = (65536 - 78) % 256; TF0 = 0; ET0 = 0; TR0 = 1;
while (!TF0) {; } TF0 = 0; WG_DATA1 = 1; } else { WG_DATA0 = 0; TR0 = 0; TH0 = (65536 - 78) / 256; TL0 = (65536 - 78) % 256; TF0 = 0; ET0 = 0; TR0 = 1; while (!TF0) {; } TF0 = 0; WG_DATA0 = 1; } ( * (long * ) & wiegand[0]) <<= 1; TR0 = 0; TH0 = (65536 - 1382) / 256; TL0 = (65536 - 1382) % 256; TF0 = 0; ET0 = 0; TR0 = 1; while (!TF0) {; } TF0 = 0; } WG_DATA0 = 1; WG_DATA1 = 1;
if (odd) { WG_DATA1 = 0;
TR0 = 0; TH0 = (65536 - 78) / 256; TL0 = (65536 - 78) % 256; TF0 = 0; ET0 = 0; TR0 = 1; while (!TF0) {; } TF0 = 0; WG_DATA1 = 1; } else { WG_DATA0 = 0; TR0 = 0; TH0 = (65536 - 78) / 256; TL0 = (65536 - 78) % 256; TF0 = 0; ET0 = 0; TR0 = 1; while (!TF0) {; } TF0 = 0; WG_DATA0 = 1; } }
|
以下为韦根26和韦根34发送代码:
wiegand.h文件
1 2 3 4 5 6 7 8 9 10 11
| #define WG_DATA0(x) {if(0==(x)) HAL_GPIO_WritePin(WGD0_GPIO_Port, WGD0_Pin,GPIO_PIN_RESET); else HAL_GPIO_WritePin(WGD0_GPIO_Port, WGD0_Pin,GPIO_PIN_SET);} #define WG_DATA1(x) {if(0==(x)) HAL_GPIO_WritePin(WGD1_GPIO_Port, WGD1_Pin,GPIO_PIN_RESET); else HAL_GPIO_WritePin(WGD1_GPIO_Port, WGD1_Pin,GPIO_PIN_SET);}
typedef struct { INT8U ucRxRingBuffer[WG_RX_BUFFERSIZE]; INT16U usReadPos; INT16U usWritePos; INT8S usFrameCount; }WieGand_MSG_ST;
|
wiegand.c
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 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225
| int WG_Send26(unsigned char *str) { unsigned char one_num = 0; unsigned char even = 0; unsigned char odd = 0; unsigned char check_temp,i;
if(NULL == str) return -1; check_temp = *str; for(i = 0;i < 8;i++) { if(check_temp & 0x01) one_num++; check_temp >>= 1; } check_temp = *(str + 1); for(i = 0;i < 4;i++) { if(check_temp & 0x80) one_num++; check_temp <<= 1; } if((one_num % 2 )==0) even = 0; else even = 1;
one_num = 0; check_temp = *(str + 1); for(i = 0;i < 4;i++) { if(check_temp & 0x01) one_num++; check_temp >>= 1; } check_temp = *(str + 2); for(i = 0;i < 8;i++) { if(check_temp & 0x01) one_num++; check_temp >>= 1; } if((one_num % 2 )==1) odd = 0; else odd = 1; WG_DATA0(1); WG_DATA1(1); HAL_Delay(5); if(even) { WG_DATA1(0); myDelay_us(300); WG_DATA1(1); } else { WG_DATA0(0); myDelay_us(300); WG_DATA0(1); } HAL_Delay(2); for(i = 0;i < 24;i++) { WG_DATA0(1); WG_DATA1(1); if(str[0] & 0x80) { WG_DATA1(0); myDelay_us(300); WG_DATA1(1); } else { WG_DATA0(0); myDelay_us(300); WG_DATA0(1); } (*(long*)&str[0]) <<= 1; HAL_Delay(2); } WG_DATA0(1); WG_DATA1(1); if(odd) { WG_DATA1(0); myDelay_us(300); WG_DATA1(1); } else { WG_DATA0(0); myDelay_us(300); WG_DATA0(1); } WG_DATA0(1); WG_DATA1(1); return 0; }
int WG_Send34(unsigned char *str) { unsigned char one_num = 0; unsigned char even = 0; unsigned char odd = 0; unsigned char check_temp,i;
if(NULL == str) return -1; check_temp = *str; for(i = 0;i < 8;i++) { if(check_temp & 0x01) one_num++; check_temp >>= 1; } check_temp = *(str + 1); for(i = 0;i < 8;i++) { if(check_temp & 0x01) one_num++; check_temp >>= 1; } if((one_num % 2 )==0) even = 0; else even = 1; one_num = 0; check_temp = *(str + 2); for(i = 0;i < 8;i++) { if(check_temp & 0x01) one_num++; check_temp >>= 1; } check_temp = *(str + 3); for(i = 0;i < 8;i++) { if(check_temp & 0x01) one_num++; check_temp >>= 1; } if((one_num % 2 )==1) odd = 0; else odd = 1; WG_DATA0(1); WG_DATA1(1); HAL_Delay(5); if(even) { WG_DATA1(0); myDelay_us(300); WG_DATA1(1); } else { WG_DATA0(0); myDelay_us(300); WG_DATA0(1); } HAL_Delay(2); for(i = 0;i < 32;i++) { WG_DATA0(1); WG_DATA1(1); if(str[0] & 0x80) { WG_DATA1(0); myDelay_us(300); WG_DATA1(1); } else { WG_DATA0(0); myDelay_us(300); WG_DATA0(1); } (*(long*)&str[0]) <<= 1; HAL_Delay(2); } WG_DATA0(1); WG_DATA1(1); if(odd) { WG_DATA1(0); myDelay_us(300); WG_DATA1(1); } else { WG_DATA0(0); myDelay_us(300); WG_DATA0(1); } WG_DATA0(1); WG_DATA1(1); return 0; }
|
在韦根信号接收方面,我使用了一个循环缓冲数组进行接收,在接收代码编写过程中,之前有一个疑问是,似乎采用中断接收时,是不用判断脉冲宽度的,然后只增加了对于一帧数据是否接收完的超时判断,这个超时计数是通过定时器做的,判断是否大于240ms还没有接收到脉冲,如果超过,则认为一帧接收完成了。
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 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
| WieGand_MSG_ST stWG_Receive; INT8U u_DataBits = 0; INT16S us_FirstBitPos = 0; extern TIMER_WG_ST st_Timer_WG;
void WG_Receive(unsigned char dataLineType) { if(WG_DATA0_LINE == dataLineType) { if (st_Timer_WG.usTIM_WgRxTimeCount == 0xffff) { u_DataBits = 0; st_Timer_WG.usTIM_WgRxTimeCount = 0; us_FirstBitPos = stWG_Receive.usWritePos; stWG_Receive.usWritePos++; if(stWG_Receive.usWritePos == WG_RX_BUFFERSIZE) { stWG_Receive.usWritePos = 0; } if(stWG_Receive.usWritePos == stWG_Receive.usReadPos) { if(stWG_Receive.ucRxRingBuffer[stWG_Receive.usReadPos] != WG_TYPE26 || stWG_Receive.ucRxRingBuffer[stWG_Receive.usReadPos] != WG_TYPE34) { stWG_Receive.usReadPos++; if(stWG_Receive.usReadPos == WG_RX_BUFFERSIZE) { stWG_Receive.usReadPos = 0; } } else { if((WG_RX_BUFFERSIZE - stWG_Receive.usReadPos)> (stWG_Receive.ucRxRingBuffer[stWG_Receive.usReadPos]+1)) { stWG_Receive.usReadPos +=stWG_Receive.ucRxRingBuffer[stWG_Receive.usReadPos] +1; } else { stWG_Receive.usReadPos = (stWG_Receive.ucRxRingBuffer[stWG_Receive.usReadPos]+1) - (WG_RX_BUFFERSIZE - stWG_Receive.usReadPos); } if(stWG_Receive.usFrameCount > 0) stWG_Receive.usFrameCount--; } } stWG_Receive.ucRxRingBuffer[stWG_Receive.usWritePos] = 0; stWG_Receive.usWritePos++; if(stWG_Receive.usWritePos == WG_RX_BUFFERSIZE) { stWG_Receive.usWritePos = 0; } } else { if(stWG_Receive.usWritePos == stWG_Receive.usReadPos) { if(stWG_Receive.ucRxRingBuffer[stWG_Receive.usReadPos] != WG_TYPE26 || stWG_Receive.ucRxRingBuffer[stWG_Receive.usReadPos] != WG_TYPE34) { stWG_Receive.usReadPos++; } else { if((WG_RX_BUFFERSIZE - stWG_Receive.usReadPos)> stWG_Receive.ucRxRingBuffer[stWG_Receive.usReadPos]+1) stWG_Receive.usReadPos +=stWG_Receive.ucRxRingBuffer[stWG_Receive.usReadPos] +1; else { stWG_Receive.usReadPos = (WG_RX_BUFFERSIZE - stWG_Receive.usReadPos) +1; } if(stWG_Receive.usFrameCount > 0) stWG_Receive.usFrameCount--; } } stWG_Receive.ucRxRingBuffer[stWG_Receive.usWritePos] = 0; stWG_Receive.usWritePos++; if(stWG_Receive.usWritePos == WG_RX_BUFFERSIZE) { stWG_Receive.usWritePos = 0; } } u_DataBits++; st_Timer_WG.usTIM_WgRxTimeCount = 0; stWG_Receive.ucRxRingBuffer[us_FirstBitPos] = u_DataBits; } else if(WG_DATA1_LINE == dataLineType) { if (st_Timer_WG.usTIM_WgRxTimeCount == 0xffff) { u_DataBits = 0; st_Timer_WG.usTIM_WgRxTimeCount = 0; us_FirstBitPos = stWG_Receive.usWritePos; stWG_Receive.usWritePos++; if(stWG_Receive.usWritePos == WG_RX_BUFFERSIZE) { stWG_Receive.usWritePos = 0; } if(stWG_Receive.usWritePos == stWG_Receive.usReadPos) { if(stWG_Receive.ucRxRingBuffer[stWG_Receive.usReadPos] != WG_TYPE26 || stWG_Receive.ucRxRingBuffer[stWG_Receive.usReadPos] != WG_TYPE34) { stWG_Receive.usReadPos++; if(stWG_Receive.usReadPos == WG_RX_BUFFERSIZE) { stWG_Receive.usReadPos = 0; } } else { if((WG_RX_BUFFERSIZE - stWG_Receive.usReadPos)> (stWG_Receive.ucRxRingBuffer[stWG_Receive.usReadPos]+1)) { stWG_Receive.usReadPos +=stWG_Receive.ucRxRingBuffer[stWG_Receive.usReadPos] +1; } else { stWG_Receive.usReadPos = (stWG_Receive.ucRxRingBuffer[stWG_Receive.usReadPos]+1) - (WG_RX_BUFFERSIZE - stWG_Receive.usReadPos); } if(stWG_Receive.usFrameCount > 0) stWG_Receive.usFrameCount--; } } stWG_Receive.ucRxRingBuffer[stWG_Receive.usWritePos] = 1; stWG_Receive.usWritePos++; if(stWG_Receive.usWritePos == WG_RX_BUFFERSIZE) { stWG_Receive.usWritePos = 0; } } else { if(stWG_Receive.usWritePos == stWG_Receive.usReadPos) { if(stWG_Receive.ucRxRingBuffer[stWG_Receive.usReadPos] != WG_TYPE26|| stWG_Receive.ucRxRingBuffer[stWG_Receive.usReadPos] != WG_TYPE34) { stWG_Receive.usReadPos++; } else { if((WG_RX_BUFFERSIZE - stWG_Receive.usReadPos)> stWG_Receive.ucRxRingBuffer[stWG_Receive.usReadPos]+1) stWG_Receive.usReadPos +=stWG_Receive.ucRxRingBuffer[stWG_Receive.usReadPos] +1; else { stWG_Receive.usReadPos = (WG_RX_BUFFERSIZE - stWG_Receive.usReadPos) +1; } if(stWG_Receive.usFrameCount > 0) stWG_Receive.usFrameCount--; } } stWG_Receive.ucRxRingBuffer[stWG_Receive.usWritePos] = 1; stWG_Receive.usWritePos++; if(stWG_Receive.usWritePos == WG_RX_BUFFERSIZE) { stWG_Receive.usWritePos = 0; } } u_DataBits++; st_Timer_WG.usTIM_WgRxTimeCount = 0; stWG_Receive.ucRxRingBuffer[us_FirstBitPos] = u_DataBits; } }
|
定时器计时代码timer.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| typedef struct { INT16U usTIM_WgRxTimeCount; }TIMER_WG_ST;
TIMER_WG_ST st_Timer_WG;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if (htim->Instance == htim3.Instance) { if(st_Timer_WG.usTIM_WgRxTimeCount != 0xffff) { st_Timer_WG.usTIM_WgRxTimeCount++; if(st_Timer_WG.usTIM_WgRxTimeCount == WG_RXTIMEOUT) { st_Timer_WG.usTIM_WgRxTimeCount = 0xffff; stWG_Receive.usFrameCount++; } } } }
|