概述
单片机中应用观察者模式
本文博客链接: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();
}
最后
以上就是善良冰淇淋为你收集整理的单片机中应用观察者模式的全部内容,希望文章能够帮你解决单片机中应用观察者模式所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复