导航:首页 > 源码编译 > observe函数源码

observe函数源码

发布时间:2022-07-09 17:25:07

‘壹’ 在ios中观察者模式和控制中心在什么时候使用

什么是观察者模式?我们先打个比方,这就像你订报纸。比如你想知道美国最近放生了些新闻,你可能会订阅一份美国周刊,然后一旦美国有了新的故事,美国周刊就发一刊,并邮寄给你,当你收到这份报刊,然后你就能够了解美国最新的动态。其实这就是观察者模式,A对B的变化感兴趣,就注册为B的观察者,当B发生变化时通知A,告知B发生了变化。这是一种非常典型的观察者的用法,我把这种使用方法叫做经典观察者模式。当然与之相对的还有另外一种观察者模式——广义观察者模式。

从经典的角度看,观察者模式是一种通知变化的模式,一般认为只在对象发生变化感兴趣的场合有用。主题对象知道有观察者存在,设置会维护观察者的一个队列;而从广义的角度看,观察者模式是中传递变化数据的模式,需要查看对象属性时就会使用的一种模式,主题对象不知道观察者的存在,更像是围观者。需要知道主题对象的状态,所以即使在主题对象没有发生改变的时候,观察者也可能会去访问主题对象。换句话说广义观察者模式,是在不同的对象之间传递数据的一种模式。

观察者模式应当是在面向对象编程中被大规模使用的设计模式之一。从方法论的角度出发,传统的认知论认为,世界是由对象组成的,我们通过不停的观察和了解就能够了解对象的本质。整个人类的认知模型就是建立在“观察”这种行为之上的。我们通过不停与世界中的其他对象交互,并观察之来了解这个世界。同样,在程序的世界中,我们构建的每一个实例,也是通过不不停的与其他对象交互(查看其他对象的状态,或者改变其他对象的状态),并通过观察其他实例的变化并作出响应,以来完成功能。这也就是,为什么会把观察模式单独提出来,做一个专门的剖析的原因——在我看来他是很多其他设计模式的基础模式,并且是编程中极其重要的一种设计模式。

经典观察者模式

经典观察者模式被认为是对象的行为模式,又叫发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。经典观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化时,会通知所有观察者对象,使它们能够自动更新自己或者做出相应的一些动作。在文章一开始举的例子就是典型观察者模式的应用。

而在IOS开发中我们可能会接触到的经典观察者模式的实现方式,有这么几种:NSNotificationCenter、KVO、Delegate等

感知通知方式

在经典观察者模式中,因为观察者感知到主题对象变化方式的不同,又分为推模型和拉模型两种方式。

推模型
ios desing pattern observer 1

主题对象向观察者推送主题的详细信息,不管观察者是否需要,推送的信息通常是主题对象的全部或者部分数据。推模型实现了观察者和主题对象的解耦,两者之间没有过度的依赖关系。但是推模型每次都会以广播的方式,向所有观察者发送通知。所有观察者被动的接受通知。当通知的内容过多时,多个观察者同时接收,可能会对网络、内存(有些时候还会涉及IO)有较大影响。

在IOS中典型的推模型实现方式为NSNotificationCenter和KVO。

NSNotificationCenter

NSnotificationCenter是一种典型的有调度中心的观察者模式实现方式。以NSNotificationCenter为中心,观察者往Center中注册对某个主题对象的变化感兴趣,主题对象通过NSNotificationCenter进行变化广播。这种模型就是文章开始发布订阅报纸在OC中的一种类似实现。所有的观察和监听行为都向同一个中心注册,所有对象的变化也都通过同一个中心向外广播。

SNotificationCenter就像一个枢纽一样,处在整个观察者模式的核心位置,调度着消息在观察者和监听者之间传递。

ios desing pattern observer 2

一次完整的观察过程如上图所示。整个过程中,关键的类有这么几个(介绍顺序按照完成顺序):

