原创 无线收发 24L01程序

2009-8-7 19:30 10328 9 19 分类: 通信

最近项目基本都做完了,闲着没事了,过来整理下博客,分享下自己的程序!这是几个月前调通的程序,24L01无线收发芯片,mcu用的是msp430f2274!该程序花费了我大量心血!算是我学起单片机来攻克的第一块芯片吧!注释相当详细!


#include<msp430x22x4.h>
#define uint unsigned int
#define uchar unsigned char
//nRF24L01的数据宽度,地址宽度,以及数据定义
#define TX_ADR_WIDTH 4
#define RX_PLOAD_WIDTH 4
#define TX_PLOAD_WIDTH 4
uchar TX_ADDRESS[]={0xe7,0xe7,0xe7,0xe7};
uchar data[4]="zhou";
uchar rx_buf[4];
//引脚定义2274
#define CSN_HIGH P3OUT|=BIT1//P3.1控制SPI使能
#define CSN_LOW P3OUT&=~BIT1
#define CE_HIGH P3OUT|=BIT2//P3.2控制芯片发射使能
#define CE_LOW P3OUT&=~BIT2
#define IRQ P3IN&BIT3//读取P3.3的值*/
                                              /***********模拟SPI方式***********/
                                              #define MOSI_HIGH P3OUT|=BIT4
                                              #define MOSI_LOW P3OUT&=~BIT4
                                              #define MISO P3IN&BIT5
                                              #define SCK_HIGH P3OUT|=BIT0
                                              #define SCK_LOW P3OUT&=~BIT0
//24L01寄存器地址
#define CONFIG 0X00//配置寄存器地址
#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
#define RX_ADDR_P2 0X0C
#define RX_ADDR_P3 0X0D
#define RX_ADDR_P4 0X0E
#define RX_ADDR_P5 0X0F
#define TX_ADDR 0X10//发送地址寄存器地址
#define RX_PW_P0 0X11//接收地址通道0有效数据宽度
#define RX_PW_P1 0X12
#define RX_PW_P2 0X13
#define RX_PW_P3 0X14
#define RX_PW_P4 0X15
#define RX_PW_P5 0X16
#define FIFO_STATUS 0X17//FIFO状态寄存器
//SPI命令字
#define READ_REG 0X00//读寄存器命令
#define WRITE_REG 0X20//写寄存器命令
#define RD_RX_PLOAD 0X61//读有效数据命令
#define WR_TX_PLOAD 0XA0//写有效数据命令
#define FLUSH_TX 0XE1//清除TX_FIFO应用于发射模式
#define FLUSH_RX 0XE2//清除RX_FIFO应用于接收模式
#define REUSE_TX_PL 0XE3//重新使用上一包有效数据
#define NOP 0XFF//空操作指令
//延时子函数us
void delay_us(uint i)
{
  while(i--)
    _NOP();
}
/*//SPI初始化程序2274
void SPI_INIT()
{
  UCA0CTL0 |=UCMSB + UCMST + UCSYNC;// 3-pin, 8-bit SPI master
  UCA0CTL1 |= UCSSEL_1; // ACLK
  UCA0BR0 |= 0x03;//波特率9600
  UCA0BR1 = 0;
  UCA0MCTL = 0X91;
  UCA0CTL1 &= ~UCSWRST; 
  P3SEL|=BIT0+BIT4+BIT5;
}
//正宗SPI写一字节数据到24L01,同时返回一个自己的数据2274
uchar SPI_RW(uchar byte)
{
  while (!(IFG2 & UCA0TXIFG));
  UCA0TXBUF=byte;
  delay_us(200);
  return UCA0RXBUF;
}*/
                                  //模拟SPI方式
                                    uchar SPI_RW(uchar byte)
                                    {
                                      uchar bit_ctr;
                                      uchar a,b;
                                      for(bit_ctr=0;bit_ctr<8;bit_ctr++)
                                      {
                                        a=(byte&0x80);
                                        if(a!=0)
                                          MOSI_HIGH;
                                        else
                                          MOSI_LOW;
                                        byte=(byte<<1);
                                        SCK_HIGH;
                                        b="P3IN"&BIT5;   
                                        if(b!=0)
                                          byte+=1;
                                        else;
                                        SCK_LOW;
                                      }
                                      return byte;
                                    }


