基于凌阳单片机的无线采集系统(发射模块为NFR905)

2019-03-26 13:36发布

//这是发射主程序,请大神帮忙检查下,我们接收不到数据
#include <SPCE061A.h>
#include "weicaozuo.h"
//----------------------------------------------------------------------------------------------------------------
#define uint  unsigned int
#define uchar  unsigned char
//----------------------------------------------------------------------------------------------------------------
#define BYTE_BIT0        0x01
#define BYTE_BIT7        0x80
//----------------------------------------------------------------------------------------------------------------
unsigned  char DATA_BUF;   //16位
#define DATA7        ((DATA_BUF&BYTE_BIT7) != 0)
#define DATA0   ((DATA_BUF&BYTE_BIT0) != 0)
//---------------------------------------------------发送数据缓冲区-------------------------------------------------
#define TxRxBuf_Len 2
unsigned char TxRxBuf[TxRxBuf_Len];
/***********************************************端口定义************************************************************************
//----------------------------------------NRF905 数据交换端口---------------------------------------------------
bit        CSN=PB_0;
bit        MOSI=PB_1;
bit        MISO=PB_2;
bit        SCK=PB_3;

//----------------------------------------NRF905工作模式控制端口------------------------------------------------------
bit        PWR=PB_4;
bit        TRX_CE=PB_5;
bit        TXEN=PB_6;

//----------------------------------------nrf905状态端口---------------------------------------------------------
bit        AM=PB_7;
bit        DR=PB_8;
bit        CD=PB_9;

********************************************************************************************************************/

//----------------------------------------nrf905控制指令-------------------------------------------
#define WC                0x00        // 写配置寄存器(RF-Configuration Register)
#define RC                0x10        // 读配置寄存器(RF-Configuration Register)
#define WTP                0x20        // 向TX-Payload寄存器写入发送有效数据
#define RTP                0x21                // 从TX-Payload寄存器读取发送有效数据
#define WTA                0x22                // 向TX-Address寄存器写入发送地址               
#define RTA                0x23                // 从TX-Address寄存器读取发送地址
#define RRP                0x24                // 从RX-Payload寄存器读取接收到的有效数据


//------------------------------------------------NRF905寄存器配置------------------------------------------------
typedef struct RFConf
{
        uchar n;
        uchar buf[10];
}RFConf;
RFConf RxTxConf=
{
          10,                           
          0x4c,0x0c,0x44,0x02,0x02,0xCC,0xCC,0xCC,0xCC,0x58                           
};  
//配置命令
//CH_NO,配置频段在430MHZ
//输出功率为10db,不重发,节电为正常模式
//地址宽度设置,为4字节
//接收发送有效数据长度为2字节
//接收地址
//CRC充许,8位CRC校验,外部时钟信号不使能,16M晶振
//================================================延时===========================================================
void Delay(unsigned int n)
{
        uint i;
        for(i=0;i<n;i++)
        {
                *P_Watchdog_Clear=0x0001; //清狗   
        }
}
//=================================================SPI读函数=======================================================
uchar SpiRead(void)
{
        uchar j;
        for (j=0;j<8;j++) //循环8次发送一个字节的数据
        {
        DATA_BUF=DATA_BUF<<1;  //左移一位,准备下一位数据
                SCK=1;
                if (MISO)        //读取最高位,保存至最末尾,通过左移位完成整个字节
                {
                        DATA_BUF|=BYTE_BIT0;  //最低位写1
                }
                else
                {
                        DATA_BUF&=~BYTE_BIT0;  //最低位写0
                }
                SCK=0;
         }
         return DATA_BUF;
}
//===========================================SPI写函数===============================================================
void SpiWrite(unsigned char send)
{
        unsigned char i;
        DATA_BUF=send;  //将需要发送的数据写入缓存
        for (i=0;i<8;i++) //循环8次发送一个字节的数据
        {
                if (DATA7)        //总是发送最高位
                {
                        MOSI=1;
                }
                else
                {
                        MOSI=0;
                }
        SCK=1;
                DATA_BUF=DATA_BUF<<1; //左移一位,准备下一位数据
                SCK=0;
        }
}

//------------------------------------------------------初始化nRF905---------------------------------------------
void nRF905Init(void)
{
        *P_IOB_Dir = 0x007B;
        *P_IOB_Attrib = 0x03ff;
        *P_IOB_Data=0xffff;
        CSN=1;                                                // Spi         disable
        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 power on
            TRX_CE=0;                                        // Set nRF905 in standby mode
             TXEN=0;                                        // set radio in Rx mode

}