观察者Observer,一般继承自NSObject,通过NSNotificationCenter的addObserver:selector:name:object接口来注册对某一类型通知感兴趣.在注册时候一定要注意,NSNotificationCenter不会对观察者进行引用计数+1的操作,我们在程序中释放观察者的时候,一定要去报从center中将其注销了。
- (void) handleMessage:(NSNotification*)nc{
//解析消息内容
NSDictionary* userInfo = [nc userInfo];
}
- (void) commonInit
{
//注册观察者
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleMessage:) name:kDZTestNotificatonMessage object:nil];
}
通知中心NSNotificationCenter,通知的枢纽。
主题对象,被观察的对象,通过postNotificationName:object:userInfo:发送某一类型通知,广播改变。
- (void) postMessage
{
[[NSNotificationCenter defaultCenter] postNotificationName:kDZTestNotificatonMessage object:Nil userInfo:@{}];
}
通知对象NSNotification,当有通知来的时候,Center会调用观察者注册的接口来广播通知,同时传递存储着更改内容的NSNotification对象。
apple版实现的NotificationCenter让我用起来不太爽的几个小问题

在使用NSNotificationCenter的时候,从编程的角度来讲我们往往不止是希望能够做到功能实现,还能希望编码效率和整个工程的可维护性良好。而Apple提供的以NSNotificationCenter为中心的观察者模式实现,在可维护性和效率上存在以下缺点:

每个注册的地方需要同时注册一个函数,这将会带来大量的编码工作。仔细分析能够发现,其实我们每个观察者每次注册的函数几乎都是雷同的。这就是种变相的CtrlCV,是典型的丑陋和难维护的代码。
每个观察者的回调函数,都需要对主题对象发送来的消息进行解包的操作。从UserInfo中通过KeyValue的方式,将消息解析出来,而后进行操作。试想一下,工程中有100个地方,同时对前面中在响应变化的函数中进行了解包的操作。而后期需求变化需要多传一个内容的时候,将会是一场维护上的灾难。
当大规模使用观察者模式的时候,我们往往在dealloc处加上一句:
[[NSNotificationCenter defaultCenter] removeObserver:self]
而在实际使用过程中,会发现该函数的性能是比较低下的。在整个启动过程中,进行了10000次RemoveObserver操作,
@implementation DZMessage
- (void) dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
....
for (int i = 0 ; i < 10000; i++) {
DZMessage* message = [DZMessage new];
}
通过下图可以看出这一过程消耗了23.4%的CPU,说明这一函数的效率还是很低的。
ios desing pattern observer 6
这还是只有一种消息类型的存在下有这样的结果,如果整个NotificationCenter中混杂着多种消息类型,那么恐怕对于性能来说将会是灾难性的。

for (int i = 0 ; i < 10000; i++) {
DZMessage* message = [DZMessage new];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handle) name:[@(i) stringValue] object:nil];
}
增加了多种消息类型之后,RemoveObserver占用了启动过程中63.9%的CPU消耗。
ios desing pattern observer 7
而由于Apple没有提供Center的源码,所以修改这个Center几乎不可能了。

改进版的有中心观察者模式(DZNotificationCenter)

GitHub地址�0�2在设计的时候考虑到以上用起来不爽的地方,进行了优化:

将解包到执行函数的操作进行了封装,只需要提供某消息类型的解包block和消息类型对应的protocol,当有消息到达的时候,消息中心会进行统一解包,并直接调用观察者相应的函数。
对观察者的维护机制进行优化(还未做完),提升查找和删除观察者的效率。
DZNotificationCenter的用法和NSNotificationCenter在注册和注销观察者的地方是一样的,不一样的地方在于,你在使用的时候需要提供解析消息的block。你可以通过两种方式来提供。

直接注册的方式
[DZDefaultNotificationCenter addDecodeNotificationBlock:^SEL(NSDictionary *userInfo, NSMutableArray *__autoreleasing *params) {
NSString* key = userInfo[@"key"];
if (params != NULL) {
*params = [NSMutableArray new];
}
[*params addObject:key];
return @selector(handleTestMessageWithKey:);
} forMessage:kDZMessageTest];
实现DZNotificationInitDelegaete协议,当整个工程中大规模使用观察者的时候,建议使用该方式。这样有利于统一管理所有的解析方式。
- (DZDecodeNotificationBlock) decodeNotification:(NSString *)message forCenter:(DZNotificationCenter *)center
{
if (message == kDZMessageTest) {
return ^(NSDictionary* userInfo, NSMutableArray* __autoreleasing* params){
NSString* key = userInfo[@"key"];
if (params != NULL) {
*params = [NSMutableArray new];
}
[*params addObject:key];
return @selector(handlePortMessage:);
};
}
return nil;
}
在使用的过程中为了,能够保证在观察者处能够回调相同的函数,可以实现针对某一消息类型的protocol

