STM32模拟串口驱动(带校验位)
[toc]
# 背景
- 年前一个项目中,由于串口的资源紧张,硬件使用的是主MCU-STM32F030C8T6,其两个硬件串口都被使用了,而另外一个器件间的通信也需要串口通信,故不得不采用模拟串口的方式,该器件的通信要求是:4800bps ,8,E,1。
对,是采用偶校验的方式。之前一直习惯无校验方式,一下子说要采用偶校验,所以不得不深度查阅和了解串口的相关信息。
- 以下即是所了解的 校验位信息的解读说明:
- 设置为奇校验,先看发送方将要发送的一帧数据中有几个1,如果是偶数个1则校验位置1,保证1的个数是奇数。如果是奇数就置0。
- 设置为偶校验,先看发送方将要发送的一帧数据中有几个1,如果是奇数个1则校验位置1,如果是偶数就置0。保证1的个数是偶数。
- 若当前校验位电平为0且校验接收"1"的个数为偶数个,则通过偶校验(即满足1的个数为偶数个)
- 若当前校验位电平为1且校验接收"1"的个数为奇数个,则通过偶校验
- 若当前校验位电平为1且校验接收"1"的个数为偶数个,则通过奇校验(即满足1的个数为奇数个)
若当前校验位电平为0且校验接收"1"的个数为奇数个,则通过奇校验
了解完这些信息之后,就开始写驱动框架:整个采用 外部中断 + 定时器来接收处理数据
外部中断: 用来处理数据bit位的状态定时器: 用来处理bit数据接收合成一个字节数据
/*模拟串口逻辑实现框架*/
typedef enum
{
VUART1=0,
VUART2,
}vuart_em;
//函数指针
typedef unsigned char(*byte_read)(vuart_em);
typedef void(*vuart_bsp)(vuart_em);
typedef void(*vuart_start)(vuart_em,FunctionalState);
typedef void(*data_timer)(FunctionalState);
/*
偶校验:就是发送的8个数据位的1的个数为偶数时,TB8=0;为奇数时,TB8=1;
奇校验:与偶校验相反的TB8。
*/
typedef enum
{
STATE_START=0, /* startbit*/
STATE_BIT0,
STATE_BIT1,
STATE_BIT2,
STATE_BIT3,
STATE_BIT4,
STATE_BIT5,
STATE_BIT6,
STATE_BIT7,
STATE_BITC,/*校验位*/
STATE_STOP /* stopbit*/
}rxsta_em;//数据枚举状态位
typedef enum
{
NONE=0,//无
ODD, //奇校验
EVEN,//偶校验
}chk_em;//校验选择枚举
typedef struct
{
unsigned short int baud; //波特率
chk_em chk_type;//校验类型
}config_st; //串口信息配置结构体
typedef struct
{
unsigned char byte_cont; //数据'1'的个数
unsigned char byte_value; //一字节数据
unsigned char byte_chkok; //数据校验成功标志
}gdata_st;//帧数据结构体
typedef struct
{
rxsta_em state; //
}bit_rx_st;//数据位结构体
typedef struct
{
bit_rx_st bit_rx;
gdata_st data;
config_st config;
data_timer bit_timer;
byte_read byte_get; //数据接收
vuart_bsp hw_init; //硬件端口初始化
vuart_start open;
}vuart_st;//虚拟串口信息结构体
#define VUART1_MAX_SIZE (32) //虚拟串口最大接收缓存字节数
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
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
/*模拟串口逻辑实现框架*/
typedef enum
{
VUART1=0,
VUART2,
}vuart_em;
//函数指针
typedef unsigned char(*byte_read)(vuart_em);
typedef void(*vuart_bsp)(vuart_em);
typedef void(*vuart_start)(vuart_em,FunctionalState);
typedef void(*data_timer)(FunctionalState);
/*
偶校验:就是发送的8个数据位的1的个数为偶数时,TB8=0;为奇数时,TB8=1;
奇校验:与偶校验相反的TB8。
*/
typedef enum
{
STATE_START=0, /* startbit*/
STATE_BIT0,
STATE_BIT1,
STATE_BIT2,
STATE_BIT3,
STATE_BIT4,
STATE_BIT5,
STATE_BIT6,
STATE_BIT7,
STATE_BITC,/*校验位*/
STATE_STOP /* stopbit*/
}rxsta_em;//数据枚举状态位
typedef enum
{
NONE=0,//无
ODD, //奇校验
EVEN,//偶校验
}chk_em;//校验选择枚举
typedef struct
{
unsigned short int baud; //波特率
chk_em chk_type;//校验类型
}config_st; //串口信息配置结构体
typedef struct
{
unsigned char byte_cont; //数据'1'的个数
unsigned char byte_value; //一字节数据
unsigned char byte_chkok; //数据校验成功标志
}gdata_st;//帧数据结构体
typedef struct
{
rxsta_em state; //
}bit_rx_st;//数据位结构体
typedef struct
{
bit_rx_st bit_rx;
gdata_st data;
config_st config;
data_timer bit_timer;
byte_read byte_get; //数据接收
vuart_bsp hw_init; //硬件端口初始化
vuart_start open;
}vuart_st;//虚拟串口信息结构体
#define VUART1_MAX_SIZE (32) //虚拟串口最大接收缓存字节数
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
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
POWER MONITOR///
#define PWR_MONITOR_PCC RCC_AHBPeriph_GPIOC
#define PWR_MONITOR_PORT GPIOC
#define PWR_MONITOR1_PIN GPIO_Pin_13
#define PWR_MONITOR2_PIN GPIO_Pin_14
#define PWR_MONITOR_EXT_PSP EXTI_PortSourceGPIOC
#define PWR_MONITOR1_EXT_PS EXTI_PinSource13
#define PWR_MONITOR1_EXT_LINE EXTI_Line13
#define PWR_MONITOR2_EXT_PS EXTI_PinSource14
#define PWR_MONITOR2_EXT_LINE EXTI_Line14
#define PWR_MONITOR_EXT_IRQ EXTI4_15_IRQn
#define PWR_MONITOR1_GET() GPIO_ReadInputDataBit(PWR_MONITOR_PORT,PWR_MONITOR1_PIN)
#define PWR_MONITOR2_GET() GPIO_ReadInputDataBit(PWR_MONITOR_PORT,PWR_MONITOR2_PIN)
//------------------------虚拟串口驱动----------------
unsigned char VUART1_RX_SIZE=0;
unsigned char VUART1_RX_BUF[VUART1_MAX_SIZE]={0};
vuart_st vuart1,vuart2;
/*
**虚拟串口1的GPIO配置
*/
void vuart1_bsp_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_AHBPeriphClockCmd(PWR_MONITOR_PCC, ENABLE);
GPIO_InitStructure.GPIO_Pin = PWR_MONITOR1_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(PWR_MONITOR_PORT, &GPIO_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel=PWR_MONITOR_EXT_IRQ;
NVIC_InitStructure.NVIC_IRQChannelPriority=1;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/*
**虚拟串口2的GPIO配置
*/
void vuart2_bsp_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_AHBPeriphClockCmd(PWR_MONITOR_PCC, ENABLE);
GPIO_InitStructure.GPIO_Pin = PWR_MONITOR2_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(PWR_MONITOR_PORT, &GPIO_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel=PWR_MONITOR_EXT_IRQ;
NVIC_InitStructure.NVIC_IRQChannelPriority=0;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/*
**虚拟串口选择
*/
void vuart_bsp_init(vuart_em vuartx)
{
if(VUART1==vuartx)
{
vuart1_bsp_init();
}
else if(VUART2==vuartx)
{
vuart2_bsp_init();
}
}
/*
**虚拟串口打开
*/
void vuart_open(vuart_em vuartx,FunctionalState fsta)
{
EXTI_InitTypeDef EXTI_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG,ENABLE);
if(VUART1==vuartx)
{
SYSCFG_EXTILineConfig(PWR_MONITOR_EXT_PSP,PWR_MONITOR1_EXT_PS);
EXTI_InitStructure.EXTI_Line=PWR_MONITOR1_EXT_LINE;
}
else if(VUART2==vuartx)
{
SYSCFG_EXTILineConfig(PWR_MONITOR_EXT_PSP,PWR_MONITOR2_EXT_PS);
EXTI_InitStructure.EXTI_Line=PWR_MONITOR2_EXT_LINE;
}
EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd=fsta;
EXTI_Init(&EXTI_InitStructure);
if(VUART1==vuartx)
{
EXTI_ClearFlag(PWR_MONITOR1_EXT_LINE);
}
else if(VUART2==vuartx)
{
EXTI_ClearFlag(PWR_MONITOR2_EXT_LINE);
}
}
/*
**数据位bit定时器
*/
void bit_timer(FunctionalState fsta)
{
TIM_Cmd(TIM14,fsta);
}
/*
**字节数据读取
*/
unsigned char byte_get(vuart_em vuart)
{
unsigned char ret=0;
if(VUART1==vuart)
{
ret= PWR_MONITOR1_GET();
}
if(VUART2==vuart)
{
ret= PWR_MONITOR2_GET();
}
return ret;
}
/
**模拟串口配置初始化
*/
void vuart_init(vuart_st *const vuart_me,vuart_em vuartx,unsigned short int baud,chk_em chk_type)
{
vuart_me->data.byte_cont=0;
vuart_me->data.byte_value=0;
vuart_me->data.byte_chkok=0;
vuart_me->bit_rx.state=STATE_STOP;//停止位
vuart_me->config.baud=baud;
vuart_me->config.chk_type=chk_type;
vuart_me->open=vuart_open; //串口开闭函数指针
vuart_me->hw_init=vuart_bsp_init; //端口硬件初始化函数指针
vuart_me->byte_get=byte_get; //端口数据读取函数指针
vuart_me->bit_timer=bit_timer; //bit数据时基器
vuart_me->hw_init(vuartx);
switch(baud)
{
case 2400:
timer14_init(417);//---bit/417us
break;
case 4800:
timer14_init(210);//---bit/209us
break;
case 9600:
timer14_init(106);//---bit/106us
break;
}
vuart_me->bit_timer(DISABLE);//使能数据位计时器
vuart_me->open(vuartx,ENABLE);//使能模拟串口接收
}
/*
**数据位状态切换
*/
__inline void vuart_state_handle(vuart_st *const vuart_me,vuart_em vuartx)//外部中断脉冲
{
//下降沿中断
if(0==vuart_me->byte_get(vuartx))//检测到低电平
{
if(STATE_STOP<=vuart_me->bit_rx.state)//已超过停止位
{
vuart_me->data.byte_cont=0;//重置
vuart_me->data.byte_value=0;
vuart_me->bit_rx.state=STATE_START;//重置为起始位
vuart_me->bit_timer(ENABLE);//开启bit数据计时器
}
}
}
/*
**字节数定时接收
*/
__inline void vuart_read_handle(vuart_st *const vuart_me,vuart_em vuartx)//定时读取
{
static unsigned char i;
//波特率:4800bps
//--START_BIT->BIT0->BIT1->BIT2->BIT3->BIT4->BIT5->BIT6->BIT7->BITC->STOP_BIT->START_BIT
vuart_me->bit_rx.state++;//状态位切换
switch(vuart_me->config.chk_type)//---是否有校验
{
case NONE://无校验
if(STATE_BITC==vuart_me->bit_rx.state)//当前已至校验位
{
vuart_me->bit_rx.state=STATE_STOP;//将校验位直接当作停止位处理
}
break;
case EVEN://偶校验
if(STATE_BITC==vuart_me->bit_rx.state)//当前为校验位
{
//校验规则判断
if((0!=vuart_me->byte_get(vuartx)&&(0==vuart_me->data.byte_cont%2))||\
((0==vuart_me->byte_get(vuartx))&&(0!=vuart_me->data.byte_cont%2)))
{
vuart_me->data.byte_chkok=0;//校验不通过
}
else
{
vuart_me->data.byte_chkok=1;
}
}
break;
case ODD://奇校验
if(STATE_BITC==vuart_me->bit_rx.state)//当前为校验位
{
//校验规则判断
if((0!=vuart_me->byte_get(vuartx)&&(vuart_me->data.byte_cont%2))||\
(0==vuart_me->byte_get(vuartx)&&(0==vuart_me->data.byte_cont%2)))
{
vuart_me->data.byte_chkok=0;//校验不通过
}
else
{
vuart_me->data.byte_chkok=1;
}
}
break;
default:break;
}
//---停止位
if(STATE_STOP==vuart_me->bit_rx.state) //定时读取209us/bit
{
vuart_me->bit_timer(DISABLE);//关闭计数时基器
if(vuart_me->data.byte_chkok)//数据位检验通过,一个字节完成
{
if(VUART1_MAX_SIZE>VUART1_RX_SIZE)//未
{
VUART1_RX_BUF[VUART1_RX_SIZE++]=vuart_me->data.byte_value;//接收串口数据送入缓存区
}
vuart_me->data.byte_chkok=0;//清除本次校验通过标志
}
else //当前字节数据校验不通过,则放弃之前收到的数据
{
VUART1_RX_SIZE=0;
vuart_me->data.byte_value=0;
memset(&VUART1_RX_BUF,0x00,VUART1_MAX_SIZE);
}
return;
}
//---有效数据位[--介于起始位与校验位间--]
if(STATE_START<vuart_me->bit_rx.state&&STATE_BITC>vuart_me->bit_rx.state)
{
i=vuart_me->bit_rx.state;
if(0!=vuart_me->byte_get(vuartx))//高电平
{
vuart_me->data.byte_cont++;
vuart_me->data.byte_value|=(1<<(i-1));
}
else//低电平
{
vuart_me->data.byte_value&=~(1<<(i-1));
}
}
}
/*
**读取串口数据
*/
void vuart_data_read(vuart_st *const vuart_me,vuart_em vuartx,unsigned char *vuart_data,unsigned char vuart_data_len)
{
#define WAIT_DATA_TIME (2) //(需要根据字节数以及调用该函数的时基作相应的时间调整),本例程调用的时基为:10ms
static unsigned char vuartx_recv_timing=0;//接收DATA_MAX_LEN帧长度数据的时间控制值
vuart_me->open(vuartx,ENABLE);//打开串口(开启外部中断,开始接收数据)
/*
PS:当时在没有加入这个时间量的控制时,调试时发现数据一致不能正常抓取,数据虽没有乱码(误码),
但是总是抓头不抓尾,像断帧,百思不得其解,后来参考同事的驱动,
才意识到是没有考虑保证接收一个完整帧数据的时间,
于是就加入了这个vuartx_recv_timing变量进行接收控制,于是问题完美解决。
*/
if(vuart_data_len<=VUART1_RX_SIZE&&WAIT_DATA_TIME<vuartx_recv_timing++)//已达到协议长度,且已超过完整帧接收时长
{
for(unsigned char i=0;i<vuart_data_len;i++)
{
vuart_data[i]=VUART1_RX_BUF[i];
}
VUART1_RX_SIZE=0;//接收地址重置
vuartx_recv_timing=0;
//memset(&VUART1_RX_BUF[0],0x00,VUART1_MAX_SIZE);//销毁本次数据
}
}
/*
**模拟串口硬件外部中断位处理
*/
void EXTI4_15_IRQHandler(void)//
{
if((EXTI_GetITStatus(PWR_MONITOR1_EXT_LINE)!= RESET)||(EXTI_GetFlagStatus(PWR_MONITOR1_EXT_LINE))!= RESET)
{
//vuart_state_handle(&vuart1,VUART1);
EXTI_ClearFlag(PWR_MONITOR1_EXT_LINE);
EXTI_ClearITPendingBit(PWR_MONITOR1_EXT_LINE);
}
if((EXTI_GetITStatus(PWR_MONITOR2_EXT_LINE)!= RESET)||(EXTI_GetFlagStatus(PWR_MONITOR2_EXT_LINE))!= RESET)
{
vuart_state_handle(&vuart2,VUART2);
EXTI_ClearFlag(PWR_MONITOR2_EXT_LINE);
EXTI_ClearITPendingBit(PWR_MONITOR2_EXT_LINE);
}
}
/*
**数据位定时中断接收里
*/
void TIM14_IRQHandler(void) //
{
if((TIM_GetFlagStatus(TIM14, TIM_FLAG_Update)!= RESET)||(TIM_GetITStatus(TIM14, TIM_IT_Update)!= RESET) )
{
// vuart_read_handle(&vuart1,VUART1);
vuart_read_handle(&vuart2,VUART2);
TIM_ClearITPendingBit(TIM14,TIM_IT_Update);
TIM_ClearFlag(TIM14,TIM_FLAG_Update);
}
}
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
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
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
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
- 虚拟串口配置初始化
/*
**配置初始化
*/
vuart_init(&vuart2,VUART2,4800,EVEN);//4800--偶校验
1
2
3
4
2
3
4
/*
**配置初始化
*/
vuart_init(&vuart2,VUART2,4800,EVEN);//4800--偶校验
1
2
3
4
2
3
4
- 接口调用例程
hlw8302_un hlw8302_a,hlw8302_b;
void hlw8032_data_handle(hlw8302_un *const hlw8302_me,vuart_st *const vuart_me,vuart_em vuartx)
{
unsigned short int crc_data=0;
vuart_data_read(vuart_me,vuartx,hlw8302_me->data,DATA_MAX_LEN);//提取串口数据
for(unsigned char j=3;j<DATA_MAX_LEN-3;j++)//有效长度
{
crc_data=+hlw8302_me->data[j]; //求取校验和值
}
//无效数据
if(0xAA==hlw8302_me->reg.state_data||((unsigned char)crc_data!=hlw8302_me->reg.checksum_data))
{
memset(&hlw8302_me->data[0],0x00,DATA_MAX_LEN);//舍弃本次数据
// memset(&VUART1_RX_BUF,0x00,VUART1_MAX_SIZE);
}
}
/*
**放入定时器中断中
*/
void hlw8302_thread(void)
{
hlw8032_data_handle(&hlw8302_b,&vuart2,VUART2);
}
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
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
hlw8302_un hlw8302_a,hlw8302_b;
void hlw8032_data_handle(hlw8302_un *const hlw8302_me,vuart_st *const vuart_me,vuart_em vuartx)
{
unsigned short int crc_data=0;
vuart_data_read(vuart_me,vuartx,hlw8302_me->data,DATA_MAX_LEN);//提取串口数据
for(unsigned char j=3;j<DATA_MAX_LEN-3;j++)//有效长度
{
crc_data=+hlw8302_me->data[j]; //求取校验和值
}
//无效数据
if(0xAA==hlw8302_me->reg.state_data||((unsigned char)crc_data!=hlw8302_me->reg.checksum_data))
{
memset(&hlw8302_me->data[0],0x00,DATA_MAX_LEN);//舍弃本次数据
// memset(&VUART1_RX_BUF,0x00,VUART1_MAX_SIZE);
}
}
/*
**放入定时器中断中
*/
void hlw8302_thread(void)
{
hlw8032_data_handle(&hlw8302_b,&vuart2,VUART2);
}
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
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
- 最后用串口助手测试,完美接收。
https://blog.csdn.net/weixin_43940932/article/details/105495332
← RT-Thread 问题 锐能微 →