//向寄存器写一字节的数据,同时返回状态字
uchar SPI_RW_Reg(uchar reg,uchar value)
{
  uchar status;
  CSN_LOW;
  status="SPI"_RW(reg);
  SPI_RW(value);
  CSN_HIGH;
  return(status);
}
//向寄存器读出一字节的数据
uchar SPI_Read(uchar reg)
{
  uchar byte;
  CSN_LOW;
  SPI_RW(reg);
  byte="SPI"_RW(0x00);//写入一个0x00,读出数据
  CSN_HIGH;
  return byte;
}
//读出bytes字节的数据
uchar SPI_Read_Buf(uchar reg,uchar *pBuf,uchar bytes)
{
  uchar status,byte_ctr;
  CSN_LOW;
  status="SPI"_RW(reg);//选择寄存器,并返回状态
  for(byte_ctr=0;byte_ctr<bytes;byte_ctr++)
    pBuf[byte_ctr]=SPI_RW(0);
  CSN_HIGH;
  return(status);
}
//写入bytes字节的数据
uchar SPI_RW_Buf(uchar reg,uchar *pBuf,uchar bytes)
{
  uchar status,byte_ctr;
  CSN_LOW;
  status="SPI"_RW(reg);
  for(byte_ctr=0;byte_ctr<bytes;byte_ctr++)
    SPI_RW(*pBuf++);
  CSN_HIGH;
  return(status);
}
//接收函数,接收返回1表示有数据收到
uchar nRF24L01_RxPacket(uchar *rx_buf)
{
  uchar sta;
  uchar revale="0";
  SPI_RW_Reg(WRITE_REG+CONFIG,0X0F);
  CE_HIGH;
  delay_us(130);
  sta="SPI"_Read(READ_REG+STATUS);
  while(sta&0x40)
  {
    CE_LOW;//进入闲置模式
    SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);/*数据宽度未定义*/
    revale="0xff";//如果有数据收到,则点亮led
  }
  SPI_RW_Reg(WRITE_REG+STATUS,sta);
  return revale;
}
//发送函数
void  nRF24L01_TxPacket(uchar *tx_buf)
{
  //stand by 模式
  CE_LOW;
  //给发送寄存器写入地址,宽度为TX_ADR_WIDTH
  SPI_RW_Buf(WRITE_REG+TX_ADDR,TX_ADDRESS,TX_ADR_WIDTH);
  //给接收寄存器写入地址,宽度也为TX_ADR_WIDTH
  SPI_RW_Buf(WRITE_REG+RX_ADDR_P0,TX_ADDRESS,TX_ADR_WIDTH);
  SPI_Read_Buf(RX_ADDR_P0,rx_buf,TX_ADR_WIDTH);
  //向发送寄存器写入TX_PLOAD_WIDTH宽度的数据,
  SPI_RW_Buf(WR_TX_PLOAD,tx_buf,TX_PLOAD_WIDTH);
  //配置为PWR_UP位,使能CRC,16位校验,发送模式
  SPI_RW_Reg(WRITE_REG+CONFIG,0X0E);
  CE_HIGH;
  delay_us(10);
  CE_LOW;
}
//nRF24L01的配置函数
void nRF24L01_Config()
{
  CE_LOW;//芯片使能
  CSN_HIGH;//SPI复位
  //使能接收模式
  SPI_RW_Reg(WRITE_REG+CONFIG,0X0F);
  SPI_Read(CONFIG);
  //数据通道0自动应答
  SPI_RW_Reg(WRITE_REG+EN_AA,0X01);
  SPI_Read(EN_AA);
  //通道0允许
  SPI_RW_Reg(WRITE_REG+EN_RXADDR,0X01);
  //设置地址宽度为4字节
  SPI_RW_Reg(WRITE_REG+SETUP_AW,0X02);
  //建立自动重发,500+86us,10次重发
  SPI_RW_Reg(WRITE_REG+SETUP_RETR,0X1A);
  //设置工作通道频率
  SPI_RW_Reg(WRITE_REG+RF_CH,0x02);
  //设置工作通道传输速率为1Mbps,发射功率为0dBm
  SPI_RW_Reg(WRITE_REG+RF_SETUP,0X03);
  //设置通道0有效数据宽度RX_PLOAD_WIDTH
  SPI_RW_Reg(WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH); 
 
}
void IO_INIT()
{
  P3DIR|=BIT0+BIT1+BIT2+BIT4;
}


