qq511153186 发表于 2013-6-25 22:22:46

关于NRF905的收发问题

本人在做一个以NRF905收发信号来联系不同的电路板(3块电路板,此为主控板),此板接收到另一块板子发来的温度值(有实际温度值和标准温度值),这个程序是比较那块板子发送过来的温度值,然后问题就来了,我接收到的温度值存在RxBuf[4】数组中,但是
if(RxBuf<RxBuf)          //实际温度与标准温度比
if(RxBuf>RxBuf)
这个比较出不来结果,如果我改成if(RxBuf<34)就可以,不知道是不是我nrf905程序出问题,希望各位大神看一下:(如有地方编程不规范望指正)
#include <regx55.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
//--------------------------------------SPI接口指令的宏定义-----nrf905控制指令-------------------------------------------------------------
#define WC                0x00               //        写配置寄存器
#define RC                0x10               //        读配置寄存器
#define WTP                0x20               //        向TX_PAYLOAD寄存器写入发送有效数据
#define RTP                0x21               //        从TX_PAYLOAD寄存器读取发送有效数据
#define WTA                0x22               //        向TX_ADRESS寄存器写入发送地址
#define RTA                0x23               //        从TX_ADRESS寄存器读取发送地址
#define RRP                0x24               //        从TX_PAYLOAD寄存器读取接收到的有效数据
//----------------------------------------------------------------------------------------------------------------
bdata uchar DATA_BUF;
sbit        flag=DATA_BUF^7;
sbit        flag1=DATA_BUF^0;
//--------------------------------发送数据缓冲区-------------------------------------------------
uchar TxBuf=
{
0,0,0,0
};
uchar RxBuf=
{
0,0,0,0
};
//------------------------------NRF905发地址------------------------------------------------------
code TxAddress={0x4c,0x4c,0x4c,0x4c};
//-------------------------------NRF905寄存器配置------------------------------------------------
uchar idata RFConf=
{
0x00,                           //配置命令//
0x4c,                           //CH_NO,配置频段在430MHZ
0x0c,                           //输出功率为10db,不重发,节电为正常模式
0x44,                           //地址宽度设置,为4字节
0x04,0x04,                        //接收发送有效数据长度为32字节
0xCC,0xCC,0xCC,0xCC,            //接收地址
0x58,                              //CRC充许,8位CRC校验,外部时钟信号不使能,16M晶振
};
//---配置口定义---//
sbit        TX_EN =P2^0;                                //TX_EN=1   TX模式   TX_EN=0   RX模式
sbit        TRX_CE=P2^1;                                //使能芯片发射或接收
sbit        PWR   =P2^2;                                //芯片上电
sbit        MISO=P2^3;                                //SPI输出
sbit        MOSI=P2^4;                                //SPI输入
sbit        SCK   =P2^5;                                //SPI时钟
sbit        CSN   =P2^6;                                //SPI使能
sbit        AM    =P2^7;                                //地址匹配
sbit        DR    =P0^6;                                //接收或发射数据完成
sbit        CD    =P0^7;                                //载波检测

sbit    LED   =P0^5;
sbit    key   =P3^0;

/***1602定义*****/
sbit rs=P0^4;      //1602的数据/命令
sbit rw=P0^3;           //1602的读/写
sbit en=P0^2;           //1602的使能端
//240c2        定义
sbit sda=P3^0;           //数据线
sbit scl=P3^1;           //时钟线
//发射

sbit key1=P3^3;           //存储开机
sbit key2=P3^4;           //存储关机
sbit key3=P3^5;           //红外码显示键
//sbit key4=P1^7;           //fa关机

//sbit p32=P3^2;

sbit LED_jie_kai=P0^0;   
sbit LED_jie_guan=P0^1;          
//sbit LED_fa_kai=P1^2;          
//sbit LED_fa_guan=P1^3;          

sbit ir=P3^6;          //发射管

bitflagfakai=0;
bitflagfaguan=0;
bitflagjiekai=0;
bitflagjieguan=0;
ucharflagfakaitimes=2;   //发射开机键码的次数
ucharflagfaguantimes=2;//发射关机键码的次数
ucharflagfaguantimes1=2;//发射关机键码的次数

uchar   flagir=0;          //红外码显示按键
/*******温度*****/
sbit DQ=P3^7;
uchar code table1[]="weclome! ir_rx   ir_tx   ";

uchar code temp[]="temp:";
uchar code table_1602[]="0123456789ABCDEF";
uchar data disp ;
uchar idata disply={0};
uchar irtime;                  //红外码高电平所占的时间
bit startflag;                  //红外解码开始标志位
bit irreceok=0;
bit irprcsok;
uchar   irdata;          //存红外各位高电平所占时间
ucharircode;               //红外码
uchar bitnum;                        //红外码位数
uchar *p;


void delay_ir1ms(uchar z)           //延时函数
{
   uchar x,y;            
   for(x=z;x>0;x--)
   for(y=125;y>0;y--);
      
}
void delay_8us()
{
       _nop_();_nop_();_nop_();_nop_();
       _nop_();_nop_();_nop_();_nop_();       
}
void delay50us(char us)
{
char x,y;
for(x=us;x>0;x--)
for(y=19;y>0;y--);
}
void delay_1ms(uint z)        
{
   uint x,y;            
   for(x=z;x>0;x--)
   for(y=123;y>0;y--);
      
}
void delay(uint t)                   //5.3us
{
        while(t--);       
}
void NRF905_delay(uchar n)
{
        uchar i;
        while(n--)
        for(i=0;i<80;i++);
}
//写命令函数,对1602写入命令
void write_com(uchar com)                          //写指令
{
    rs = 0;                                                   //选择写指令
    rw = 0;
    P1 = com;
        en = 1;                                            //en先1后0为高脉冲
        delay50us(5);
    en = 0;
}
//写数据函数,使1602显示数据
void write_dat(uchar dat)                   //写数据
{
        rs = 1;                                                  //选择写数据
        rw = 0;
        P1 = dat;
        en = 1;                                                  //en先1后0为高脉冲
        delay50us(5);                                       
        en = 0;
}
//1602初始化
void init1602()
{
    rw =0;                                                          //读/写 置低 ,选择写
        write_com(0x38);                      //设置16x2显示,5x7点阵,8位数据口
        write_com(0x06);                      //读写数据,光标及数据指针加一
        write_com(0x0C);                  //开显示,光标不显示
        write_com(0x01);                      //显示清屏,数据指针以及所有显示清零
}

void display_temp(uchar add_temp,uchar a)       //显示
{       
   uchar i;                                                                  
   write_com(0x80);
   for(i=0;i<5;i++)
   {
           write_dat(temp);
           delay_1ms(20);
   }
           write_com(0x80+0x40+add_temp);
        for(i=0;i<2;i++)
        write_dat(table_1602]);

}
/***********************温度部分*********************/
void init_ds18b20(void)
{
        uchar n;
        DQ=1;
        delay(8);
        DQ=0;
        delay(95);
        DQ=1;
        delay(8);
        n=DQ;
        delay(15);

}

