单片机中应用观察者模式

发布者:忠正最新更新时间:2016-05-17 来源: eefocus关键字:单片机  观察者模式 手机看文章 扫描二维码
随时随地手机看文章
环境:

主机: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();
 }
 
关键字:单片机  观察者模式 引用地址:单片机中应用观察者模式

上一篇:基于STM32单片机开发光学指纹识别模块(FPM10A)全教程
下一篇:S3C2440 Mini 2440 DMA方式实现Uart串口通信

推荐阅读最新更新时间:2024-03-16 14:54

飞思卡尔推出全新基于ARM Cortex-M4内核的KS22 MCU
飞思卡尔半导体(NYSE: FSL)日前宣布推出全新KS22系列MCU。KS22系列基于ARM Cortex-M4内核,是飞思卡尔为了满足中国市场需求全新打造的一款通用MCU。KS22系列在继承了飞思卡尔32位MCU高度集成和丰富产品特性的同时,优化了功能配置和生产流程,提高了性价比和市场竞争力,可广泛用于车载信息娱乐系统、工业及消费类等应用领域。 飞思卡尔微控制器事业部中国区产品及研发总监周荣政博士表示: 中国MCU市场瞬息万变,竞争日趋激烈,设计人员面临着应用广泛、需求多样、客户分散、成本控制等多种挑战。飞思卡尔在中国市场深耕多年,投资巨大。为了更好地服务于中国市场,我们通过对本土市场的潜心研究,整合市场和设计资源,精
[单片机]
一种基于单片机的函数发生器的设计实现
1 引 言      在自动控制系统设计及调试过程中,不同频率的正弦波、三角波和方波常作为信号源,应用十分方便。过去常由分立元件及集成运放构成振荡器,后来出现的ICL8038其最高频率仅能达到100kHz。而MAX038芯片性能更好,最高频率可达20MHz,且三种波形由同一端输出。单片机控制品质卓越,基于单片机的函数发生器运行可靠,操作方便。 2 高频信号发生器芯片MAX038简介      MAXIM公司生产的MAX038芯片是一种高频精密的函数发生器,可产生三角波、锯齿波、正弦波、方波及脉冲波,且频率及占空比的控制可独立进行。      Lin管脚电流范围在10~400μA时电路获得最佳工作性能。输出波形的选择由逻辑地
[应用]
单片机c语言教程第一章 建立你的第一个KeilC51项目
随着单片机技术的不断发展,以单片机C语言为主流的高级语言也不断被更多的单片机爱好者和工程师所喜爱。使用C51肯定要使用到编译器,以便把写好的C程序编译为机器码,这样单片机才能执行编写好的程序。KEIL uVISION2 是众多单片机应用开发软件中优秀的软件之一,它支持众多不一样公司的MCS51架构的芯片,它集编辑,编译,仿真等于一体,同时还支持,PLM,汇编和C语言的程序设计,它的界面和常用的微软 VC++的界面相似,界面友好,易学易用,在调试程序,软件仿真方面也有很强大的功能。本站提供的单片机c语言教程都是基于keilc51的   下面结合8051介绍单片机C语言的优越性:   ·无须懂得单片机的具体硬件,也能够编出符合硬件
[单片机]
<font color='red'>单片机</font>c语言教程第一章 建立你的第一个KeilC51项目
PIC单片机对数字温度传感器的控制设计
#include #define uchar unsigned char #define uint unsigned int #define DQ RC1 #define DQ_HIGH() TRISC1=1 #define DQ_LOW() TRISC1=0;DQ=0 __CONFIG(0x3B31); const uchar table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d, 0x07,0x7f,0x6f}; const uchar table1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd, 0x87,0xff,0xef}; uint te mper; uc
[单片机]
PIC<font color='red'>单片机</font>对数字温度传感器的控制设计
单片机读写RC522射频卡上位机调试软件及参考例程
下位机(单片机)电路原理图: 上位机delphi源码与说明资料: IC读写器使用说明 一、读写器连接 1.1 把通讯线“DB9”端插到PC 机的串口1/2 上 1.2 把通讯线2510端插到读写器的插座,使读写器和PC 机的串口良好连接 1.2 把电源线的“圆柱”端插到读写器的电源座子上 1.3读写器上电以后可以听到一声风鸣器的响声,如果没有听到风鸣器声,表明读写器没有正常上电. 二、启动Demo 软件 2.1 双击启动测试软件 2.2 如果串口良好连接的话可以听到一声风鸣器的响声,如果启动测试软件以后并没有听到风鸣器声表明串口通讯没有连接好,请检查串口连接线是否连接正确 三、M1卡片读写测试 3.1 把一张Mifa
[单片机]
<font color='red'>单片机</font>读写RC522射频卡上位机调试软件及参考例程
聚焦IoT领域 鸿博微以“MCU+”策略推动国产替代进程
近年来,受物联网快速发展带来的联网节点数量增长、汽车电子的渗透率提升以及工业4.0对自动化设备的旺盛需求等因素的影响,MCU在汽车电子、物联网、消费电子等下游应用领域的使用大幅增加,全球MCU市场规模快速增长。 面对如此诱人的市场蛋糕,包括兆易创新、芯海科技、广州鸿博微电子技术有限公司(下称“鸿博微”)等国内MCU厂商也纷纷加码布局。其中,鸿博微作为国内“造芯”的新势力,其设立之初便制定“MCU+解决方案”的产品策略,并在一年内量产三款MCU产品,具备较高的产品迭代速度和研发能力。 据了解,鸿博微拥有高水平的技术团队,在模拟芯片和数字芯片方面都有丰富的经验积累。同时,该公司在产品布局、知识产权、市场开发以及团队建设方面均做了清晰规
[手机便携]
PIC单片机入门_汇编/混编/C编比较
1.问题描述: 对RAM中从30h开始的50个单元清零。 2.汇编方法 span style= font-size:18px; COUNT EQU 20H ;指定20H寄存器为循环变量 FSR EQU 04H ;指定FSR为04H INDF EQU 00H ;指定INDF为00H MOVLW D’50 ;给循环变量赋初值 MOVWF COUNT MOVLW 30H ;将30H →FSR MOVWF FSR NEXT CLRF INDF ;间接寻址 INCF FSR,1 ;地址指针内容加
[单片机]
MCS-51单片机外中断软件编程
MCS-51单片机有多个中断源,以8051为例,有5个中断源,两个外中断、两个定时中断和一个串行中断,这一节我们讨论外中断软件编程。 外中断是由外部原因引起的中断,有两个中断源。即外中断0(INT0)和外中断1(INT1),中断请求信号由引脚P3.2(INT0)和P3.3(INT1)输入。 外中断请求信号有两种方式,一是电平方式,二是脉冲方式。可通过有关控制位的定义进行规定。 电平方式为低电平有效,只需在单片机的(INT0)和(INT1)中断请求输入端采样到有效的低电平时,就会激活外部中断。 脉冲方式则在脉冲的后负跳沿有效,即在相邻两个机器周期对中断请求引入端进行采样中,如前一次为高,后一次为低即为有效中断请求
[单片机]
MCS-51<font color='red'>单片机</font>外中断软件编程
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved