找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2103|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

求幫助 用51單片機(jī)做船模 但是一直調(diào)不通 用的nrf24l01 ps2搖桿 l298n 直流電機(jī)

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:489438 發(fā)表于 2019-3-27 23:49 | 只看該作者 回帖獎勵 |倒序?yàn)g覽 |閱讀模式
發(fā)送的代碼:
#include "stc12c5a.h"
#include "intrins.h"
//#include "stc12_adc.h"


//這個(gè)是寄存器基地址
#define READ_REG        0x00          //讀配置寄存器,低5位為寄存器地址
#define WRITE_REG       0x20          //寫配置寄存器,低5位為寄存器地址
#define RD_RX_PLOAD     0x61          //讀RX有效數(shù)據(jù),1~32字節(jié)
#define WR_TX_PLOAD     0xA0          //寫TX有效數(shù)據(jù),1~32字節(jié)
#define FLUSH_TX        0xE1          //清除TX FIFO寄存器.發(fā)射模式下用
#define FLUSH_RX        0xE2          //清除RX FIFO寄存器.接收模式下用
#define REUSE_TX_PL     0xE3          //重新使用上一包數(shù)據(jù),P_24L01_CE為高,數(shù)據(jù)包被不斷發(fā)送.
#define NOP             0xFF          //空操作,可以用來讀狀態(tài)寄存器         


// SPI(nRF24L01) registers(addresses) 這個(gè)是寄存器偏移地址
#define CONFIG          0x00          //配置寄存器地址                             
#define EN_AA           0x01          //使能自動應(yīng)答功能
#define EN_RXADDR       0x02          //接收地址允許
#define SETUP_AW        0x03          //設(shè)置地址寬度(所有數(shù)據(jù)通道)
#define SETUP_RETR      0x04          //建立自動重發(fā)
#define RF_CH           0x05          //RF通道
#define RF_SETUP        0x06          //RF寄存器
#define STATUS          0x07          //狀態(tài)寄存器
#define OBSERVE_TX      0x08          // 發(fā)送檢測寄存器
#define CD              0x09          // 載波檢測寄存器
#define RX_ADDR_P0      0x0A          // 數(shù)據(jù)通道0接收地址
#define RX_ADDR_P1      0x0B          // 數(shù)據(jù)通道1接收地址
#define RX_ADDR_P2      0x0C          // 數(shù)據(jù)通道2接收地址
#define RX_ADDR_P3      0x0D          // 數(shù)據(jù)通道3接收地址
#define RX_ADDR_P4      0x0E          // 數(shù)據(jù)通道4接收地址
#define RX_ADDR_P5      0x0F          // 數(shù)據(jù)通道5接收地址
#define TX_ADDR         0x10          // 發(fā)送地址寄存器
#define RX_PW_P0        0x11          // 接收數(shù)據(jù)通道0有效數(shù)據(jù)寬度(1~32字節(jié))
#define RX_PW_P1        0x12          // 接收數(shù)據(jù)通道1有效數(shù)據(jù)寬度(1~32字節(jié))
#define RX_PW_P2        0x13          // 接收數(shù)據(jù)通道2有效數(shù)據(jù)寬度(1~32字節(jié))
#define RX_PW_P3        0x14          // 接收數(shù)據(jù)通道3有效數(shù)據(jù)寬度(1~32字節(jié))
#define RX_PW_P4        0x15          // 接收數(shù)據(jù)通道4有效數(shù)據(jù)寬度(1~32字節(jié))
#define RX_PW_P5        0x16          // 接收數(shù)據(jù)通道5有效數(shù)據(jù)寬度(1~32字節(jié))
#define FIFO_STATUS     0x17          // FIFO狀態(tài)寄存器
#define STA_MARK_RX     0X40
#define STA_MARK_TX     0X20
#define STA_MARK_MX     0X10            


//AD轉(zhuǎn)換
//#ifndef _STC12_ADC_H_
//#define _STC12_ADC_H_
#define ADC_POWER 0x80          //ADC power control bit        給ADC上電 置位ADC_power
#define ADC_FLAG 0x10           //ADC complete flag   ADC轉(zhuǎn)換完成標(biāo)志
#define ADC_START 0x08          //ADC start control bit   ADC開始轉(zhuǎn)換
#define ADC_SPEEDH 0x40           //180 clocks                 原來為0x00 =540? 但好像不符合
#define ADC_SPEEDLL  0x00  
#define ADC_SPEEDL   0x20  
#define ADC_SPEEDHH  0x60  
sfr ADC_LOW2 = 0xBE;           //ADC low 2-bit result register        低2位
void Init_ADC( );
unsigned int GetADC(unsigned char ch);
float AD_av(unsigned char ch);
//#endif