void write_byte(uchar dat)
{
        uchar i;
        for(i=0;i<8;i++)
        {
                DQ=0;
                DQ=dat&0x01;
                delay(4);
                DQ=1;
                dat>>=1;
        }
        delay(4);
}

uchar read_byte(void)
{
        uchar i,value;
        for(i=0;i<8;i++)
        {
                DQ=0;
                value>>=1;
                DQ=1;
                if(DQ)
                value|=0x80;
                delay(4);

        }
        return value;
}

uchar readtemperature(void)
{
        uchar a,b;
        init_ds18b20();
        write_byte(0xcc);        //跳过ROM
        write_byte(0x44);        //启动温度测量
        delay(300);

        init_ds18b20();
        write_byte(0xcc);
        write_byte(0xbe);
        a=read_byte();
        b=read_byte();
        b<<=4;
        b+=(a&0xf0)>>4;
        return b;

}
//-----------------无线NRF905-------------------
//---------------------------------------SPI读函数-----------------------------------------------------
uchar SpiRead(void)
{
        uchar i;
        for (i=0;i<8;i++)
        {
      DATA_BUF=DATA_BUF<<1;                //用DATA_BUF来存接收到的数据
                SCK=1;
                if (MISO)        //读取最高位,保存至最末尾,通过左移位完成整个字节
                {
                        flag1=1;                               //flag1=DATA_BUF^0
                }
                else
                {
                        flag1=0;
                }
                SCK=0;
       }
       return DATA_BUF;                          //DATA_BUF为接收到的完整的数据
}
//--------------------------------------SPI写函数----------------------------------------------------------
void SpiWrite(uchar send)
{
        uchar i;
        DATA_BUF=send;                               //将需要发送的数据写入缓存
        for (i=0;i<8;i++)                        //循环8次发送一个字节
        {
                if (flag)                 //总是发送最高位,//flag=DATA_BUF^7
                {
                        MOSI=1;
                }
                else
                {
                        MOSI=0;
                }
                SCK=1;
                DATA_BUF=DATA_BUF<<1;                //左移一位,为下一位的发送做准备
                SCK=0;
        }
}
//--------------------------------------初始化nRF905---------------------------------------------
void nRF905Init(void)
{
    CSN=1;                                                // Spi使能
        SCK=0;                                                // Spi clock line init low
        DR=0;                                                // Init DR for input
        AM=0;                                                // Init AM for input
        CD=0;                                                // Init CD for input
        PWR=1;                                        // nRF905上电
        TRX_CE=0;                                        // 设置nRF905处于待机模式
        TX_EN=0;                                        // 设置nRF905处于接收模式
}