//-------------------------------------主机通过SPI接口向905配置寄存器写入信息-------------------------------------------------
void Config905(void)
{
        uchar i;
        CSN=0;                                                // SPI使能输入
        SpiWrite(WC);                                // 写配置字命令
        for (i=0;i<RxTxConf.n;i++)        //  循环写配置字
        {
           SpiWrite(RxTxConf.buf[i]);  //RxTxConf保存预先设置好的配置信息
        }
        CSN=1;                                        // 结束SPI数据输入
}
//-----------------------------------------------------发送数据打包---------------------------------------------------
void TxPacket(uchar *TxRxBuf)
{
        uchar i;
        CSN=0;                                                //SPI使能,准备写入数据信息
        SpiWrite(WTP);                                // Write payload command
        for (i=0;i<2;i++)
        {
                SpiWrite(TxRxBuf[i]);        // 写入2字节发送数据
        }
        CSN=1;                                                //关闭SPI,保存写入的数据
        Delay(10);                                       
        CSN=0;                                                // SPI使能,准备写入地址信息
        SpiWrite(WTA);                                // Write address command
        for (i=0;i<4;i++)                        // 写入与对方地址一样的地址
        {
                SpiWrite(RxTxConf.buf[i+5]);
        }
        CSN=1;                                                // 关闭SPI
        TRX_CE=1;                                        // 进入发送模式,启动射频发送
        Delay(10);                                        // 进入ShockBurst发送模式后,芯片保证数据发送完成后返回STANDBY模式z
        TRX_CE=0;                                        // 关闭发送开关
}
//----------------------------------------------设置发送状态---------------------------------------------
void SetTxMode(void)
{
        TRX_CE=0;
        TXEN=1;
        Delay(6000);                                         // nrf905_Delay for mode change(>=650us)
}

extern void F_AD_Initial(void);
extern unsigned int F_ReadAD(unsigned int);
unsigned int uiCircleChannelNumber=1;
int main()
{
        nRF905Init();
        Config905();
        F_AD_Initial();
        uiCircleChannelNumber=1;
       
        while(1)
        {
                   for(uiCircleChannelNumber=1;uiCircleChannelNumber<4;uiCircleChannelNumber++)
                {
                                    TxRxBuf[0]=(F_ReadAD(uiCircleChannelNumber)&0x00ff);//采集通道数据
                                TxRxBuf[1]=((F_ReadAD(uiCircleChannelNumber)&0xff00)>>8);
                                 TxPacket(TxRxBuf);    //发送数据打包
                                 SetTxMode();           //设置发送初始状态

                    }
                        if(uiCircleChannelNumber==4)
                        {
                                uiCircleChannelNumber=1;
                        }

                 
                       
          }
         
}

//这是AD转换子程序
//*************************************************************                                                                       

// 时钟源为Fosc/8,采样率为8KHz
.include SPCE061A.inc
.CODE
.public _F_AD_Initial;
_F_AD_Initial:  .PROC
                PUSH r1,r1 TO [sp];
                R1 = 0x0001                    //允许A/D
                [P_ADC_Ctrl] = R1                  
            
            r1=0x0000;                        //通过读P_ADC触发ADC自动转换       
            [P_DAC_Ctrl] = r1;
               
                r1 = 0x0001            //LINE1输入                       
                [P_ADC_MUX_Ctrl] = r1;
               
                POP r1,r1 FROM [sp];
                RETF
                .ENDP
       
       
//************** A/D 转换程序 **********************//       
.public _F_ReadAD
_F_ReadAD: .PROC
                   PUSH r2,r5 TO [sp];
                   BP=SP+1;
                   r1 = [BP+6];                          
                   [P_ADC_MUX_Ctrl] = r1;//设置通道号
                   r1=0x0001;
                   [P_Watchdog_Clear]=r1;
                   r2=16      //进行4次转换
                   r3=0
L_SampleLoop:          
                   r1=[P_ADC_MUX_Data]      //读[P_ADC_MUX_Data],启动一次AD转换
           r1=0x8000