@protocol DZTestMessageInterface <NSObject>
- (void) handleTestMessageWithKey:(NSString*)key;
@end
这样就能够保证,在使用观察者的地方不用反复的拼函数名和解析消息内容了。

@interface DZViewController () <DZTestMessageInterface>
@end
@implementation DZViewController
....
- (void) handleTestMessageWithKey:(NSString *)key
{
self.showLabel.text = [NSString stringWithFormat:@"get message with %@", key];
}
....
KVO

KVO的全称是Key-Value Observer,即键值观察。是一种没有中心枢纽的观察者模式的实现方式。一个主题对象管理所有依赖于它的观察者对象,并且在自身状态发生改变的时候主动通知观察者对象。 让我们先看一个完整的示例:

static NSString* const kKVOPathKey = @"key";
@implementation DZKVOTest
- (void) setMessage:(DZMessage *)message
{
if (message != _message) {
if (_message) {
[_message removeObserver:self forKeyPath:kKVOPathKey];
}
if (message) {
[message addObserver:self forKeyPath:kKVOPathKey options:NSKeyValueObservingOptionNew context:Nil];
}
_message = message;
}
}
- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if ([keyPath isEqual:kKVOPathKey] && object == _message) {
NSLog(@"get %@",change);
}
}
- (void) postMessage
{
_message.key = @"asdfasd";
}
@end

‘贰’ 哪些JavaScript 框架的源代码最值得阅读和学习

RubyLouvre/avalon · GitHub Object.defineProperty的极致使用及各种黑魔法

knockout/knockout · GitHub 观察者模式的极致使用

jakearchibald/es6-promise · GitHub 目前最好的Promise实现

Polymer/observe-js 路 GitHub 强大的状态机与最短编辑长度算法

jquery/jquery · GitHub 最强的DOM兼容处理

‘叁’ C#函数中如何返回多个返回值

如果给多个类都要实现的话,直接写一个写信信的类,专门用于处理写记录,每次要用的时候调用,我建的类的名字systemio
public
class
systemio
{
static
string
path
=
@"d:\observe.log";
public
static
void
writetotxt(string
message)
{
using
(streamwriter
sw
=
new
streamwriter(path,
false,
encoding.default))
{
sw.writeline(message);
}
}
}
你要实现的类
class
a
{
public
a()
{
systemio.writetotxt("程序a初始化");
}
public
void
a1()
{
systemio.writetotxt("程序a中a1方法执行了");
//...
}
public
int
a2()
{
systemio.writetotxt("程序a中a2方法执行了");
int
a2;
//...
systemio.writetotxt("程序a中a2方法的返回值是:"+a2.tostring());
return
a2;
}
}
函数进去的时候在构造函数里面加,
如果是返回值的话,在return之前捕获。
思想的话没有,硬套的话还是oop的思想

‘肆’ js 中 Event.observe()和Object.extend()函数的作用和用法,请高手帮帮我,谢啦

Object.extend = function (destination, source) {
for ( var property in source) {
destination[property] = source[property];
}
return destination;
}
Prototype 对Object类进行的扩展主要通过一个静态函数Object.extend(destination, source)实现了JavaScript中的继承。 从语义的角度, Object.extend(destination, source)方法有些不和逻辑, 因为它事实上仅仅实现了从源对象到目标对象的全息拷贝。不过你也可以这样认为:由于目标对象拥有了所有源对象所拥有的特性, 所以看上去就像目标对象继承了源对象(并加以扩展)一样。另外, Prototype对Object扩展了几个比较有用的静态方法, 所有其他的类可以通过调用这些静态方法获取支持。
JScript code
Object.extend=function(destination, source) { // 一个静态方法表示继承, 目标对象将拥有源对象的所有属性和方法
for (var property in source) {
destination[property] = source[property]; // 利用动态语言的特性, 通过赋值动态添加属性与方法
}
return destination; // 返回扩展后的对象
}