sbit  remote_IRQ=P0^3;
sbit  remote_CE=P0^5;
sbit  remote_CSN=P1^3;
sbit  remote_SCK=P1^7;
sbit  remote_MOSI=P1^5;
sbit  remote_MISO=P1^6;        //定義nrf24l01芯片管腳



//定義ps2搖桿管腳
sbit ps2_vcc1=P0^0;                 
sbit ps2_gnd1=P0^4;
sbit ps2_y1=P1^0 ;                 //1號y

sbit ps2_vcc2=P0^1;                 
sbit ps2_gnd2=P0^2;
sbit ps2_x2=P1^1 ;                 //2號x        


unsigned int  bdata sta;           //狀態(tài)標(biāo)志
sbit     RX_DR =sta^6;           //定義再可位尋址區(qū)的變量
sbit     TX_DS =sta^5;
sbit     MAX_RT =sta^4;


#define TX_DATA_WIDTH 32  //數(shù)據(jù)長度為32
#define RX_DATA_WIDTH 32
#define TX_ADR_WIDTH 5           //地址長度為5
#define RX_ADR_WIDTH 5
#define remote_TX_Mode 0x0e        //發(fā)送模式
#define remote_RX_Mode 0x0f        //接收模式


typedef unsigned int u16;
typedef unsigned char u8;


u8 code  TX_ADDRESS[TX_ADR_WIDTH]  = {0x17,0x14,0x14,0x93,0xcd}; //本機(jī)地址
u8 code  RX_ADDRESS[RX_ADR_WIDTH]  = {0x17,0x14,0x14,0x93,0xcd}; //接受端地址
//u8 Tx_Buffer1[DATA_WIDTH];
//u8 Tx_Buffer2[DATA_WIDTH];


//延時(shí)函數(shù)
void inerDelay_us(unsigned char n)
{
      for(;n>0;n--)
      _nop_();
}

void delay_ms(unsigned char x)
{
    unsigned char i, j;
    i = 0;
    for(i=0; i<x; i++)
    {
       j = 250;
       while(--j);
           j = 250;
       while(--j);
    }
}


void delay(unsigned int k)
{
    unsigned int i,j;
    for(i=0;i<k;i++)
    {
                for(j=0;j<121;j++)
                {;}
        }
}





u16 remote_SPI_Drive(u16 Dat)                        //spi協(xié)議配置 設(shè)置spi寫時(shí)序                                                                                                                                                                                
{
        u16 i;                                                        //定義循環(huán)量
        remote_SCK=0;                                   // 輸出 8-bit
        for(i=0;i<8;i++)                          
        {
        remote_MOSI=Dat&0x80;                   // 輸出 'Dat', 高位 進(jìn)入 MOSI
        Dat<<=1;                                          // 進(jìn)行移位 轉(zhuǎn)換下一位數(shù)據(jù)為高位
        remote_SCK=1;                                  // spi時(shí)鐘設(shè)為高
        Dat|=remote_MISO;                          // 讀取當(dāng)前的MISO位                     
        remote_SCK=0;                                  // spi時(shí)鐘設(shè)為低
        }
  return Dat;
}


u16 remote_Write_Read_Reg_Drive(u8 reg,u8 value)          //NRF24L01用spi讀寫寄存器函數(shù)        
{
        u16 status;                                                        // CSN=0,初始化spi                                                      
          status = remote_SPI_Drive(reg);         // 選擇寄存器作為讀取來源 讀寄存器                                       
        remote_SPI_Drive(value);                 //將value寫入寄存器
        remote_CSN=1;
        return status;
}


u16 remote_Read_Buffer_Drive(u8 reg,u8 *pBuf,u8 len)        //用于讀數(shù)據(jù),
//reg 為寄存器地址,pBuf:為待讀出數(shù)據(jù)地址,len:讀出數(shù)據(jù)的個(gè)數(shù)
{
        u16 status,k;
        remote_CSN=0;   
          status=remote_SPI_Drive(reg);              
         for(k=0;k<len;k++)
        {
                pBuf[k]=remote_SPI_Drive(NOP);
        }
        remote_CSN=1;
          return status;
}


u8 remote_Write_Buffer_Drive(u8 reg, u8 *pBuf, u8 len)    // 用于寫數(shù)據(jù):reg 為寄存器地址
//pBuf:為待寫入數(shù)據(jù)地址,len:寫入數(shù)據(jù)的個(gè)數(shù)
{
        u8 status,k;
        remote_CSN=0;                                                                                       
          status = remote_SPI_Drive(reg);                                                
          for(k=0; k<len; k++)
        {
                remote_SPI_Drive(*pBuf++);                                                
        }
        remote_CSN=1;                                                                                       
          return status;                                                                          
}


