本帖最后由 xiao_yp2014 于 2016-6-7 13:58 編輯
nRF24L01應(yīng)用筆記
nRF24L01是Nordic公司生產(chǎn)的一個(gè)單芯片射頻收發(fā)器件,是目前應(yīng)用比較廣泛的一款無(wú)線通訊芯片,具體手冊(cè)資料網(wǎng)上大把,我就不再重復(fù)它的特性什么的了,直接說(shuō)說(shuō)它的調(diào)試方法,方法供大家參考。 24L01是收發(fā)雙方都需要編程的器件,這就對(duì)調(diào)試方法產(chǎn)生了一定的要求,如果兩塊一起調(diào),那么通訊不成功,根本不知道是發(fā)的問(wèn)題還是收的問(wèn)題,不隱晦的說(shuō),我當(dāng)時(shí)也是沒(méi)理清調(diào)試思路才浪費(fèi)了大半天時(shí)間看著模塊干瞪眼。正確的方法應(yīng)該是先調(diào)試發(fā)送方,能保證發(fā)送正確,再去調(diào)接收,這樣就可以有針對(duì)性的解決問(wèn)題。
至于怎么去調(diào)發(fā)送方,先說(shuō)下發(fā)送方的工作流程:
·配置寄存器使芯片工作于發(fā)送模式后拉高CE端至少10us ·讀狀態(tài)寄存器STATUS ·判斷是否是發(fā)送完成標(biāo)志位置位 ·清標(biāo)志 ·清數(shù)據(jù)緩沖
網(wǎng)上的程序我也看過(guò),大多都是成品,發(fā)送方發(fā)送-等應(yīng)答-(自動(dòng)重發(fā))-觸發(fā)中斷�?墒沁@樣的流程就已經(jīng)把接收方給牽涉進(jìn)來(lái)了,就是說(shuō)一定要接收方正確收到數(shù)據(jù)并且回送應(yīng)答信號(hào)之后發(fā)送方才能觸發(fā)中斷,結(jié)束一次完整的發(fā)送�?墒沁@跟我們的初衷不相符,我們想單獨(dú)調(diào)試發(fā)送,完全拋開接收,這樣就要去配置一些參數(shù)來(lái)取消自動(dòng)應(yīng)答,取消自動(dòng)重發(fā),讓發(fā)送方達(dá)到發(fā)出數(shù)據(jù)就算成功的目的。 - SPI_RW_Reg(WRITE_REG + EN_AA, 0x00); //失能通道0自動(dòng)應(yīng)答
- SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x00); //失能接收通道0
- SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x00); //失能自動(dòng)重發(fā)
復(fù)制代碼
(注:以下貼出的寄存器描述由于中文資料上有一個(gè)錯(cuò)誤,故貼出原版英文資料)
有了以上這三個(gè)配置,發(fā)送方的流程就變成了發(fā)送-觸發(fā)中斷。這樣就拋開了接收方,可以專心去調(diào)試發(fā)送,可是怎么樣才知道發(fā)送是否成功呢,要用到另外兩個(gè)寄存器,STATUS和FIFO_STATUS。 這樣就很清晰了,我們可以通過(guò)讀取STATUS的值來(lái)判斷是哪個(gè)事件觸發(fā)了中斷,寄存器4、5、6位分別對(duì)應(yīng)自動(dòng)重發(fā)完成中斷,數(shù)據(jù)發(fā)送完成中斷,數(shù)據(jù)接收完成中斷。也就是說(shuō),在之前的配置下,如果數(shù)據(jù)成功發(fā)送,那么STATUS的值應(yīng)該為0x2e。這樣就可以作為一個(gè)檢測(cè)標(biāo)準(zhǔn),另外一個(gè)標(biāo)準(zhǔn)可以看FIFO_STATUS寄存器,第5位的描述:發(fā)送緩沖器滿標(biāo)志,1為滿,0為有可用空間;第4位的描述:發(fā)送緩沖器空標(biāo)志,1為空,0為有數(shù)據(jù);同樣可以看到接收緩沖器的對(duì)應(yīng)標(biāo)志。這樣在數(shù)據(jù)發(fā)送成功后,發(fā)送寄存器當(dāng)然應(yīng)該是空的,接收緩沖因?yàn)樵谥耙呀?jīng)失能,所以也應(yīng)該是空,也就是說(shuō)成功發(fā)送之后的FIFO_STATUS寄存器值應(yīng)該是0x11。 有了這兩個(gè)檢測(cè)標(biāo)準(zhǔn),我們即使不用接收方也可以確定發(fā)送方是否成功發(fā)送。當(dāng)發(fā)送方調(diào)試成功之后,在程序里讓它一直發(fā)送,然后我們就可以去調(diào)試接收方,思路是一樣的,同樣說(shuō)下接收方工作流程先。
·配置寄存器使芯片工作于接收模式后拉高CE端至少130us ·讀狀態(tài)寄存器STATUS ·判斷是否是接收完成標(biāo)志位置位 ·清標(biāo)志 ·讀取數(shù)據(jù)緩沖區(qū)的數(shù)據(jù) ·清數(shù)據(jù)緩沖
然后在初始化配置寄存器的時(shí)候要和發(fā)送方保持一致,比較重要的是要失能自動(dòng)應(yīng)答,使能通道0接收: - SPI_RW_Reg(WRITE_REG + EN_AA, 0x00); //失能通道0自動(dòng)應(yīng)答
- SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); //接收要使能接收通道0
復(fù)制代碼
這樣就可以了,接收方就可以進(jìn)入接收模式去接收數(shù)據(jù)了,這次的調(diào)試就會(huì)靈活一些,因?yàn)槭墙邮諗?shù)據(jù),可以在接收方添加一個(gè)顯示設(shè)備把數(shù)據(jù)直觀的顯示出來(lái),去對(duì)照看是否正確,當(dāng)然還可以使用和發(fā)送方一樣的方法:觀察STATUS和FIFO_STATUS的值,對(duì)照寄存器描述,接收正確時(shí)STATUS的值應(yīng)該是0x40,對(duì)于FIFO_STATUS的情況就多了些,因?yàn)閿?shù)據(jù)寬度的不同也會(huì)造成寄存器的值不一樣,24L01最大支持32字節(jié)寬度,就是說(shuō)一次通訊最多可以傳輸32個(gè)字節(jié)的數(shù)據(jù),在這種情況下,接收成功讀數(shù)據(jù)之前寄存器值應(yīng)該為0x12,讀數(shù)據(jù)之后就會(huì)變成0x11;如果數(shù)據(jù)寬度定義的小于32字節(jié),那么接收成功讀數(shù)據(jù)之前寄存器值應(yīng)該為0x10,讀數(shù)據(jù)之后就會(huì)變成0x11。這個(gè)看起來(lái)挺復(fù)雜,其實(shí)很清晰,大家可以試著分析下,對(duì)照數(shù)據(jù)手冊(cè)分析每個(gè)位的狀態(tài)就可以得到結(jié)果。
好了,到這里對(duì)nRF24L01的調(diào)試基本上就算通了,但是要明白這些只是調(diào)試方法,最終的產(chǎn)品如果不加上應(yīng)答和重發(fā)的話那么數(shù)據(jù)的穩(wěn)定性是很難保證的,所以在基本的通訊建立之后就要把發(fā)送的配置改為: - 發(fā)送:
- SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); //使能接收通道0自動(dòng)應(yīng)答
- SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); //使能接收通道0
- SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x1a); //自動(dòng)重發(fā)10次,間隔500us
- 接收:
- SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); //失能通道0自動(dòng)應(yīng)答
- SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); //接收要使能接收通道0
復(fù)制代碼
這樣發(fā)送和接收就進(jìn)入了一個(gè)標(biāo)準(zhǔn)狀態(tài),發(fā)送-等應(yīng)答-(自動(dòng)重發(fā))-觸發(fā)中斷;接收-應(yīng)答-觸發(fā)中斷,一切按部就班,程序里加上自己的應(yīng)用部分就能實(shí)現(xiàn)很多功能了,呵呵,這個(gè)帖子就先到這,明白芯片工作原理之后寫程序就有目的性了,下一篇再說(shuō)說(shuō)程序中查詢法和中斷法以及具體的程序?qū)嵗?/font>
|