Object.extend(Object, {
inspect: function(object) { // 一个静态方法, 传入一个对象, 返回对象的字符串表示
try {
if (object == undefined) return'undefined'; // 处理undefined情况
if (object ==null) return'null'; // 处理null情况
// 如果对象定义了inspect方法, 则调用该方法返回, 否则返回对象的toString()值
return object.inspect ? object.inspect() : object.toString();
} catch (e) {
if (e instanceof RangeError) return'...'; // 处理异常情况
throw e;
}
},
keys: function(object) { // 一个静态方法, 传入一个对象, 返回该对象中所有的属性, 构成数组返回
var keys = [];
for (var property in object)
keys.push(property); // 将每个属性压入到一个数组中
return keys;
},
values: function(object) { // 一个静态方法, 传入一个对象, 返回该对象中所有属性所对应的值, 构成数组返回
var values = [];
for (var property in object) values.push(object[property]); // 将每个属性的值压入到一个数组中
return values;
},
clone: function(object) { // 一个静态方法, 传入一个对象, 克隆一个新对象并返回
returnObject.extend({}, object);
}
});

‘伍’ 计算机程序教程求专业翻译,要精细,翻译机再简单处理处理的别来了,翻得好可加分

最后撤消先前在地址0x00000020设置的断点, 然后选择 Continue 命令继续运行程序。观察程序在 DE2 板的16 进制显示器上循环显示的图形。按 DE2 板上的 KEY1 或 KEY2 键可以改变图形循环显示的方向,按 KEY3 键可以根据 SW 开关的值来改变图形的形状。按 KEY0 键可以使 Nios II 处理器复位,并将程序控制交还到位于地址 0x0 的监控程序。

8.2 C 程序中的中断
我们创建一个名为 Monitor_Interrupts_C 的新的工程来演示 C 程序中断的例子。在创建这个工程时, 将程序类型设为 C 程序, 将程序名设为 Interrupt Example. 这个程序用 C 语言代码来执行和前面的汇编语言程序同样的操作。在图 31 中列出了 C 程序的源代码文件. main 主程序在文件 interrupt_example.c 中,其它源程序文件为这个 C 程序提供了复位和异常处理功能以及两个中断处理服务子程序。完成创建该工程的其余步骤,然后编译并装载该程序。

在地址0x00000020 设置一个断点, 该地址是 Nios II 处理器的中断向量地址。将反编译窗口卷动到位于地址 0x00000698 名为 Interrupt_handler (中断处理程序)的函数. 如图 32 所示, 在此地址设置另一个断点. 现在开始执行程序到位于地址 0x00000020 的第一个断点, 此地址的代码位于 exception_handler.c 文件中。读取 Nois II 处理器控制寄存器的值来判断是否引发外了外部设备的中断, 将寄存器中的值存入堆栈, 然后调用interrupt_handler 函数。按监控程序中的 Actions > Continue 菜单使程序执行到第二个断点. 单步执行几条指令后可以看到, 如同前面的例子中讨论过的那样, DE2 板上的 Basic 计算机中的间隔定时器引发了中断。再单步执行指令就会使 Nios II 处理器进入间隔定时器的中断服务子程序, 如图 33 所示。该子程序先将引发中断的定时寄存器清零, 然后执行程序所需的其它功能。最后撤消前面在地址 0x00000020 和 0x00000698 设置的两处断点, 然后运行程序. 和前面讨论过的一样,该程序在 DE2板的16进制显示器上显示一个循环滚动的图形。

‘陆’ 51单片机控制SPI接口芯片都是模拟SPI吧

恩,是的,51单片机没有带SPI控制器。给你模拟SPI控制nRF24L01程序参考,我的联系方式看我名字

#include <reg52.h>
#include <intrins.h>

typedef unsigned char uchar;
typedef unsigned char uint;

//****************************************IO端口定义***************************************
sbit CSN =P2^0; //SPI 片选使能,低电平使能
sbit MOSI =P2^1; //SPI串行输入
sbit IRQ =P2^2; //中断.低电平使能
sbit MISO =P2^3; //SPI串行输出
sbit SCK =P2^4; //SPI时钟
sbit CE =P2^5; //芯片使能,高电平使能