L_VoltageConverLoop:   
          TEST r1,[P_ADC_MUX_Ctrl]
          JZ L_VoltageConverLoop;
          r1=[P_ADC_MUX_Data]      //AD转换值
          r1=r1 LSR 4           //将AD值移到低10位
          r1=r1 LSR 2
          r3+=r1             //四次A/D值累加
          r2-=1
          jnz  L_SampleLoop
          r3=r3 LSR 4     //结果除以4,求4次的平均值
          r1=r3           //返回结果
         
          POP r2,r5 FROM [sp];
          RETF
          .ENDP
                  
   

//接收端程序
#include <SPCE061A.h>
#include "weicaozuo.h"
//----------------------------------------------------------------------------------------------------------------
#define uint unsigned int
#define uchar unsigned char
//----------------------------------------------------------------------------------------------------------------
#define BYTE_BIT0        0x01
#define BYTE_BIT7        0x80
//----------------------------------------------------------------------------------------------------------------
unsigned  char DATA_BUF;
#define DATA7        ((DATA_BUF&BYTE_BIT7) != 0)
#define DATA0   ((DATA_BUF&BYTE_BIT0) != 0)
//---------------------------------------------------接收数据缓冲区-------------------------------------------------
#define TxRxBuf_Len 2
unsigned char TxRxBuf[TxRxBuf_Len]={0x00,0x00};
/***********************************************端口定义************************************************************************
//----------------------------------------NRF905 数据交换端口---------------------------------------------------
bit        CSN=PA_0;
bit        MOSI=PA_1;
bit        MISO=PA_2;
bit        SCK=PA_3;

//----------------------------------------NRF905工作模式控制端口------------------------------------------------------
bit        PWR=PA_4;
bit        TRX_CE=PA_5;
bit        TXEN=PA_6;

//----------------------------------------nrf905状态端口---------------------------------------------------------
bit        AM=PA_7;
bit        DR=PA_8;
bit        CD=PA_9;

********************************************************************************************************************/
//----------------------------------------nrf905控制指令-------------------------------------------
#define WC                0x00
#define RC                0x10
#define WTP                0x20
#define RTP                0x21
#define WTA                0x22
#define RTA                0x23
#define RRP                0x24
//------------------------------------------------NRF905寄存器配置------------------------------------------------
typedef struct RFConf
{
        uchar n;
        uchar buf[10];
}RFConf;
RFConf RxTxConf=
{
          10,                             //配置命令//
        0x4c,                             //CH_NO,配置频段在430MHZ
          0x0c,                             //输出功率为10db,不重发,节电为正常模式
          0x44,                             //地址宽度设置,为4字节
          0x02,0x02,                        //接收发送有效数据长度为2字节
          0xCC,0xCC,0xCC,0xCC,              //接收地址
          0x58                         //CRC充许,8位CRC校验,外部时钟信号不使能,16M晶振
};
//================================================延时===========================================================
void Delay(unsigned int n)
{
        uint i;
        for(i=0;i<n;i++)
        {
                *P_Watchdog_Clear=0x0001; //清狗   
        }
}
//=================================================SPI读函数=======================================================
uchar SpiRead(void)
{
        uchar j;
        for (j=0;j<8;j++) //循环8次发送一个字节的数据
        {
        DATA_BUF=DATA_BUF<<1;  //左移一位,准备下一位数据
                SCK=1;
                if (MISO)        //读取最高位,保存至最末尾,通过左移位完成整个字节
                {
                        DATA_BUF|=BYTE_BIT0;  //最低位写1
                }
                else
                {
                        DATA_BUF&=~BYTE_BIT0;  //最低位写0
                }
                SCK=0;
         }
         return DATA_BUF;
}
//===========================================SPI写函数===============================================================
void SpiWrite(unsigned char send)
{
        unsigned char i;
        DATA_BUF=send;  //将需要发送的数据写入缓存
        for (i=0;i<8;i++) //循环8次发送一个字节的数据
        {
                if (DATA7)        //总是发送最高位
                {
                        MOSI=1;
                }
                else
                {
                        MOSI=0;
                }
        SCK=1;
                DATA_BUF=DATA_BUF<<1; //左移一位,准备下一位数据
                SCK=0;
        }
}
//------------------------------------------------------初始化nRF905---------------------------------------------
void nRF905Init(void)
{
        *P_IOA_Dir = 0x007B;
    *P_IOA_Attrib = 0x03ff;
    CSN=1;                                                // Spi         disable
        SCK=0;                                                // Spi clock line init low
        DR=1;                                                // Init DR for input
        AM=0;                                                // Init AM for input
        CD=0;                                                // Init CD for input
        PWR=1;                                        // nRF905 power on
        TRX_CE=0;                                        // Set nRF905 in standby mode
        TXEN=0;                                        // set radio in Rx mode
}
//--------------------------------------------------主机通过SPI接口向905配置寄存器写入信息-----------------------------------------------
void Config905(void)
{
        uchar i;
        CSN=0;                                                // SPI使能输入
        SpiWrite(WC);                                // 写配置字命令
        for (i=0;i<RxTxConf.n;i++)        //  循环写配置字
        {
           SpiWrite(RxTxConf.buf[i]);  //RxTxConf保存预先设置好的配置信息
        }
        CSN=1;                                        // 结束SPI数据输入
}
//-----------------------------------------------设置接收初始化---------------------------------------------------
void SetRxMode(void)
{
        TXEN=0;
        TRX_CE=1;
        Delay(6000);                                         // nrf905_Delay for mode change(>=650us)
}

