nrf51822之间通讯

来源:互联网 发布:淘宝网商城棉服 编辑:程序博客网 时间:2024/06/03 14:15

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,blue    gpio_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的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,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.21  nrf_gpio_pin_set(22);//green灭p0.22          nrf_gpio_pin_set(23);// blue灭p0.23// 设置有效载荷指针        NRF_RADIO->PACKETPTR    = (uint32_t)packet;//指针指向数据缓冲packet            while(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个char  if ((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,在此感谢!

1 0
原创粉丝点击