void remote_Init(void)    //nrf24l01芯片初始化
{
        remote_CE=0;                                 //使能
        remote_CSN=1;                                 //spi中斷
        remote_SCK=0;                                 //spi時(shí)鐘
        remote_Write_Buffer_Drive(WRITE_REG+TX_ADDR,TX_ADDRESS,TX_ADR_WIDTH);                 // 寫本地地址 地址值 長度
        remote_Write_Buffer_Drive(WRITE_REG+RX_ADDR_P0,TX_ADDRESS,RX_ADR_WIDTH);         //        寫接收端地址 地址
        remote_Write_Read_Reg_Drive(WRITE_REG+RX_PW_P0,RX_DATA_WIDTH);          //設(shè)置接收數(shù)據(jù)長度 通道0接受32長度的數(shù)據(jù)
        remote_Write_Read_Reg_Drive(WRITE_REG + EN_AA, 0x01);      //  頻道0自動              ACK應(yīng)答允許 即自動應(yīng)答            
    remote_Write_Read_Reg_Drive(WRITE_REG + EN_RXADDR, 0x01);  //  允許接收地址只有頻道0,如果需要多頻道可以參考Page21
        remote_Write_Read_Reg_Drive(WRITE_REG+RF_CH,55);                          //設(shè)置通信頻率為2454HZ
        remote_Write_Read_Reg_Drive(WRITE_REG+RF_SETUP,0x0f);                  //數(shù)據(jù)傳輸率2Mbps,發(fā)射功率0dBm,最遠(yuǎn)
        remote_Write_Read_Reg_Drive(WRITE_REG+SETUP_RETR,0x0f);                  //建立自動重發(fā) 間隔250us 重發(fā)15次
}

//這個(gè)相當(dāng)于remote_Init不傳參數(shù) 將0x0f即 remote_RX_Mode賦值給函數(shù)
//即為接受函數(shù)
void SetRX_Mode(void)                                                                                                //數(shù)據(jù)接收配置
{
     remote_CE=0;
     remote_Write_Read_Reg_Drive(WRITE_REG + CONFIG, remote_TX_Mode);     // IRQ收發(fā)完成中斷響應(yīng),16位CRC ,主接收 0x0f表示接收
     remote_CE = 1;
     inerDelay_us(130);
}


//數(shù)據(jù)讀取后放如rx_buf接收緩沖區(qū)中
unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)                                 
{
        unsigned char revale=0;
    sta = remote_SPI_Drive(STATUS);              // 讀取狀態(tài)寄存 STATUS為狀態(tài)寄存器 其來判斷數(shù)據(jù)接收狀況
    if(RX_DR)                                            // 判斷是否接收到數(shù)據(jù)
    {
            remote_CE = 0;                                           //SPI使能
        remote_Read_Buffer_Drive(RD_RX_PLOAD,rx_buf,TX_DATA_WIDTH);      // read receive payload from RX_FIFO buffer
        revale =1;                                           //讀取數(shù)據(jù)完成標(biāo)志
    }
    remote_Write_Read_Reg_Drive(WRITE_REG+STATUS,sta);       //接收到數(shù)據(jù)后RX_DR,TX_DS,MAX_PT都置高為1,通過寫1來清楚中斷標(biāo)志
    return revale;
}


//發(fā)送 tx_buf中數(shù)據(jù)
void nRF24L01_TxPacket(unsigned char * tx_buf)
{
        remote_CE=0;                                              //StandBy I 待機(jī)模式            
    remote_Write_Buffer_Drive(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH);   // 裝載接收端地址
    remote_Write_Buffer_Drive(WR_TX_PLOAD, tx_buf, TX_DATA_WIDTH);                // 裝載數(shù)據(jù)            
    remote_Write_Read_Reg_Drive(WRITE_REG + CONFIG, remote_TX_Mode);      // IRQ收發(fā)完成中斷響應(yīng),16位CRC,remote_TX_Mode即0x0e  主發(fā)送
    remote_CE=1;                                            //置高CE,激發(fā)數(shù)據(jù)發(fā)送
    inerDelay_us(10);
}


//AD采集   初始化
void Init_ADC(void)
{
  P1M0=0X03;
  P1M1=0X03;           //P1^0 P1^1作為AD采集位
  P1ASF = 0x03;    //P1^0,1采集電壓
  ADC_RES = 0;     //清空轉(zhuǎn)換結(jié)果存儲寄存器
  ADC_LOW2=0;           
  ADC_CONTR = 0x00;                                   //寄存器初始化
  _nop_(); _nop_(); _nop_(); _nop_();      //等待ADC_CONTR值寫入  
        ADC_CONTR =ADC_CONTR |  ADC_SPEEDH | ADC_START ;
        _nop_(); _nop_(); _nop_(); _nop_();            //確保ADC_CONTR的值寫入
}

