单片机中应用观察者模式
本文博客链接:http://blog.csdn.net/jdh99,作者:jdh,转载请注明.
环境:
主机:WIN8
开发环境:MDK5.13
mcu: stm32f103RB
说明:
之前在java中应用观察者模式,现将此模式的思想应用在单片机程序设计中
Android编程:观察者模式设计:
http://blog.csdn.net/jdh99/article/details/41821295
观察者模式本质:
有两个模块A,B。A是目标,B是观察者。则B能观察到A的变化。
在程序实现中过程是:
1.A产生数据
2.A通知B
3.B处理数据
单片机中实现的方法:
Java中通过接口实现此思想,单片机是C语言编程,则可以通过函数指针来实现。
源代码中dw1000通信模块提供了两个被观察的目标:接收数据,发送数据完成。
源代码:
dw1000.h
复制代码
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/********************************************************************* * dw1000通信模块头文件 * (c)copyright 2015,jdh * All Right Reserved *新建时间:2015/1/5 by jdh *修改时间:2015/1/6 by jdh **********************************************************************/ #ifndef _DW1000_H_ #define _DW1000_H_ /********************************************************************* * 头文件 **********************************************************************/ #include "world.h" /********************************************************************* * 宏定义 **********************************************************************/ /********************************************************************* * 接收数据缓存最大长度 **********************************************************************/ #define LEN_DW1000_BUF_RX 128 /********************************************************************* * 数据结构 **********************************************************************/ /********************************************************************* * dw1000时间结构 **********************************************************************/ union _Dw1000_Time { uint8_t pt[8]; uint64_t value; }; /********************************************************************* * 接收数据结构 **********************************************************************/ struct _Dw1000_Rx { //接收数据 uint8_t buf[LEN_DW1000_BUF_RX]; //接收数据的dw1000时间 union _Dw1000_Time time; }; /********************************************************************* * 观察者模式:接收数据处理函数指针 **********************************************************************/ typedef void (*T_Dw1000_Deal_Rx)(struct _Dw1000_Rx); /********************************************************************* * 观察者模式:发送数据完成处理函数指针 **********************************************************************/ typedef void (*T_Dw1000_Deal_Tx_End)(union _Dw1000_Time); /********************************************************************* * 接收缓存 **********************************************************************/ struct _Rx_Buf_CC1100 { //接收时间 T_Time time; //源ID uint16_t src_id; //功能码 uint8_t cmd; //数据 uint8_t data[3]; //rssi int rssi; //lqi uint8_t lqi; }; /********************************************************************* * 函数 **********************************************************************/ /********************************************************************* * 接口函数:模块载入 **********************************************************************/ void dw1000_load(void); /********************************************************************* * 接口函数:模块运行 **********************************************************************/ void dw1000_run(void); /********************************************************************* * 接口函数:中断处理函数 **********************************************************************/ void dw1000_irq_handler(void); /********************************************************************* * 接口函数:判断是否可以发送 *返回:0:不可以发送,1:可以发送 **********************************************************************/ uint8_t cc1100_judge_tx(void); /********************************************************************* * 接口函数:发送数据 *参数:cmd:功能码 * id:目标id * data:3字节数据 **********************************************************************/ void cc1100_tx(uint8_t cmd,uint16_t id,uint8_t *data); /********************************************************************* * 接口函数:得到接收数据 *返回:接收数据 **********************************************************************/ struct _Rx_Buf_CC1100 cc1100_get_rx_buf(void); /********************************************************************* * 接口函数:设置频点 *参数:freq:需要设置的频点 **********************************************************************/ void cc1100_set_freq(uint8_t freq); /********************************************************************* * 接口函数:注册观察者:接收数据 **********************************************************************/ void dw1000_register_observer_rx(T_Dw1000_Deal_Rx function); /********************************************************************* * 接口函数:注册观察者:发送完成 **********************************************************************/ void dw1000_register_observer_tx_end(T_Dw1000_Deal_Tx_End function); #endif
dw1000.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
226
227/********************************************************************* * dw1000通信模块主文件 * (c)copyright 2015,jdh * All Right Reserved *新建时间:2015/1/5 by jdh *修改时间:2015/1/6 by jdh **********************************************************************/ /********************************************************************* * 头文件 **********************************************************************/ #include "dw1000.h" /********************************************************************* * 宏定义 **********************************************************************/ /********************************************************************* * 观察者最大个数 **********************************************************************/ #define MAX_OBSERVER 10 /********************************************************************* * 静态变量 **********************************************************************/ /********************************************************************* * 接收数据观察者列表 **********************************************************************/ static T_Dw1000_Deal_Rx Observer_Rx[MAX_OBSERVER]; static uint8_t Len_Observer_Rx = 0; /********************************************************************* * 发送完成观察者列表 **********************************************************************/ static T_Dw1000_Deal_Tx_End Observer_Tx_End[MAX_OBSERVER]; static uint8_t Len_Observer_Tx_End = 0; /********************************************************************* * 静态函数 **********************************************************************/ /********************************************************************* * 接收处理 **********************************************************************/ static void deal_rx(void); /********************************************************************* * 发送结束处理 **********************************************************************/ static void deal_tx_end(void); /********************************************************************* * 函数 **********************************************************************/ /********************************************************************* * 接口函数:模块载入 **********************************************************************/ void dw1000_load(void) { } /********************************************************************* * 接口函数:模块运行 **********************************************************************/ void dw1000_run(void) { } /********************************************************************* * 接口函数:注册观察者:接收数据 **********************************************************************/ void dw1000_register_observer_rx(T_Dw1000_Deal_Rx function) { Observer_Rx[Len_Observer_Rx++] = function; } /********************************************************************* * 接口函数:注册观察者:发送完成 **********************************************************************/ void dw1000_register_observer_tx_end(T_Dw1000_Deal_Tx_End function) { Observer_Tx_End[Len_Observer_Tx_End++] = function; } /********************************************************************* * 接口函数:中断处理函数 **********************************************************************/ void dw1000_irq_handler(void) { uint32_t status = 0; uint32_t clear = 0; // will clear any events seen uint8_t resetrx; status = dwt_read32bitreg(SYS_STATUS_ID) ; // read status register low 32bit if(status & SYS_STATUS_LDEDONE) { if((status & (SYS_STATUS_LDEDONE | SYS_STATUS_RXPHD | SYS_STATUS_RXSFDD)) != (SYS_STATUS_LDEDONE | SYS_STATUS_RXPHD | SYS_STATUS_RXSFDD)) { resetrx = 0xe0; //got LDE done but other flags SFD and PHR are clear - this is a bad frame - reset the transceiver dwt_forcetrxoff(); //this will clear all events //set rx reset dwt_writetodevice(PMSC_ID, 0x3, 1, &resetrx); resetrx = 0xf0; //clear RX reset dwt_writetodevice(PMSC_ID, 0x3, 1, &resetrx); // dwt_write16bitoffsetreg(SYS_CTRL_ID,0,(uint16)SYS_CTRL_RXENAB) ; } } if((status & SYS_STATUS_RXFCG) && (status & SYS_STATUS_LDEDONE)) // Receiver FCS Good { //clear all receive status bits (as we are finished with this receive event) clear |= status & CLEAR_ALLRXGOOD_EVENTS ; dwt_write32bitreg(SYS_STATUS_ID,clear) ; // write status register to clear event bits we have seen //接收处理 deal_rx(); } else { if (status & SYS_STATUS_TXFRS) // Transmit Frame Sent { clear |= CLEAR_ALLTX_EVENTS; //clear TX event bits dwt_write32bitreg(SYS_STATUS_ID,clear) ; // write status register to clear event bits we have seen //发送结束处理 deal_tx_end(); } else { if (status & SYS_STATUS_RXRFTO) { //接收超时 clear |= status & SYS_STATUS_RXRFTO ; dwt_write32bitreg(SYS_STATUS_ID,clear) ; // write status register to clear event bits we have seen dwt_setrxtimeout(0); dwt_rxenable(0) ; } else { //异常 清除所有标识 clear |= CLEAR_ALLRXERROR_EVENTS; dwt_write32bitreg(SYS_STATUS_ID,clear) ; // write status register to clear event bits we have seen dwt_forcetrxoff(); //this will clear all events //set rx reset dwt_writetodevice(PMSC_ID, 0x3, 1, &resetrx); resetrx = 0xf0; //clear RX reset dwt_writetodevice(PMSC_ID, 0x3, 1, &resetrx); dwt_rxenable(0) ; } } } } /********************************************************************* * 接收处理 **********************************************************************/ static void deal_rx(void) { struct _Dw1000_Rx rx; uint16_t len; uint8_t i = 0; len = dwt_read16bitoffsetreg(RX_FINFO_ID, 0) & 0x3FF; if (len >= 127) { return; } dwt_write32bitreg(SYS_STATUS_ID,CLEAR_ALLRXGOOD_EVENTS) ; //得到接收时间 dwt_readrxtimestamp(rx.time.pt); rx.time.value &= MASK_40BIT; //得到接收数据 dwt_readfromdevice(RX_BUFFER_ID,0,len,rx.buf) ; //通知观察者 for (i = 0;i < Len_Observer_Rx;i++) { Observer_Rx[i](rx); } // uint8 resetrx; // resetrx = 0xe0; //got LDE done but other flags SFD and PHR are clear - this is a bad frame - reset the transceiver dwt_forcetrxoff(); //this will clear all events dwt_writetodevice(PMSC_ID, 0x3, 1, &resetrx);//set rx reset resetrx = 0xf0; //clear RX reset dwt_writetodevice(PMSC_ID, 0x3, 1, &resetrx); dwt_write16bitoffsetreg(SYS_CTRL_ID,0,(uint16)SYS_CTRL_RXENAB) ; } /********************************************************************* * 发送结束处理 **********************************************************************/ static void deal_tx_end(void) { union _Dw1000_Time time; uint8_t i = 0; //获得发送时间 dwt_readtxtimestamp(time.pt) ; time.value &= MASK_40BIT; //通知观察者 for (i = 0;i < Len_Observer_Tx_End;i++) { Observer_Tx_End[i](time); } }
main.c中观察dw1000模块的接收数据:
复制代码
1
2//增加接收数据观察者 dw1000_register_observer_rx(deal_rx);
处理函数:
复制代码
1
2
3
4
5
6
7void deal_rx(struct _Dw1000_Rx rx) { //处理... __nop(); __nop(); __nop(); }
最后
以上就是善良冰淇淋最近收集整理的关于单片机中应用观察者模式的全部内容,更多相关单片机中应用观察者模式内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复