//----------------------主机通过SPI接口向905配置寄存器写入信息,初始化寄存器-----------------------------------------------
void Config905(void)
{
        uchar i;
        CSN=0;                                                // 全能SPI,低电平有效
        for (i=0;i<11;i++)                // 写放配置字
        {
           SpiWrite(RFConf);
        }
        CSN=1;                                           //停用SPI
}
//-------------------------使用NRF905发送数据----------------------------------------------
void TxPacket(uchar *TxBuf)
{
        uchar i;
        CSN=0;                     //使能SPI
        SpiWrite(WTP);               //写向TX_PAYLOAD寄存器写入发送有效数据命令
        for(i=0;i<4;i++)
        {
                SpiWrite(TxBuf);                        //写入4个字节的数据
        }
        CSN=1;                                                       //关闭SPI
        NRF905_delay(1);
        CSN=0;
        SpiWrite(WTA);
        for(i=0;i<4;i++)                       //要发送目标的地址
        {
          SpiWrite(TxAddress);
        }
        CSN=1;                                                //关闭SPI
        TRX_CE=1;                   //进入发送模式,启动射频发射
        NRF905_delay(1);                                  // while (DR!=1),等待发送完成
        TRX_CE=0;                                        // 返回待机模式
        LED_jie_kai=1;
        delay_1ms(200);
        LED_jie_kai=0;
        delay_1ms(200);
}


//-----------------------读NRF905接收数据----------
void RxPacket(void)
{
        uchar i;
        TRX_CE=0 ;      //设置NRF905为待机状态
        CSN=0;            //全能SPI
        NRF905_delay(1);
        SpiWrite(RRP);    // 准备读取接收到的数据
        for(i=0;i<4;i++)
        {
                RxBuf=SpiRead();
                NRF905_delay(1);                   //读取4个字节的数据
        }
        CSN=1;      //停用SPI
        while(DR||AM);                  //AM接收到有效地址置高,DR接收到了数据包并解码后置高,
        NRF905_delay(1);                                          //当所有的数据都读取完后,NRF905会置低AM,DR
        TRX_CE=1;
}
//--------------------------------------设置发送模式---------------------------------------------
void SetTxMode(void)
{
        TRX_CE=0;
        TX_EN=1;
        NRF905_delay(1);                                         // delay for mode change(>=650us)
}
//----------------------------------------设置接收模式---------------------------------------------------
void SetRxMode(void)
{
        TX_EN=0;
        TRX_CE=1;
        NRF905_delay(1);                                         // delay for mode change(>=650us)
}
//-------------------------------------判断数据接收状态-----------------------------------------------------
uchar CheckDR(void)                //检查是否有新数据传入 Data Ready
{
        if (DR=1 && TRX_CE==1 && TX_EN==0)
        {
       // NRF905_delay(50);
                return 1;
        }
        else
        {
                return 0;
        }
}
//--------------------------------数据接收------------------------------------------------
voidRX(void)
{
        SetRxMode();                           // 设置NRF905在接收模式
        //while (CheckDR()==0);           //有新数据传入时继续
        if(CheckDR())
        {
                NRF905_delay(10);
                RxPacket();
                /*if(RxBuf)           //判断接收到的数据是否为发送过来的数据
                {
                        LED=0;                   //是的话灯闪
                        delay_1ms(500);
                        LED=1;
                        delay_1ms(500);                              
                }       */
        }
}
/***********20c02部分**********/