unsigned int GetADC(unsigned char ch)
{
        unsigned int res;
    ADC_CONTR =ADC_CONTR | ADC_POWER | ADC_START|ch ;
        _nop_(); _nop_(); _nop_(); _nop_();     //確保ADC_CONTR的值寫入
        while(!(ADC_CONTR & 0x10));             //如果AD轉(zhuǎn)換未結(jié)束FLAG位為0,程序在此等待,如果為1,跳出循環(huán)
        res=ADC_RES*4+ADC_LOW2;                 //讀AD轉(zhuǎn)換結(jié)果讀走AD轉(zhuǎn)換結(jié)果,由于ADC_DATA中存儲12位中的
                                                                                        //高8位,當(dāng)要轉(zhuǎn)換成10進(jìn)制時(shí),需將ADC_DATA中的數(shù)左移2位,即相當(dāng)于*4
    ADC_CONTR&=0xe7;                                                //清除標(biāo)志位
        return res;
}

float AD_av(unsigned char ch)
{
        float ADV;
        unsigned char num;
        for(num=20;num>0;num--)                                         //采集20次
        {
          ADV+=GetADC(ch);                                                 //求和
        }
        ADV/=20.0;
        ADV=ADV/4.0;
  return ADV;
}



//檢查接收設(shè)備有無接收到數(shù)據(jù)包,設(shè)定沒有收到應(yīng)答信號是否重發(fā)
//unsigned char Check_ACK(bit clear)
//{
//        while(remote_IRQ);
//        sta = remote_SPI_Drive(NOP);                    // 返回狀態(tài)寄存器
//        if(MAX_RT)                                                                                                  //1:最大重發(fā)計(jì)數(shù)中斷關(guān)閉
//                if(clear)                          // 是否清除TX FIFO,沒有清除在復(fù)位MAX_RT中斷標(biāo)志后重發(fā)
//                        remote_SPI_Drive(FLUSH_TX);
//        remote_Write_Read_Reg_Drive(WRITE_REG + STATUS, sta);  // 清除TX_DS或MAX_RT中斷標(biāo)志
//        remote_IRQ = 1;
//        if(TX_DS)
//                return(0x00);
//        else
//                return(0xff);
//}



void main(void)
{
        unsigned char _pwm,wheel,RxBuf[32]={0},TxBuf[32]; // 接收的數(shù)據(jù) 數(shù)組        
          delay(500);        
        remote_Init();         //模塊初始化
        Init_ADC();                 //AD初始化
        while(1)
    {
                SetRX_Mode();          //設(shè)置成接受模式
                  nRF24L01_RxPacket(RxBuf);
                  delay(10);
                //電機(jī)
                ps2_vcc1=1;
                ps2_gnd1=0;
                ps2_vcc2=1;
                ps2_gnd2=0;
                _pwm=(unsigned char)((256-AD_av(0)+70)*0.92);          //這個(gè)參數(shù)可能以后要調(diào)
            if(_pwm<140)
            {
                      Init_ADC();
                      TxBuf[1]=1;
                          _pwm=_pwm;
            }
                else
            {
                      TxBuf[1]=0;
                _pwm=_pwm;
                      delay(2);
            }
                //方向
                Init_ADC();
            wheel=(unsigned char)AD_av(1);            //  pwm:68~250         AD_av(1):(右)47~118~189(左) 有待考究
                  if(wheel<=105)       //右轉(zhuǎn)
            {
         //TxBuf[2]=_pwm-(130-wheel);
                 TxBuf[2]=0;
                TxBuf[3]=_pwm;
            }
                  if( wheel>105&&wheel<=131)                                       
                 {        
              //TxBuf[2]=_pwm;
                TxBuf[2]=1;
              TxBuf[3]=_pwm;
            }
                  if(wheel>131)     //左轉(zhuǎn)
            {                                 
                 //TxBuf[2]=_pwm;
                 TxBuf[2]=2;
               TxBuf[3]=_pwm-(wheel-100);
            }
        nRF24L01_TxPacket(TxBuf);        //發(fā)送數(shù)據(jù) Transmit Tx buffer data
        //        Check_ACK(1);
        delay(50);
        }
}
接受的代碼:
#include "stc12c5a.h"
#include "intrins.h"
//#include "stc12_adc.h"