//***********************************数码管0-9编码*******************************************
uchar seg[10]={0xC0,0xCF,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90}; //0~~9段码
uchar TxBuf[32]=
{ /*
0x01,0x02,0x03,0x4,0x05,0x06,0x07,0x08,
0x09,0x10,0x11,0x12,0x13,0x14,0x15,0x16,
0x17,0x18,0x19,0x20,0x21,0x22,0x23,0x24,
0x25,0x26,0x27,0x28,0x29,0x30,0x31,0x32,
*/
0x00
}; //
//************************************按键**********************************************
sbit KEY1=P3^6;
sbit KEY2=P3^7;
//***********************************数码管位选**************************************************
sbit led1=P2^1;
sbit led0=P2^0;
sbit led2=P2^2;
sbit led3=P2^3;
//*********************************************NRF24L01*************************************
#define TX_ADR_WIDTH 5 // 5 uints TX address width
#define RX_ADR_WIDTH 5 // 5 uints RX address width
#define TX_PLOAD_WIDTH 32 // 20 uints TX payload
#define RX_PLOAD_WIDTH 32 // 20 uints TX payload
uint const TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //本地地址
uint const RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //接收地址
//***************************************NRF24L01寄存器指令*******************************************************
#define READ_REG 0x00 // 读寄存器指令
#define WRITE_REG 0x20 // 写寄存器指令
#define RD_RX_PLOAD 0x61 // 读取接收数据指令
#define WR_TX_PLOAD 0xA0 // 写待发数据指令
#define FLUSH_TX 0xE1 // 冲洗发送 FIFO指令
#define FLUSH_RX 0xE2 // 冲洗接收 FIFO指令
#define REUSE_TX_PL 0xE3 // 定义重复装载数据指令
#define NOP 0xFF // 保留
//*************************************SPI(nRF24L01)寄存器地址****************************************************
#define CONFIG 0x00 // 配置收发状态,CRC校验模式以及收发状态响应方式
#define EN_AA 0x01 // 自动应答功能设置
#define EN_RXADDR 0x02 // 可用信道设置
#define SETUP_AW 0x03 // 收发地址宽度设置
#define SETUP_RETR 0x04 // 自动重发功能设置
#define RF_CH 0x05 // 工作频率设置
#define RF_SETUP 0x06 // 发射速率、功耗功能设置
#define STATUS 0x07 // 状态寄存器
#define OBSERVE_TX 0x08 // 发送监测功能
#define CD 0x09 // 地址检测
#define RX_ADDR_P0 0x0A // 频道0接收数据地址
#define RX_ADDR_P1 0x0B // 频道1接收数据地址
#define RX_ADDR_P2 0x0C // 频道2接收数据地址
#define RX_ADDR_P3 0x0D // 频道3接收数据地址
#define RX_ADDR_P4 0x0E // 频道4接收数据地址
#define RX_ADDR_P5 0x0F // 频道5接收数据地址
#define TX_ADDR 0x10 // 发送地址寄存器
#define RX_PW_P0 0x11 // 接收频道0接收数据长度
#define RX_PW_P1 0x12 // 接收频道0接收数据长度
#define RX_PW_P2 0x13 // 接收频道0接收数据长度
#define RX_PW_P3 0x14 // 接收频道0接收数据长度
#define RX_PW_P4 0x15 // 接收频道0接收数据长度
#define RX_PW_P5 0x16 // 接收频道0接收数据长度
#define FIFO_STATUS 0x17 // FIFO栈入栈出状态寄存器设置
//**************************************************************************************
void Delay(unsigned int s);
void inerDelay_us(unsigned char n);
void init_NRF24L01(void);
uint SPI_RW(uint uchar);
uchar SPI_Read(uchar reg);
void SetRX_Mode(void);
uint SPI_RW_Reg(uchar reg, uchar value);
uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars);
uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars);
unsigned char nRF24L01_RxPacket(unsigned char* rx_buf);
void nRF24L01_TxPacket(unsigned char * tx_buf);
//*****************************************长延时*****************************************
void Delay(unsigned int s)
{
unsigned int i;
for(i=0; i<s; i++);
for(i=0; i<s; i++);
}
//******************************************************************************************
uint bdata sta; //状态标志
sbit RX_DR =sta^6;
sbit TX_DS =sta^5;
sbit MAX_RT =sta^4;
/******************************************************************************************
/*延时函数
/******************************************************************************************/
void inerDelay_us(unsigned char n)
{
for(;n>0;n--)
_nop_();
}
//****************************************************************************************
/*NRF24L01初始化
//***************************************************************************************/
void init_NRF24L01(void)
{
inerDelay_us(100);
CE=0; // chip enable
CSN=1; // Spi disable
SCK=0; // Spi clock line init high
SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // 写本地地址
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); // 写接收端地址
SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // 频道0自动 ACK应答允许
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // 允许接收地址只有频道0,如果需要多频道可以参考Page21
SPI_RW_Reg(WRITE_REG + RF_CH, 0); // 设置信道工作为2.4GHZ,收发必须一致
SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32字节
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); //设置发射速率为1MHZ,发射功率为最大值0dB
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // IRQ收发完成中断响应,16位CRC,主发送
}
/****************************************************************************************************
/*函数:uint SPI_RW(uint uchar)
/*功能:NRF24L01的SPI写时序
/****************************************************************************************************/
uint SPI_RW(uint uchar)
{
uint bit_ctr;
for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit
{
MOSI = (uchar & 0x80); // output 'uchar', MSB to MOSI
uchar = (uchar << 1); // shift next bit into MSB..
SCK = 1; // Set SCK high..
uchar |= MISO; // capture current MISO bit
SCK = 0; // ..then set SCK low again
}
return(uchar); // return read uchar
}
/****************************************************************************************************
/*函数:uchar SPI_Read(uchar reg)
/*功能:NRF24L01的SPI时序
/****************************************************************************************************/
uchar SPI_Read(uchar reg)
{
uchar reg_val;

CSN = 0; // CSN low, initialize SPI communication...
SPI_RW(reg); // Select register to read from..
reg_val = SPI_RW(0); // ..then read registervalue
CSN = 1; // CSN high, terminate SPI communication

return(reg_val); // return register value
}
/****************************************************************************************************/
/*功能:NRF24L01读写寄存器函数
/****************************************************************************************************/
uint SPI_RW_Reg(uchar reg, uchar value)
{
uint status;

CSN = 0; // CSN low, init SPI transaction
status = SPI_RW(reg); // select register
SPI_RW(value); // ..and write value to it..
CSN = 1; // CSN high again

return(status); // return nRF24L01 status uchar
}
/****************************************************************************************************/
/*函数:uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)
/*功能: 用于读数据,reg:为寄存器地址,pBuf:为待读出数据地址,uchars:读出数据的个数
/****************************************************************************************************/
uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)
{
uint status,uchar_ctr;

CSN = 0; // Set CSN low, init SPI tranaction
status = SPI_RW(reg); // Select register to write to and read status uchar

for(uchar_ctr=0;uchar_ctr<uchars;uchar_ctr++)
pBuf[uchar_ctr] = SPI_RW(0); //

CSN = 1;

return(status); // return nRF24L01 status uchar
}
/*********************************************************************************************************
/*函数:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)
/*功能: 用于写数据:为寄存器地址,pBuf:为待写入数据地址,uchars:写入数据的个数
/*********************************************************************************************************/
uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)
{
uint status,uchar_ctr;

CSN = 0; //SPI使能
status = SPI_RW(reg);
for(uchar_ctr=0; uchar_ctr<uchars; uchar_ctr++) //
SPI_RW(*pBuf++);
CSN = 1; //关闭SPI
return(status); //
}
/****************************************************************************************************/
/*函数:void SetRX_Mode(void)
/*功能:数据接收配置
/****************************************************************************************************/
void SetRX_Mode(void)
{
CE=0;
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f); // IRQ收发完成中断响应,16位CRC ,主接收
CE = 1;
inerDelay_us(130);
}
/******************************************************************************************************/
/*函数:unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)
/*功能:数据读取后放如rx_buf接收缓冲区中
/******************************************************************************************************/
unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)
{
unsigned char revale=0;
sta=SPI_Read(STATUS); // 读取状态寄存其来判断数据接收状况
if(RX_DR) // 判断是否接收到数据
{
CE = 0; //SPI使能
SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);// read receive payload from RX_FIFO buffer
revale =1; //读取数据完成标志
}
SPI_RW_Reg(WRITE_REG+STATUS,sta); //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标志
return revale;
}
/***********************************************************************************************************
/*函数:void nRF24L01_TxPacket(unsigned char * tx_buf)
/*功能:发送 tx_buf中数据
/**********************************************************************************************************/
void nRF24L01_TxPacket(unsigned char * tx_buf)
{
CE=0; //StandBy I模式
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // 装载接收端地址
SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH); // 装载数据
// SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // IRQ收发完成中断响应,16位CRC,主发送
CE=1; //置高CE,激发数据发送
inerDelay_us(10);
}