void start()
{
        sda=1;
        delay_8us();
        scl=1;
        delay_8us();
        sda=0;
        delay_8us();
}
void stop()
{
        sda=0;
        delay_8us();
        scl=1;
        delay_8us();
        sda=1;
        delay_8us();
}
void ack()                                //应答程序
{
        uchar i;
        scl=1;
        delay_8us();
        while((sda==1)&&(i<200))
        i++;
        scl=0;
        delay_8us();
}
void noack()                           //非应答
{
        sda=1;
        delay_8us();
        scl=1;
        delay_8us();
        scl=0;
        delay_8us();
}
void init_2402()
{
        scl=1;
        sda=1;
}
void iicwr_byte(uchar dat)
{
        uchar i;
        scl=0;
        for(i=0;i<8;i++)
        {
                if(dat&0x80)
                {
                  sda=1        ;
                }
                else
                {
                sda=0;
                }
                dat=dat<<1;
                delay_8us();
                scl=1;
                delay_8us();
                scl=0;
                delay_8us();
        }
        scl=1;
        delay_8us();
}
uchar iicre_byte()
{
        char i;
        uchar dat;
        scl=0;
        delay_8us();
        sda=1;
        delay_8us();
    for(i=0;i<8;i++)
    {
          scl=1;
          delay_8us();
          dat=dat<<1;
                if(sda)
                {
                  dat++;
                  
                }
                  scl=0;
                  delay_8us();

    }
        return dat;
}
void write_byte_2402(uchar add,uchar dat)
{
        init_2402();
        start();
        iicwr_byte(0xa0);
        ack();
       
        iicwr_byte(add);
        ack();
       
        iicwr_byte(dat);
        ack();
        stop();

}
uchar read_byte_2402(uchar add)
{
        uchar record        ;
        init_2402();
        start();
        iicwr_byte(0xa0);
        ack();
       
        iicwr_byte(add);
        ack();
        start();
        iicwr_byte(0xa1);
        ack();
        record=iicre_byte();
        noack();
        stop();   
        return record;

}
/***********红外解码部分*******/

void int0init ()   //外部中断0的初始化
{
        IT0=1;                   //INT0为负边沿触发 (1:负边沿触发,0:低电平触发)
        EX0=0;                  //外部中断INT0开,
        EA=1;                       //开所有中断
}
void timer0init()//定时器0的初始化
{
        TMOD=0X02;
        TH0=0X00;                   //经256us后进入定时器0中断
        TL0=0X00;
        ET0=1;                           //T0中断允许
        EA=0;                           //关总中断
        TR0=1;                           //开定时器0
}
/*********红外码0、1的判断并 ************/
void irprcs()                          
{
        char k=1,i,j;
        uchar value;
        for(j=0;j<8;j++)
          {       
                for(i=0;i<8;i++)
                {
                        value=value>>1;
                        if(irdata>7)
                        {
                          value=value|0x80;               //irtime>7,
                        }                                               
                        k++;
                }
                ircode=value;
          }       
       
          irprcsok=1;
}
/*****************红外码处理成16进制 **********************/
void irwork()                               
{
        disply=ircode/16;
        disply=ircode%16;
        disply=ircode/16;
        disply=ircode%16;
        disply=ircode/16;
        disply=ircode%16;
        disply=ircode/16;
        disply=ircode%16;
       
        disply=ircode/16;
        disply=ircode%16;
        disply=ircode/16;
        disply=ircode%16;
        disply=ircode/16;
        disply=ircode%16;
        disply=ircode/16;
        disply=ircode%16;
}
void display(char x,char y)       //显示红外码
{       
        char i;                                                                  
        write_com(0x80);
        for(i=x;i<x+y;i++)
        {
                write_dat(table1);
                delay_1ms(20);
        }
        write_com(0x80+0x40);
        for(i=0;i<16;i++)
        write_dat(table_1602]);
}