//這個(gè)是寄存器基地址
#define READ_REG        0x00          //讀配置寄存器,低5位為寄存器地址
#define WRITE_REG       0x20          //寫配置寄存器,低5位為寄存器地址
#define RD_RX_PLOAD     0x61          //讀RX有效數(shù)據(jù),1~32字節(jié)
#define WR_TX_PLOAD     0xA0          //寫TX有效數(shù)據(jù),1~32字節(jié)
#define FLUSH_TX        0xE1          //清除TX FIFO寄存器.發(fā)射模式下用
#define FLUSH_RX        0xE2          //清除RX FIFO寄存器.接收模式下用
#define REUSE_TX_PL     0xE3          //重新使用上一包數(shù)據(jù),P_24L01_CE為高,數(shù)據(jù)包被不斷發(fā)送.
#define NOP             0xFF          //空操作,可以用來讀狀態(tài)寄存器         


// SPI(nRF24L01) registers(addresses) 這個(gè)是寄存器偏移地址
#define CONFIG          0x00          //配置寄存器地址                             
#define EN_AA           0x01          //使能自動應(yīng)答功能
#define EN_RXADDR       0x02          //接收地址允許
#define SETUP_AW        0x03          //設(shè)置地址寬度(所有數(shù)據(jù)通道)
#define SETUP_RETR      0x04          //建立自動重發(fā)
#define RF_CH           0x05          //RF通道
#define RF_SETUP        0x06          //RF寄存器
#define STATUS          0x07          //狀態(tài)寄存器
#define OBSERVE_TX      0x08          // 發(fā)送檢測寄存器
#define CD              0x09          // 載波檢測寄存器
#define RX_ADDR_P0      0x0A          // 數(shù)據(jù)通道0接收地址
#define RX_ADDR_P1      0x0B          // 數(shù)據(jù)通道1接收地址
#define RX_ADDR_P2      0x0C          // 數(shù)據(jù)通道2接收地址
#define RX_ADDR_P3      0x0D          // 數(shù)據(jù)通道3接收地址
#define RX_ADDR_P4      0x0E          // 數(shù)據(jù)通道4接收地址
#define RX_ADDR_P5      0x0F          // 數(shù)據(jù)通道5接收地址
#define TX_ADDR         0x10          // 發(fā)送地址寄存器
#define RX_PW_P0        0x11          // 接收數(shù)據(jù)通道0有效數(shù)據(jù)寬度(1~32字節(jié))
#define RX_PW_P1        0x12          // 接收數(shù)據(jù)通道1有效數(shù)據(jù)寬度(1~32字節(jié))
#define RX_PW_P2        0x13          // 接收數(shù)據(jù)通道2有效數(shù)據(jù)寬度(1~32字節(jié))
#define RX_PW_P3        0x14          // 接收數(shù)據(jù)通道3有效數(shù)據(jù)寬度(1~32字節(jié))
#define RX_PW_P4        0x15          // 接收數(shù)據(jù)通道4有效數(shù)據(jù)寬度(1~32字節(jié))
#define RX_PW_P5        0x16          // 接收數(shù)據(jù)通道5有效數(shù)據(jù)寬度(1~32字節(jié))
#define FIFO_STATUS     0x17          // FIFO狀態(tài)寄存器
#define STA_MARK_RX     0X40
#define STA_MARK_TX     0X20
#define STA_MARK_MX     0X10            


//AD轉(zhuǎn)換
//#ifndef _STC12_ADC_H_
//#define _STC12_ADC_H_
#define ADC_POWER 0x80          //ADC power control bit        給ADC上電 置位ADC_power
#define ADC_FLAG 0x10           //ADC complete flag   ADC轉(zhuǎn)換完成標(biāo)志
#define ADC_START 0x08          //ADC start control bit   ADC開始轉(zhuǎn)換
#define ADC_SPEEDH 0x40           //180 clocks                 原來為0x00 =540? 但好像不符合
#define ADC_SPEEDLL  0x00  
#define ADC_SPEEDL   0x20  
#define ADC_SPEEDHH  0x60  
sfr ADC_LOW2 = 0xBE;           //ADC low 2-bit result register        低2位
void Init_ADC( );
unsigned int GetADC(unsigned char ch);
float AD_av(unsigned char ch);
//#endif




sbit  remote_IRQ=P0^3;
sbit  remote_CE=P0^5;
sbit  remote_CSN=P1^3;
sbit  remote_SCK=P1^7;
sbit  remote_MOSI=P1^5;
sbit  remote_MISO=P1^6;        //定義nrf24l01芯片管腳



//定義輸出管腳 電機(jī)驅(qū)動
sbit IN1=P1^0;
sbit IN2=P1^1;

//sg90 舵機(jī)
sbit Zheng=P2^0;
sbit Fu=P2^1;
sbit _pwm_=P2^2;