void main()
{
  uchar sta;      
  WDTCTL="WDTPW"+WDTHOLD;
  IO_INIT();
//  SPI_INIT();
  nRF24L01_Config();
  while(1)
  {
  nRF24L01_TxPacket(data);
  sta="SPI"_Read(READ_REG+STATUS);
  if(sta&0x20);
  SPI_RW_Reg(WRITE_REG+STATUS,sta);
  delay_us(10000);
  }
}

PARTNER CONTENT

文章评论10条评论)

登录后参与讨论

用户1645455 2011-4-3 14:53

刚学习,

用户1373959 2010-5-18 21:27

nice

用户277995 2010-5-6 22:50

谢谢分享!

用户222124 2009-12-31 11:41

呵呵,能交流下么?QQ 569350810 24L01 读状态正确,但是读出数据全是0X08 不知道是为什么

用户124881 2009-12-16 08:59

搂主忍耐了,现在都是这样,你还要调整一下心态,凡是你贴上来的就要做好被人转的心理准备,要是担心的话,还是不要铁上来的好

用户515414 2009-11-10 16:47

我很郑重的告诉你,这是我原创,当我同学告诉我,现在很多人把这个程序直接贴到其他地方,也不注明出处,对此我感觉很无语!但是学习交流么,对我来说也不存在什么经济利益,不过请各位尊重我的学习成果

用户1664001 2009-11-8 07:47

你那就是网上的历程,注释都是一样的。

用户1531813 2009-9-2 08:39

谢谢楼主了~~~

用户246181 2009-8-28 16:43

谢谢分享

用户1414082 2009-8-21 00:24

谢谢分享! 前段时间没调出来,先看看,有时间再调下~
相关推荐阅读
用户515414 2010-04-28 22:18
第一天
capture CIS中的快捷键原理图页面编辑 CTRL+A 全选所有原理图页面编辑 B 放置总线BUS原理图页面编辑 E 放置总线BUS 的分支Entry原理图页面编辑 F 放置电源符号原理图页面编...
用户515414 2010-04-27 20:33
准备做个板
从咸宁过来武大有半年了,一直忙着毕业的事情以及导师的项目,很久没有更新空间了,现在项目闲下来了,也该做做自己的事情了,准备画一个2440的开发板。想每天上来更新下自己的进度,记录下,也能让自己坚持下去...
用户515414 2009-09-18 13:01
关于ARM7时钟的问题
在ARM7处理器中,在没有配置PLL和VPB分频器前,系统时钟Fcclk就是外部晶振的时钟Fosc,内部VPB总线的时钟是Fcclk/4也就是说是Fosc/4,开始关于时钟这章的疑惑就在这里。网上有学...
用户515414 2009-09-15 18:38
msp430开发板
对msp430的一个总结板,集成了学习430来做过的一些东西,彩色触摸液晶屏,24L01,DDS AD9851……正面反面https://static.assets-stash.eet-china.c...
用户515414 2009-09-09 11:10
开始学习ARM了
开始两天了,今天终于能在Proteus里仿真lpc2100了,对系统启动的过程也有了个大致的认识,再过两天我的板子就到了。...
用户515414 2009-08-30 15:04
AD603调试心得
在众多网友的经验下,AD603的调试也算是顺风顺水,半天解决了,开始直接照着PDF搭了个模式二的电路,直接将函数发生器的信号输入进来,波形严重失真,扭曲的不成样子,频率也不对,并且增益不可控,但是很稳...
EE直播间
更多
我要评论
10
9
关闭 站长推荐上一条 /3 下一条