nrf51822之间通讯
                                                            生活随笔
收集整理的這篇文章主要介紹了
                                nrf51822之间通讯
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.                        
                                GPIO引腳配置:
//大家51單片機用過嗎?知道P0 ,P1 ,P2 ,P3這些io口嗎? //因為nrf51822是32位單片機。用下面的代碼可以拆成8位單片機用。使用的效果就和51單片機一模一樣 //可以P1=0x0f;這樣51822的P0.8~P0.15腳就被設置了 typedef enum {NRF_GPIO_PORT_SELECT_PORT0 = 0, ///< Port 0 (GPIO pin 0-7)NRF_GPIO_PORT_SELECT_PORT1, ///< Port 1 (GPIO pin 8-15)NRF_GPIO_PORT_SELECT_PORT2, ///< Port 2 (GPIO pin 16-23)NRF_GPIO_PORT_SELECT_PORT3, ///< Port 3 (GPIO pin 24-31) } nrf_gpio_port_select_t;//定義P口,用法和51單片機一樣用P0,P1,P2,P3 #define P0 NRF_GPIO_PORT_SELECT_PORT0 //P0.0~P0.7(P0.0~P0.07) #define P1 NRF_GPIO_PORT_SELECT_PORT1 //P1.0~P1.7(P0.8~P0.15) #define P2 NRF_GPIO_PORT_SELECT_PORT2 //P2.0~P2.7(P0.16~P0.23) #define P3 NRF_GPIO_PORT_SELECT_PORT3 //P3.0~P3.7(P0.24~P0.31)發射程序:
//arm_startup_nrf51.s是啟動文件,包含中斷定義 //#include "nrf51.h"//包含51822各個寄存器結構地址。以上2文件就可以控制51822了。 //nrf51_bitfields.h包含各個寄存器設置值的作用 #include "project_nrf51822.c"//包含51822工程需要用到的頭文件(晶振,延時,io腳什么的#include <stdbool.h>//調用bool #include "stdio.h"//標準輸入輸出 #include <stdint.h>//聲明已知大小的整數或顯示特征的整數//packet[3]中QxC(Q開始,C結束,x是數據char) static uint8_t packet[3]={'Q','0','C'}; //數據傳輸用QxC(Q代表開始,C代表結束,x代表數據)void init(void)//51822時鐘初始化 { //判斷電源時鐘狀態if ((((*(uint32_t *)0xF0000FE0) & 0xFF) == 1) && (((*(uint32_t *)0xF0000FE4) & 0xF) == 0)){if ((((*(uint32_t *)0xF0000FE8) & 0xF0) == 0x0) && (((*(uint32_t *)0xF0000FEC) & 0xF0) == 0x0)){//解決radio無法寫入 *(uint32_t *)0x40000504 = 0xC007FFDF;//電源時鐘設置*(uint32_t *)0x40006C18 = 0x00008000;//GPIOTE設置 }else if ((((*(uint32_t *)0xF0000FE8) & 0xF0) == 0x10) && (((*(uint32_t *)0xF0000FEC) & 0xF0) == 0x0)){//解決radio無法寫入 *(uint32_t *)0x40000504 = 0xC007FFDF;//電源時鐘設置*(uint32_t *)0x40006C18 = 0x00008000;//GPIOTE設置 }else if ((((*(uint32_t *)0xF0000FE8) & 0xF0) == 0x30) && (((*(uint32_t *)0xF0000FEC) & 0xF0) == 0x0)){//解決radio無法寫入 *(uint32_t *)0x40000504 = 0xC007FFDF;//電源時鐘設置*(uint32_t *)0x40006C18 = 0x00008000;//GPIOTE設置 }}NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;//HFCLK晶振運行狀態標志位 0關閉,1運行NRF_CLOCK->TASKS_HFCLKSTART = 1;//高外晶振HFCLK 0關閉,1啟動while(!NRF_CLOCK->EVENTS_HFCLKSTARTED);//等待HFCLK晶振運行狀態標志位 為1 }void ioinit()//51822引腳初始化 {//接收用usb-jtag的nrf51822 // gpio_init_in(9,9,3);//p0.09輸入 // gpio_init_in(11,11,3);//p0.11輸入 // gpio_init_out(21,23);//led:red,green,bluegpio_init_out(0,15);//設置0~15腳配置為輸出gpio_init_in(16,17,3);//設置16~17腳配置為輸入3代表上拉電阻(開發板為按鈕key0,key1)gpio_init_out(18,25);//設置18~25腳配置為輸出/那個26~27接的是低速晶振gpio_init_out(28,31);//設置28~31腳配置為輸出 }int main(void)//main主程序開始 {init();//時鐘初始化ioinit();//引腳初始化radio_configure();//無線電配置(也可用于和nrf2401通訊)// 設置有效載荷指針NRF_RADIO->PACKETPTR = (uint32_t)packet;//指針指向數據緩沖packet //檢查io腳是否正常NRF_GPIO->OUTSET=(1<<22);//led4亮,表示51822已經工作中while(1){packet[1]= (NRF_GPIO->IN>>16)&3; //讀到的key0,key1數據給發射緩沖nrf_gpio_pin_clear(18);//led0滅,表示數據還沒發出//數據準備發送NRF_RADIO->EVENTS_READY = 0U;//收發模式轉換完成標志位。復位NRF_RADIO->TASKS_TXEN = 1U;//啟動無線電為發射模式while (NRF_RADIO->EVENTS_READY == 0U);//等待收發模式轉換完成// Start transmission.NRF_RADIO->EVENTS_END = 0U;//傳輸完成標志位,復位 NRF_RADIO->TASKS_START = 1U;//開始傳輸while(NRF_RADIO->EVENTS_END == 0U) //等待傳輸完成{nrf_gpio_pin_clear(18);//傳輸失敗led0滅// Do nothing.}// 組1引腳(8~15)nrf_gpio_port_write(P1, packet[1]);//數值顯示在單片機P1口上nrf_gpio_pin_set(18);//傳輸成功led0亮,越暗說明有干擾,需要改頻率NRF_RADIO->EVENTS_DISABLED = 0U;//無線關閉標志位 復位NRF_RADIO->TASKS_DISABLE = 1U; // 關閉無線while(NRF_RADIO->EVENTS_DISABLED == 0U)//等待無線關閉{// Do nothing.}} }
 