unsigned int  bdata sta;           //狀態(tài)標(biāo)志
sbit     RX_DR =sta^6;           //定義再可位尋址區(qū)的變量
sbit     TX_DS =sta^5;
sbit     MAX_RT =sta^4;


#define TX_DATA_WIDTH 32  //數(shù)據(jù)長度為32
#define RX_DATA_WIDTH 32
#define TX_ADR_WIDTH 5           //地址長度為5
#define RX_ADR_WIDTH 5
#define remote_TX_Mode 0x0e        //發(fā)送模式
#define remote_RX_Mode 0x0f        //接收模式


typedef unsigned int u16;
typedef unsigned char u8;


u8 code  TX_ADDRESS[TX_ADR_WIDTH]  = {0x17,0x14,0x14,0x93,0xcd}; //本機(jī)地址
u8 code  RX_ADDRESS[RX_ADR_WIDTH]  = {0x17,0x14,0x14,0x93,0xcd}; //接受端地址
//u8 Tx_Buffer1[DATA_WIDTH];
//u8 Tx_Buffer2[DATA_WIDTH];


//延時(shí)函數(shù)
void inerDelay_us(unsigned char n)
{
      for(;n>0;n--)
      _nop_();
}

void delay_ms(unsigned char x)
{
    unsigned char i, j;
    i = 0;
    for(i=0; i<x; i++)
    {
       j = 250;
       while(--j);
           j = 250;
       while(--j);
    }
}


void delay(unsigned int k)
{
    unsigned int i,j;
    for(i=0;i<k;i++)
    {
                for(j=0;j<121;j++)
                {;}
        }
}





u16 remote_SPI_Drive(u16 Dat)                        //spi協(xié)議配置 設(shè)置spi寫時(shí)序                                                                                                                                                                                
{
        u16 i;                                                        //定義循環(huán)量
        remote_SCK=0;                                   // 輸出 8-bit
        for(i=0;i<8;i++)                          
        {
        remote_MOSI=Dat&0x80;                   // 輸出 'Dat', 高位 進(jìn)入 MOSI
        Dat<<=1;                                          // 進(jìn)行移位 轉(zhuǎn)換下一位數(shù)據(jù)為高位
        remote_SCK=1;                                  // spi時(shí)鐘設(shè)為高
        Dat|=remote_MISO;                          // 讀取當(dāng)前的MISO位                     
        remote_SCK=0;                                  // spi時(shí)鐘設(shè)為低
        }
  return Dat;
}


u16 remote_Write_Read_Reg_Drive(u8 reg,u8 value)          //NRF24L01用spi讀寫寄存器函數(shù)        
{
        u16 status;                                                        // CSN=0,初始化spi                                                      
          status = remote_SPI_Drive(reg);         // 選擇寄存器作為讀取來源 讀寄存器                                       
        remote_SPI_Drive(value);                 //將value寫入寄存器
        remote_CSN=1;
        return status;
}


u16 remote_Read_Buffer_Drive(u8 reg,u8 *pBuf,u8 len)        //用于讀數(shù)據(jù),
//reg 為寄存器地址,pBuf:為待讀出數(shù)據(jù)地址,len:讀出數(shù)據(jù)的個(gè)數(shù)
{
        u16 status,k;
        remote_CSN=0;   
          status=remote_SPI_Drive(reg);              
         for(k=0;k<len;k++)
        {
                pBuf[k]=remote_SPI_Drive(NOP);
        }
        remote_CSN=1;
          return status;
}


u8 remote_Write_Buffer_Drive(u8 reg, u8 *pBuf, u8 len)    // 用于寫數(shù)據(jù):reg 為寄存器地址
//pBuf:為待寫入數(shù)據(jù)地址,len:寫入數(shù)據(jù)的個(gè)數(shù)
{
        u8 status,k;
        remote_CSN=0;                                                                                       
          status = remote_SPI_Drive(reg);                                                
          for(k=0; k<len; k++)
        {
                remote_SPI_Drive(*pBuf++);                                                
        }
        remote_CSN=1;                                                                                       
          return status;                                                                          
}