void irmain()
{
        if(irreceok)
        {
                irprcs();
                irreceok=0;
        }
        if(irprcsok)
        {
                irwork();
                irprcsok=0;
        }
}
/***********发射部分**********/
void khz(int aa)   //发射38KHZ
{
        int a,i;
        for(a=aa;a>0;a--)   //这个for语句可以得到准确的26.3波特率
                {
                        ir=0;
                        i=7;                //低17us
                        while(i>0)i--;                //   38kHZ
                        ir=1;                        //高了9us      17+9=26us   比26.3快一点点
                }

}
void fashe()
{
        char num1,num2;
    uchar aa;
        khz(125);         //发射9ms 38khz        1--0.072112        ms
        delay_ir1ms(17);        //4.5ms                       1--0.25966667
        for(num2=0;num2<4;num2++)
        {
               aa=ircode;
                for(num1=0;num1<8;num1++) //原来用的是a后来出错,肯定在这里!
                {
                        khz(8);                //0.56ms0.56896
                        if(aa&0x01)
                                delay_ir1ms(6);//delay 1.685ms   1.5580002
                        else
                                delay_ir1ms(2);//delay 0.56ms           0.519334
                   aa>>=1;
               
                }
       
       }

        khz(8);          //0
        delay_ir1ms(2);
        khz(8);       //1
        delay_ir1ms(6);
        khz(8);       //0
        delay_ir1ms(2);
        khz(8);           //21ms
        delay_ir1ms(81);
        for(num2=0;num2<4;num2++)
        {
               aa=ircode;
                for(num1=0;num1<8;num1++)
                {
                        khz(8);                //0.56ms0.56896
                        if(aa&0x01)
                                delay_ir1ms(6);//delay 1.685ms   1.5580002
                        else
                                delay_ir1ms(2);//delay 0.56ms           0.519334
                   aa>>=1;
               
                }
       
       }
        khz(8);       //1
        delay_ir1ms(20);
}