接收程序:
//arm_startup_nrf51.s是啟動文件,包含中斷定義 //#include "nrf51.h"//包含51822各個寄存器結構地址。以上2文件就可以控制51822了。 //nrf51_bitfields.h包含各個寄存器設置值的作用 #include "project_nrf51822.c"//包含51822工程需要用到的頭文件(晶振,延時,io腳什么的#include <stdbool.h>//調用bool #include "stdio.h"//標準輸入輸出 #include <stdint.h>//聲明已知大小的整數或顯示特征的整數void init(void)//51822時鐘初始化 { //判斷電源時鐘狀態if ((((*(uint32_t *)0xF0000FE0) & 0xFF) == 1) && (((*(uint32_t *)0xF0000FE4) & 0xF) == 0)){if ((((*(uint32_t *)0xF0000FE8) & 0xF0) == 0x0) && (((*(uint32_t *)0xF0000FEC) & 0xF0) == 0x0)){//解決radio無法寫入 *(uint32_t *)0x40000504 = 0xC007FFDF;//電源時鐘設置*(uint32_t *)0x40006C18 = 0x00008000;//GPIOTE設置 }else if ((((*(uint32_t *)0xF0000FE8) & 0xF0) == 0x10) && (((*(uint32_t *)0xF0000FEC) & 0xF0) == 0x0)){//解決radio無法寫入 *(uint32_t *)0x40000504 = 0xC007FFDF;//電源時鐘設置*(uint32_t *)0x40006C18 = 0x00008000;//GPIOTE設置 }else if ((((*(uint32_t *)0xF0000FE8) & 0xF0) == 0x30) && (((*(uint32_t *)0xF0000FEC) & 0xF0) == 0x0)){//解決radio無法寫入 *(uint32_t *)0x40000504 = 0xC007FFDF;//電源時鐘設置*(uint32_t *)0x40006C18 = 0x00008000;//GPIOTE設置 }}NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;//HFCLK晶振運行狀態0關閉,1運行NRF_CLOCK->TASKS_HFCLKSTART = 1;//高外晶振HFCLK 0關閉,1啟動while(!NRF_CLOCK->EVENTS_HFCLKSTARTED);//等待HFCLK晶振運行狀態為1 }void ioinit()//51822引腳初始化 {//接收用usb-jtag的nrf51822gpio_init_in(9,9,3);//p0.09輸入gpio_init_in(11,11,3);//p0.11輸入gpio_init_out(21,23);//led:red,green,blue// gpio_init_out(0,15);//設置0~15腳配置為輸出 // gpio_init_in(16,17,3);//設置16~17腳配置為輸入(開發板為按鈕key0,key1) // gpio_init_out(18,25);//設置18~25腳配置為輸出/那個26~27接的是低速晶振 // gpio_init_out(28,31);//設置28~31腳配置為輸出 }//packet[3]中QxC(Q開始,C結束,x是數據char) static uint8_t volatile packet[3]; //< 數據傳輸的緩沖包packet[1]是數據int main(void)//main主程序開始 {init();//時鐘初始化ioinit();//引腳初始化radio_configure();//無線電配置(也可用于和nrf2401通訊)//檢查io腳是否正常nrf_gpio_pin_set(21);// red滅p0.21nrf_gpio_pin_set(22);//green滅p0.22nrf_gpio_pin_set(23);// blue滅p0.23// 設置有效載荷指針NRF_RADIO->PACKETPTR = (uint32_t)packet;//指針指向數據緩沖packetwhile(1){NRF_RADIO->EVENTS_READY = 0U; //收發模式轉換完成 標志位 NRF_RADIO->TASKS_RXEN = 1U; //接收模式while(NRF_RADIO->EVENTS_READY == 0U) //等待收發模式轉換完成(接收模式)標志位{// Do nothing.等待}NRF_RADIO->EVENTS_END = 0U;//傳輸完成 標志位 NRF_RADIO->TASKS_START = 1U; // 開始傳輸while(NRF_RADIO->EVENTS_END == 0U)//等待傳輸完成 標志位{nrf_gpio_pin_set(23);// blue滅 //傳輸不成功// Do nothing.等待}if (NRF_RADIO->CRCSTATUS == 1U)//如果CRC校驗正確{//nrf_gpio_port_write(NRF_GPIO_PORT_SELECT_PORT1, packet[0]);if(packet[0]==('Q'))//確定開始{if(packet[2]==('C'))//結束正確{ NRF_GPIO->OUT=(packet[1]<<21);//數據給io腳nrf_gpio_pin_clear(23);// blue亮,數據成功了,燈越暗說明數據傳輸越快。//不亮說明,數據傳輸失敗。}}}NRF_RADIO->EVENTS_DISABLED = 0U;//無線關閉 標志位NRF_RADIO->TASKS_DISABLE = 1U;// 關閉無線設備while(NRF_RADIO->EVENTS_DISABLED == 0U)//等待設備關閉{// Do nothing.}} }無線電配置:
//無線功率4分貝,2440MHz,通道0地址0x99999999C0,通道1~7地址0x66666666XX //速率2MHz,數據字節3字節QxC(Q開始,C結束,x是數據char) void radio_configure()//無線配置,準備和nrf24L01通訊 {//無線功率04:+4分貝,0:0分貝,FC:-4分貝,F8:-8分貝// F4:-12分貝,F0:-16分貝,EC:-20分貝,D8:-30分貝NRF_RADIO->TXPOWER = (0x04<<0);//無線功率4分貝NRF_RADIO->FREQUENCY = 40UL;//無線頻率40MHz+2400MHz=2440MHz//無線速率:00:1Mbit,01:2Mbit,02:250Kbit,03:1Mbit(藍牙)NRF_RADIO->MODE = (01<<0);//速率2MHz// 無線地址設置NRF_RADIO->PREFIX0 = 0xC3C2C1C0UL; // 通道3 到 0 的低1字節NRF_RADIO->PREFIX1 = 0xC7C6C5C4UL; // 通道7 到 4 的低1字節NRF_RADIO->BASE0 = 0x99999999UL; // 通道0的高字節NRF_RADIO->BASE1 = 0x66666666UL; // 通道1-7的高字節NRF_RADIO->TXADDRESS = 0x00UL; // 發射使用的通道號:0通道NRF_RADIO->RXADDRESSES = 0x01UL; // 接收的通道號:1通道// 配置包0的設置NRF_RADIO->PCNF0 = (0<<16)| //S1領域的長度(0<<8) | //S0場的長度(0<<0); //長度字段中的比特數// 配置包1的設置NRF_RADIO->PCNF1 = (0<<25)| //效驗位(0關,1開)(1<<24)| //數據大小端(高低字節哪個先發 0低字節,1高字節)(4<<16)| //通道1~7高字節長度( nrf24高低字節5字節:4個高+1個低)(3<<8) | //數據字節長度(255~1)3字節QxC(3<<0); //硬件傳輸字節長度(255~1)3字節QxC// CRC 校驗長度配置NRF_RADIO->CRCCNF = 2; // 校驗長度 2個charif ((NRF_RADIO->CRCCNF & 0x03)== 2 ){NRF_RADIO->CRCINIT = 0xFFFFUL; // 校驗初始值NRF_RADIO->CRCPOLY = 0x11021UL; // CRC poly: x^16+x^12^x^5+1}else if ((NRF_RADIO->CRCCNF & 0x03) == 1 ){NRF_RADIO->CRCINIT = 0xFFUL; // 校驗初始值NRF_RADIO->CRCPOLY = 0x107UL; // CRC poly: x^8+x^2^x^1+1}//接收寄存器是 NRF_RADIO->PACKETPTR }轉載自:http://www.openedv.com/posts/list/0/25014.htm?privmsg=1,在此感謝!
 
 
總結
以上是生活随笔為你收集整理的nrf51822之间通讯的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 珠海公共自行车系统分析系列 - 前言
- 下一篇: 回溯算法(全排列、组合、N皇后问题)