void remote_Init(void)    //nrf24l01芯片初始化
{
        remote_CE=0;                                 //使能
        remote_CSN=1;                                 //spi中斷
        remote_SCK=0;                                 //spi時(shí)鐘
        remote_Write_Buffer_Drive(WRITE_REG+TX_ADDR,TX_ADDRESS,TX_ADR_WIDTH);                 // 寫本地地址 地址值 長度
        remote_Write_Buffer_Drive(WRITE_REG+RX_ADDR_P0,TX_ADDRESS,RX_ADR_WIDTH);         //        寫接收端地址 地址
        remote_Write_Read_Reg_Drive(WRITE_REG+RX_PW_P0,RX_DATA_WIDTH);          //設(shè)置接收數(shù)據(jù)長度 通道0接受32長度的數(shù)據(jù)
        remote_Write_Read_Reg_Drive(WRITE_REG + EN_AA, 0x01);      //  頻道0自動              ACK應(yīng)答允許 即自動應(yīng)答            
    remote_Write_Read_Reg_Drive(WRITE_REG + EN_RXADDR, 0x01);  //  允許接收地址只有頻道0,如果需要多頻道可以參考Page21
        remote_Write_Read_Reg_Drive(WRITE_REG+RF_CH,55);                          //設(shè)置通信頻率為2454HZ
        remote_Write_Read_Reg_Drive(WRITE_REG+RF_SETUP,0x0f);                  //數(shù)據(jù)傳輸率2Mbps,發(fā)射功率0dBm,最遠(yuǎn)
        remote_Write_Read_Reg_Drive(WRITE_REG+SETUP_RETR,0x0f);                  //建立自動重發(fā) 間隔250us 重發(fā)15次
}

//這個(gè)相當(dāng)于remote_Init不傳參數(shù) 將0x0f即 remote_RX_Mode賦值給函數(shù)
//即為接受函數(shù)
void SetRX_Mode(void)                                                                                                //數(shù)據(jù)接收配置
{
     remote_CE=0;
     remote_Write_Read_Reg_Drive(WRITE_REG + CONFIG, remote_RX_Mode);     // IRQ收發(fā)完成中斷響應(yīng),16位CRC ,主接收 0x0f表示接收
     remote_CE = 1;
     inerDelay_us(130);
}


//數(shù)據(jù)讀取后放如rx_buf接收緩沖區(qū)中
unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)                                 
{
        unsigned char revale=0;
    sta = remote_SPI_Drive(STATUS);              // 讀取狀態(tài)寄存 STATUS為狀態(tài)寄存器 其來判斷數(shù)據(jù)接收狀況
    if(RX_DR)                                            // 判斷是否接收到數(shù)據(jù)
    {
            remote_CE = 0;                                           //SPI使能
        remote_Read_Buffer_Drive(RD_RX_PLOAD,rx_buf,TX_DATA_WIDTH);      // read receive payload from RX_FIFO buffer
        revale =1;                                           //讀取數(shù)據(jù)完成標(biāo)志
    }
    remote_Write_Read_Reg_Drive(WRITE_REG+STATUS,sta);       //接收到數(shù)據(jù)后RX_DR,TX_DS,MAX_PT都置高為1,通過寫1來清楚中斷標(biāo)志
    return revale;
}


//發(fā)送 tx_buf中數(shù)據(jù)
void nRF24L01_TxPacket(unsigned char * tx_buf)
{
        remote_CE=0;                                              //StandBy I 待機(jī)模式            
    remote_Write_Buffer_Drive(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH);   // 裝載接收端地址
    remote_Write_Buffer_Drive(WR_TX_PLOAD, tx_buf, TX_DATA_WIDTH);                // 裝載數(shù)據(jù)            
    remote_Write_Read_Reg_Drive(WRITE_REG + CONFIG, remote_TX_Mode);      // IRQ收發(fā)完成中斷響應(yīng),16位CRC,remote_TX_Mode即0x0e  主發(fā)送
    remote_CE=1;                                            //置高CE,激發(fā)數(shù)據(jù)發(fā)送
    inerDelay_us(10);
}


////檢查接收設(shè)備有無接收到數(shù)據(jù)包,設(shè)定沒有收到應(yīng)答信號是否重發(fā)
//unsigned char Check_ACK(bit clear)
//{
//        while(remote_IRQ);
//        sta = remote_SPI_Drive(NOP);                    // 返回狀態(tài)寄存器
//        if(MAX_RT)                                                                                                  //1:最大重發(fā)計(jì)數(shù)中斷關(guān)閉
//                if(clear)                          // 是否清除TX FIFO,沒有清除在復(fù)位MAX_RT中斷標(biāo)志后重發(fā)
//                        remote_SPI_Drive(FLUSH_TX);
//        remote_Write_Read_Reg_Drive(WRITE_REG + STATUS, sta);  // 清除TX_DS或MAX_RT中斷標(biāo)志
//        remote_IRQ = 1;
//        if(TX_DS)
//                return(0x00);
//        else
//                return(0xff);
//}


