導航:首頁 > 源碼編譯 > 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