//----------------------------------------------------读NRF905接收数据------------------------------------------------------------
void RxPacket(void)                                               
{
        uchar i;                                       
    TRX_CE=0;                  // 设置 nRF905 进入待机模式
        CSN=0;                                                // 使能SPI
        SpiWrite(RRP);
        for (i = 0 ;i < 2 ;i++)
        {
                TxRxBuf[i]=SpiRead();                // 通过SPI接口从905芯片读取数据保存到Buf中      
        }
        CSN=1;
    Delay(10);
    while(DR||AM);
        TRX_CE=1;
                                                               
}

extern void F_UART_Initial(void);
extern void F_UART_WriteByteData(unsigned int uiVoltageValue);
//-----------------------------------------------------------------------------------------------------------------
void main(void)
{

        F_UART_Initial();
        nRF905Init();
             Config905();
     //        SetRxMode();
     //        RxPacket();
             while(1)
             {      

                                  SetRxMode();
                                  RxPacket();                 
                          //分两次发送一个通道的电压值。
                                        F_UART_WriteByteData(TxRxBuf[0]);//发送低8bit
                                    Delay(1000);
                                        F_UART_WriteByteData(TxRxBuf[1]);//发送高2bit
             }
            
               
}

//串口通信程序
//========================================================================================================//
.include SPCE061A.inc
.CODE

//========================================================================================================
//函数: F_UART_Initial
//语法:void F_UART_Initial()
//描述:初始化UART
//参数:无
//返回:无
//========================================================================================================

.PUBLIC _F_UART_Initial;
_F_UART_Initial:               
        INT OFF;
        r1 = 0x0000;                        //未使能任何中断
        [P_INT_Ctrl] = r1;
        r1 = 0x0480;                //设置IOB7为输入IOB10为输出
        [P_IOB_Attrib] = r1;
        R1 = 0x0400;
        [P_IOB_Dir] = R1;
        R1 = 0x0000;       
        [P_IOB_Data] = R1;

           R1 = 0x0000;                     //设置波特率为9600bps
    [P_UART_BaudScalarLow] = R1;
        R1 = 0x0005;
    [P_UART_BaudScalarHigh] = R1;
       
       
        R1 = 0x0080;
        [P_UART_Command1] = R1;
        R4 = 0x00C0;                    //使能输入和输出
        [P_UART_Command2] = R4;
        IRQ ON       
        RETF
       
//========================================================================================================
//函数: F_UART_Write
//语法:void F_UART_Write(unsigned int)
//描述:写UART
//参数:为要写入串口的值,其低8bit为有效值。
//返回:无
//========================================================================================================
.PUBLIC _F_UART_WriteByteData
_F_UART_WriteByteData:
        PUSH r1,r5 TO [sp]
        bp=sp+1;
        r1=[bp+7];//command value
        r4=0xFFFF;
L_Check_TxRDY:
        r3=0x0001;
        [P_Watchdog_Clear]=r3;
        r4-=1;
        JZ L_UART_Write_Timeout;
        r2 = [P_UART_Command2];
        r2 &= 0x0040;                        //检测输出是否READY
        JZ L_Check_TxRDY;
        [P_UART_Data] = r1;//send data
L_UART_Write_Timeout:       
        POP r1,r5 FROM [SP]
        RETF;




谢谢大神,请多指教!!!!

此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。