void keyscan()//按键扫描
{
        if(key1==0)           //存储开机
        {
                delay_1ms(5);
                if(key1==0)
                {
                        while(!key1);
                        flagjiekai=1;                  
                }
        }
        if(key2==0)
        {
                delay_1ms(5);
                if(key2==0)
                {
                        while(!key2);
                        flagjieguan=1;
               
                }
        }
        if(key3==0)
        {
                delay_1ms(5);
                if(key3==0)
                {
                        while(!key3);
                        flagir++;
                        LED_jie_kai=1;
                        delay_1ms(200);
                        LED_jie_kai=0;
                        delay_1ms(200);

                }
        }


}
void ir_cun(uintadd)
{
        uint i ;
        for(i=0;i<8;i++)
        {
                write_byte_2402(add+i,ircode);
                delay_ir1ms(10);               //给足够的时间给2402存储
        }
}
void ir_qu(uint add)
{
        uinti ;
        for(i=0;i<8;i++)
        {
                ircode=read_byte_2402(add+i);                                                                               
                delay_ir1ms(10);
        }
}
void ircl()
{
        char i;
        p=irdata;
        for(i=0;i<33;i++)
        {
                irdata=*(p+i+37);
        }
}
void main()
{
        uchar temp;
       
        init1602();                          //初始化1602
        int0init ();                  //中断初始化
        timer0init();
        init_ds18b20();                  //18b20初始化
    nRF905Init();
        Config905();                  //初始化寄存器
        LED=1;
        LED_jie_kai=0;
    LED_jie_guan=0;
        while(1)
        {                       
                keyscan();                             
                temp=readtemperature();
                disp=temp/10;
                disp=temp%10;
                display_temp(0,0);       
                RX();
                disp=RxBuf/10;
                disp=RxBuf%10;
                display_temp(6,2);
                disp=RxBuf/10;
                disp=RxBuf%10;
                display_temp(10,4);       
                while(flagir)
                {
                        keyscan();                             
                        if(flagjiekai==1)
                        {
                                  EX0=1;EA=1;
                                LED_jie_kai=1;
                                if(irreceok)
                                { LED_jie_kai=0;
                                  irmain();
                                  EX0=0;EA=0;
                                  display(9,8);
                                  delay_1ms(60);
                                  ir_cun(1);
                                  delay_1ms(10);       
                                  flagjiekai=0;       
                                  flagfakai=1;                                  
                                  irreceok=0;                       
                                }
                        }
                        if(flagjieguan==1)
                        {
                                  EX0=1;EA=1;
                                LED_jie_guan=1;
                                if(irreceok)
                                { LED_jie_guan=0;
                                  irmain();
                                  EX0=0;EA=0;
                                  display(9,8);
                                  delay_1ms(60);
                                  ir_cun(13);
                                  delay_1ms(10);       
                                  flagjieguan=0;
                                  flagfaguan=0;
                                  
                                  irreceok=0;                               
                                }                
                        }
                        if(flagir==2)
                        {
                                flagir=0;
                                init1602();                       
                        }
                }

                if(RxBuf<RxBuf)          //实际温度与标准温度比                     
                {                       
                        flagfaguan=1;
                        TxBuf=0x20;          //开鼓风机
                SetTxMode();                  //设置成发送模式
                  TxPacket(TxBuf);           // 发送命令数据
                        delay_1ms(50);

                        if(flagfaguan)
                        {
                                ir_qu(13);
                                delay_1ms(50);
                                fashe();

                //        irwork();
                        //        display(17,8);
                                delay_1ms(10);
                                flagfaguan=0;
                        }                                                                                      
                }
                if(RxBuf>=34)                     
                {
                        flagfaguan=0;
                        flagfakai=1;
                        TxBuf=0x50;          //关鼓风机
                SetTxMode();
                  TxPacket(TxBuf);           // 发送命令数据
                        //LED=0;                                   //是的话灯闪
                        delay_1ms(50);
                        //LED=1;
                        //delay_1ms(500);
                        if(flagfakai)
                        {
                                ir_qu(1);
                                delay_1ms(10);
                                fashe();
                        //LED_jie_kai=1;
                        //        delay_1ms(200);
                        //        LED_jie_kai=0;
                        //        delay_1ms(200);
                        //        irwork();
                        //        display(17,8);
                                delay_1ms(10);                       
                                flagfakai=0;
                        }                                                                                                                                                                      
                }

        }

}

void timer0() interrupt 1                //定时器0中断
{
        irtime++;                                       //红外0、1高电平持续的时间
}
void int0()interrupt 0                   //外部中断
{
       if(startflag)
       {
               if(irtime>49&&irtime<57)       //引导码        13.5ms的引导码
               {
                       bitnum=0;                               //开始计红外码的位数
               }
               irdata=irtime;               //把红外0、1码高电平持续的时间存入数组中
               irtime=0;
               bitnum++;
               if(bitnum==70)
               {
               bitnum=0;                                   //红外码计到70位时清0
               ircl();                               
               irreceok=1;                               //红外处理标志位置1
               }
       }
       else
       {
             startflag=1;
               irtime=0;
       }
}

qq511153186 发表于 2013-6-26 11:19:05

没人看吗?程序调了很久,哪位帮忙看下,

沐风野草 发表于 2013-8-5 01:08:35

我来看了,可惜我也是菜鸟,是过来学习的
页: [1]
查看完整版本: 关于NRF905的收发问题