单片机中应用观察者模式

??

本文博客链接: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();
 }
时间: 2024-10-12 20:36:22

单片机中应用观察者模式的相关文章

[设计模式]NetworkManagementService中的观察者模式

观察者模式 观察者模式有如下角色 (1)被观察者(Subject) (2)观察者(Observer) public class Subject{ private: list<Observer> mObservers; protect: void onChange(){ for(int i=0; i<mObservers.size(); ++i){ mObservers.get(i).onAction(); } } public: void attach(Observer m){ mObs

一种单片机支持WiFi的应用——SimpleWiFi在单片机中的应用

一种单片机支持WiFi的应用——SimpleWiFi在单片机中的应用 先上图: 现在的智能控制都是基于微控制器,随着智能的手持终端的普及,基于智能终端的控制就会越来越普遍. WIFI便是其中的一种.WiFi用于智能家居控制,有着其得天独厚的优势.其优势如下: 优势一:WiFi终端设备现在基本上已经普及,WiFi已经智能手持终端的标配.大到笔记本.Pad,小到手机,WiFi已经是无所不在. 优势二:WiFi作为无线局域网的技术标准,能够通过无线路由器与现有的互联网进行互联互通.没有任何的技术以及协

单片机中 负跳变和高脉冲是什么

在单片机中,负跳变指平由高电平变成低电平的过程,也叫下降沿,高脉冲就是正脉冲,给一个上升沿. 负跳变指令检测它前面的逻辑状态.如果上个程序扫描周期是1,本周期是0,则它后面的逻辑状态在本周期的剩余扫描时间内为1, 该指令仅在一个扫描周期内有效. 高脉冲即从逻辑0变化到逻辑1再变化到逻辑0,如此便是一个高脉冲.在单片机中定义高脉冲就是让某个I/O先输出逻辑0,接着保持一定的时间(延时),再输出逻辑1,同样保持一定的时间(延时),最后再转变输出为逻辑0+延时.

为什么单片机中既有Flash又有EEPROM

单片机运行时的数据都存在于RAM(随机存储器)中,在掉电后RAM 中的数据是无法保留的,那么怎样使数据在掉电后不丢失呢?这就需要使用EEPROM 或FLASHROM 等存储器来实现. 插播一段:ROM最初不能编程,出厂什么内容就永远什么内容,不灵活.后来出现了PROM,可以自己写入一次,要是写错了,只能换一片.随着不断改进,终于出现了可多次擦除写入的EPROM,每次擦除要把芯片拿到紫外线上照一下,想一下你往单片机上下了一个程序之后发现有个地方需要加一句话,为此你要把单片机放紫外灯下照半小时,然后

单片机中C语言的程序与数据存储

单片机中C语言的程序与数据存储 一.五大内存分区: 内存分成5个区,它们分别是堆.栈.自由存储区.全局/静态存储区和常量存储区. 1.栈区(stack):FIFO就是那些由编译器在需要的时候分配,在不需要的时候自动清除的变量的存储区.里面的变量通常是局部变量.函数参数等. 2.堆区(heap):就是那些由new分配的内存块,它们的释放编译器不去管,由我们的应用程序去控制,一般一个new就要对应一个delete.如果程序员没有释放掉,那么在程序结束后,操作系统会自动回收. 3.自由存储区:就是那些

ListView中的观察者模式

*本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布 虽然现在RecyclerView很好用,也在逐渐替代ListView.很多github的开源大神也在对其进行更加实用的封装.我现在写的一个音乐播放器也在使用RecyclerView.但是这些都不阻碍我们学习ListView优秀的源码设计. 播放器我想要写的精美,但现在越写越多bug,这也应该是我离开大学校园,实习前的最后一个小作品了,接下来的半年多的时间要冲刺复习咯. 进入正题,我用的是Api-23的源码.接下来就从源码的角度

单片机中的软定时器

因单片机中常有一些控制与延时关联,这些操作并不需要特别高的精度,为了少敲点字,故做了这个单片机软定时器,不足之处,欢迎指正. timer.h 1 #ifndef __SOFT_TIMER_H__ 2 #define __SOFT_TIMER_H__ 3 4 //#define TIMEBASE_FREQ 1000 5 // 6 #define ONESHOT_TIMER 0 7 #define PERIODIC_TIMER 1 8 9 //time vector size ,可同时使用的最大定时

单片机中嵌入操作系统

在单片机中嵌入操作系统的利弊       摘要:近年来,在单片机系统中嵌入操作系统已经成为人们越来越关心的一个话题.本文通过对一种源码公开的单片机嵌入式实时操作系统μC/OS-II为例,阐述了在单片机中使用该嵌入式操作系统的优缺点,以及在应用中应当注意的一些问题. 关键词:实时操作系统:μC/OS-II:单片机   引言   早在20世纪60年代,就已经有人开始研究和开发嵌入式操作系统.但直到最近,它才在国内被越来越多的提及,在通信.电子.自动化等需要实时处理的领域所日益显现的重要性吸引了人们越

【安卓笔记】数据适配器(adapter)中的观察者模式

ListView要想显示数据,需要用到数据适配器即Adapter.而当我们删除ListView的某个条目时,数据适配器中的数据源必然发生改变,这时候我们通过调用适配器类提供的notifyDataSetChanged方法通知listview数据发生改变,请求重新绘制. 这其中其实使用了一种比较常见的设计模式,即观察者模式. 在分析数据适配器中涉及到的观察者模式之前,我们先简单了解下什么是观察者模式. 观察者模式的定义:定义对象间的一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象