/***********************************************************************************************************
/*函数:init_uart(void)
/*功能:初始化串口;波特率4800bps
/**********************************************************************************************************/
void init_uart(void)
{
SCON = 0x50;
TMOD = 0x20;
TH1 = 0xFA;
TL1 = 0xFA;
PCON = 0x00;
TR1 = 1;
}

//************************************通过串口将接收到数据发送给PC端**************************************
void R_S_Byte(uchar R_Byte)
{
SBUF = R_Byte;
while( TI == 0 ); //查询法
TI = 0;
}

//************************************工作指示灯**************************************
void power_on(void)
{
P0 = 0xfd;
Delay(6000);

P0 = 0xff;
Delay(6000);
}

//************************************主函数************************************************************
void main(void)
{
uchar i;
uchar temp =0;

init_uart();
init_NRF24L01();

nRF24L01_TxPacket(TxBuf); // Transmit Tx buffer data

Delay(6000);

//CE = 1;
while(1)
{
power_on();
nRF24L01_TxPacket(TxBuf);
SPI_RW_Reg(WRITE_REG+STATUS,0XFF);
Delay(100);
//Delay(6000);
TxBuf[31] = TxBuf[31] + 1;
}
}

‘柒’ 如何使用vue.js中的$watch

Observer, Watcher, vm 可谓 Vue 中比较重要的部分,检测数据变动后视图更新的重要环节。下面我们来看看 如何实现一个简单的 $watch 功能,当然Vue 中使用了很多优化手段,在本文中暂不一一讨论。
例子:
// 创建 vm
let vm = new Vue({
data: 'a'
})

