单片机中应用观察者模式
本文博客链接: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
/********************************************************************* * 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
/********************************************************************* * 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模块的接收数据:
//增加接收数据观察者 dw1000_register_observer_rx(deal_rx);
处理函数:
void deal_rx(struct _Dw1000_Rx rx) { //处理... __nop(); __nop(); __nop(); }