单片机中应用观察者模式

来源:互联网 发布:和视频软件 编辑:程序博客网 时间:2024/05/23 19:16


单片机中应用观察者模式


本文博客链接: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_RX128/**********************************************************************数据结构**********************************************************************//**********************************************************************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;//源IDuint16_t src_id;//功能码uint8_t cmd;//数据uint8_t data[3];//rssiint rssi;//lqiuint8_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_OBSERVER10/**********************************************************************静态变量**********************************************************************//**********************************************************************接收数据观察者列表**********************************************************************/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 seenuint8_t resetrx;status = dwt_read32bitreg(SYS_STATUS_ID) ;            // read status register low 32bitif(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 transceiverdwt_forcetrxoff(); //this will clear all events//set rx resetdwt_writetodevice(PMSC_ID, 0x3, 1, &resetrx);resetrx = 0xf0; //clear RX resetdwt_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 bitsdwt_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 seendwt_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 seendwt_forcetrxoff(); //this will clear all events//set rx resetdwt_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(); }

2 0
原创粉丝点击