// 键路径
vm.$watch('a.b.c', function () {
// 做点什么
})

先阐明在这个 demo 以及Vue 中,它们的关系:
vm 调用 $watch 后,首先调用 observe 函数 创建 Observer 实例观察数据,Observer 又创建 Dep , Dep 用来维护订阅者。然后创建 Watcher 实例提供 update 函数。一旦数据变动,就层层执行回调函数。

‘捌’ vue watch用法需要自己写吗

Observer, Watcher, vm 可谓 Vue 中比较重要的部分,检测数据变动后视图更新的重要环节。下面我们来看看 如何实现一个简单的 $watch 功能,当然Vue 中使用了很多优化手段,在本文中暂不一一讨论。
例子:
// 创建 vm
let vm = new Vue({
data: 'a'
})
// 键路径
vm.$watch('a.b.c', function () {
// 做点什么
})
先阐明在这个 demo 以及Vue 中,它们的关系:
vm 调用 $watch 后,首先调用 observe 函数 创建 Observer 实例观察数据,Observer 又创建 Dep , Dep 用来维护订阅者。然后创建 Watcher 实例提供 update 函数。一旦数据变动,就层层执行回调函数。

阅读全文

与observe函数源码相关的资料

热点内容
喷油螺杆制冷压缩机 浏览:579
python员工信息登记表 浏览:377
高中美术pdf 浏览:161
java实现排列 浏览:513
javavector的用法 浏览:982
osi实现加密的三层 浏览:233
大众宝来原厂中控如何安装app 浏览:916
linux内核根文件系统 浏览:243
3d的命令面板不见了 浏览:526
武汉理工大学服务器ip地址 浏览:149
亚马逊云服务器登录 浏览:525
安卓手机如何进行文件处理 浏览:71
mysql执行系统命令 浏览:930
php支持curlhttps 浏览:143
新预算法责任 浏览:444
服务器如何处理5万人同时在线 浏览:251
哈夫曼编码数据压缩 浏览:426
锁定服务器是什么意思 浏览:385
场景检测算法 浏览:617
解压手机软件触屏 浏览:350