//產(chǎn)生pwm波形
#define Stop 0    //宏定義,停止
#define Left 1          //宏定義,左轉(zhuǎn)
#define Right 2          //宏定義,右轉(zhuǎn)
unsigned char TimeOutCounter = 0; //TimeOutCounter:定時(shí)器溢出計(jì)數(shù)
unsigned char LeftOrRight = 0;  //  LeftOrRight:舵機(jī)左右旋轉(zhuǎn)標(biāo)志



void InitialTimer ( void )  //配置定時(shí)器1
{
        {
    TMOD=0x10;       //定時(shí)/計(jì)數(shù)器1工作于方式1
    TH1 = ( 65535 - 500 ) / 256;          //0.25ms
        TL1 = ( 65535 - 500 ) % 256;
    EA=1;          //開總中斷
    ET1=1;         //允許定時(shí)/計(jì)數(shù)器1 中斷
    TR1=1;         //啟動定時(shí)/計(jì)數(shù)器1 中斷
        }
}

//void ControlLeftOrRight ( void )   //控制舵機(jī)函數(shù)
//{
//        if( RxBuf[2] == 0 )
//        {
//                //while ( !KeyStop );           //使標(biāo)志等于Stop(0),在中斷函數(shù)中將用到
//                LeftOrRight = Stop;
//        }
//
//        if( RxBuf[2] == 1 )
//        {
//                //while ( !KeyLeft );           //使標(biāo)志等于Left(1),在中斷函數(shù)中將用到
//                LeftOrRight = Left;
//        }
//
//        if( RxBuf[2] == 2 )
//        {
//                //while ( !KeyRight );   //使標(biāo)志等于Right(2),在中斷函數(shù)中將用到
//                LeftOrRight = Right;
//        }
//
//}





void main(void)
{

        unsigned char RxBuf[32]={0}; // 接收的數(shù)據(jù) 數(shù)組
          delay(500);        
        remote_Init();        //模塊初始化
        //PWM_init();
        //PWM_clock(2);      // PCA/PWM時(shí)鐘源為定時(shí)器0的溢出
          while(1)
          {
            SetRX_Mode();          //設(shè)置成接受模式
                  nRF24L01_RxPacket(RxBuf);
                  delay(10);   
             if(RxBuf[1]==0)             //制動
             {
                delay(10);
                        IN1=1;
                        IN2=1;
             }
             else                       
             {
                      if(RxBuf[0]==0)                        //停止
                      {
                                delay(10);
                                IN1=0;
                                IN2=0;
                      }
                        //else                                                            
              }
            //舵機(jī)
        InitialTimer();
        if( RxBuf[2] == 0 )
        {
                //while ( !KeyStop );           //使標(biāo)志等于Stop(0),在中斷函數(shù)中將用到
                LeftOrRight = Stop;
        }

        if( RxBuf[2] == 1 )
        {
                //while ( !KeyLeft );           //使標(biāo)志等于Left(1),在中斷函數(shù)中將用到
                LeftOrRight = Left;
        }

        if( RxBuf[2] == 2 )
        {
                //while ( !KeyRight );   //使標(biāo)志等于Right(2),在中斷函數(shù)中將用到
                LeftOrRight = Right;
        }
        switch ( LeftOrRight )
        {
                case 0 :          //為0時(shí),舵機(jī)歸位,脈寬1.5ms
                {
                        if( TimeOutCounter <= 3 )
                        {
                                Zheng=1;
                                Fu=0;
                                _pwm_ = 1;
                        }
                        else
                        {
                                _pwm_ = 0;
                        }
                        break;
                }
                case 1 :     //為1時(shí),舵機(jī)左轉(zhuǎn),脈寬1ms(理論值),實(shí)際可以調(diào)試得出
                {
                        if( TimeOutCounter <= 1 )
                        {
                                Zheng=1;
                                Fu=0;
                                _pwm_ = 1;
                        }
                        else
                        {
                                _pwm_ = 0;
                        }
                        break;
                }
                case 2 :   //為2時(shí),舵機(jī)右轉(zhuǎn),脈寬2ms(理論值),實(shí)際可以調(diào)試得出
                {
                        if( TimeOutCounter <= 6 )
                        {
                                Zheng=1;
                                Fu=0;
                                _pwm_ = 1;
                        }
                        else
                        {
                                _pwm_ = 0;
                        }
                        break;
                }
                default : break;
                }
        
        if( TimeOutCounter == 80 )         //周期20ms(理論值),比較可靠,最好不要修改
        {
                TimeOutCounter = 0;
        }
               
                delay(50);
        
        }
}
void Timer1( void ) interrupt 3  //定時(shí)器中斷函數(shù)
{
                  TH1 = ( 65535 - 500 ) / 256;
        TL1 = ( 65535 - 500 ) % 256;
        TimeOutCounter ++;
}


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表