找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1667|回复: 0
打印 上一主题 下一主题
收起左侧

求帮助 用51单片机做船模 但是一直调不通 用的nrf24l01 ps2摇杆 l298n 直流电机

[复制链接]
跳转到指定楼层
楼主
ID:489438 发表于 2019-3-27 23:49 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
发送的代码:
#include "stc12c5a.h"
#include "intrins.h"
//#include "stc12_adc.h"


//这个是寄存器基地址
#define READ_REG        0x00          //读配置寄存器,低5位为寄存器地址
#define WRITE_REG       0x20          //写配置寄存器,低5位为寄存器地址
#define RD_RX_PLOAD     0x61          //读RX有效数据,1~32字节
#define WR_TX_PLOAD     0xA0          //写TX有效数据,1~32字节
#define FLUSH_TX        0xE1          //清除TX FIFO寄存器.发射模式下用
#define FLUSH_RX        0xE2          //清除RX FIFO寄存器.接收模式下用
#define REUSE_TX_PL     0xE3          //重新使用上一包数据,P_24L01_CE为高,数据包被不断发送.
#define NOP             0xFF          //空操作,可以用来读状态寄存器         


// SPI(nRF24L01) registers(addresses) 这个是寄存器偏移地址
#define CONFIG          0x00          //配置寄存器地址                             
#define EN_AA           0x01          //使能自动应答功能
#define EN_RXADDR       0x02          //接收地址允许
#define SETUP_AW        0x03          //设置地址宽度(所有数据通道)
#define SETUP_RETR      0x04          //建立自动重发
#define RF_CH           0x05          //RF通道
#define RF_SETUP        0x06          //RF寄存器
#define STATUS          0x07          //状态寄存器
#define OBSERVE_TX      0x08          // 发送检测寄存器
#define CD              0x09          // 载波检测寄存器
#define RX_ADDR_P0      0x0A          // 数据通道0接收地址
#define RX_ADDR_P1      0x0B          // 数据通道1接收地址
#define RX_ADDR_P2      0x0C          // 数据通道2接收地址
#define RX_ADDR_P3      0x0D          // 数据通道3接收地址
#define RX_ADDR_P4      0x0E          // 数据通道4接收地址
#define RX_ADDR_P5      0x0F          // 数据通道5接收地址
#define TX_ADDR         0x10          // 发送地址寄存器
#define RX_PW_P0        0x11          // 接收数据通道0有效数据宽度(1~32字节)
#define RX_PW_P1        0x12          // 接收数据通道1有效数据宽度(1~32字节)
#define RX_PW_P2        0x13          // 接收数据通道2有效数据宽度(1~32字节)
#define RX_PW_P3        0x14          // 接收数据通道3有效数据宽度(1~32字节)
#define RX_PW_P4        0x15          // 接收数据通道4有效数据宽度(1~32字节)
#define RX_PW_P5        0x16          // 接收数据通道5有效数据宽度(1~32字节)
#define FIFO_STATUS     0x17          // FIFO状态寄存器
#define STA_MARK_RX     0X40
#define STA_MARK_TX     0X20
#define STA_MARK_MX     0X10            


//AD转换
//#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转换完成标志
#define ADC_START 0x08          //ADC start control bit   ADC开始转换
#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;           //状态标志
sbit     RX_DR =sta^6;           //定义再可位寻址区的变量
sbit     TX_DS =sta^5;
sbit     MAX_RT =sta^4;


#define TX_DATA_WIDTH 32  //数据长度为32
#define RX_DATA_WIDTH 32
#define TX_ADR_WIDTH 5           //地址长度为5
#define RX_ADR_WIDTH 5
#define remote_TX_Mode 0x0e        //发送模式
#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}; //本机地址
u8 code  RX_ADDRESS[RX_ADR_WIDTH]  = {0x17,0x14,0x14,0x93,0xcd}; //接受端地址
//u8 Tx_Buffer1[DATA_WIDTH];
//u8 Tx_Buffer2[DATA_WIDTH];


//延时函数
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协议配置 设置spi写时序                                                                                                                                                                                
{
        u16 i;                                                        //定义循环量
        remote_SCK=0;                                   // 输出 8-bit
        for(i=0;i<8;i++)                          
        {
        remote_MOSI=Dat&0x80;                   // 输出 'Dat', 高位 进入 MOSI
        Dat<<=1;                                          // 进行移位 转换下一位数据为高位
        remote_SCK=1;                                  // spi时钟设为高
        Dat|=remote_MISO;                          // 读取当前的MISO位                     
        remote_SCK=0;                                  // spi时钟设为低
        }
  return Dat;
}


u16 remote_Write_Read_Reg_Drive(u8 reg,u8 value)          //NRF24L01用spi读写寄存器函数        
{
        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)        //用于读数据,
//reg 为寄存器地址,pBuf:为待读出数据地址,len:读出数据的个数
{
        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)    // 用于写数据:reg 为寄存器地址
//pBuf:为待写入数据地址,len:写入数据的个数
{
        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时钟
        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);          //设置接收数据长度 通道0接受32长度的数据
        remote_Write_Read_Reg_Drive(WRITE_REG + EN_AA, 0x01);      //  频道0自动              ACK应答允许 即自动应答            
    remote_Write_Read_Reg_Drive(WRITE_REG + EN_RXADDR, 0x01);  //  允许接收地址只有频道0,如果需要多频道可以参考Page21
        remote_Write_Read_Reg_Drive(WRITE_REG+RF_CH,55);                          //设置通信频率为2454HZ
        remote_Write_Read_Reg_Drive(WRITE_REG+RF_SETUP,0x0f);                  //数据传输率2Mbps,发射功率0dBm,最远
        remote_Write_Read_Reg_Drive(WRITE_REG+SETUP_RETR,0x0f);                  //建立自动重发 间隔250us 重发15次
}

//这个相当于remote_Init不传参数 将0x0f即 remote_RX_Mode赋值给函数
//即为接受函数
void SetRX_Mode(void)                                                                                                //数据接收配置
{
     remote_CE=0;
     remote_Write_Read_Reg_Drive(WRITE_REG + CONFIG, remote_TX_Mode);     // IRQ收发完成中断响应,16位CRC ,主接收 0x0f表示接收
     remote_CE = 1;
     inerDelay_us(130);
}


//数据读取后放如rx_buf接收缓冲区中
unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)                                 
{
        unsigned char revale=0;
    sta = remote_SPI_Drive(STATUS);              // 读取状态寄存 STATUS为状态寄存器 其来判断数据接收状况
    if(RX_DR)                                            // 判断是否接收到数据
    {
            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;                                           //读取数据完成标志
    }
    remote_Write_Read_Reg_Drive(WRITE_REG+STATUS,sta);       //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标志
    return revale;
}


//发送 tx_buf中数据
void nRF24L01_TxPacket(unsigned char * tx_buf)
{
        remote_CE=0;                                              //StandBy I 待机模式            
    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);                // 装载数据            
    remote_Write_Read_Reg_Drive(WRITE_REG + CONFIG, remote_TX_Mode);      // IRQ收发完成中断响应,16位CRC,remote_TX_Mode即0x0e  主发送
    remote_CE=1;                                            //置高CE,激发数据发送
    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;     //清空转换结果存储寄存器
  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转换未结束FLAG位为0,程序在此等待,如果为1,跳出循环
        res=ADC_RES*4+ADC_LOW2;                 //读AD转换结果读走AD转换结果,由于ADC_DATA中存储12位中的
                                                                                        //高8位,当要转换成10进制时,需将ADC_DATA中的数左移2位,即相当于*4
    ADC_CONTR&=0xe7;                                                //清除标志位
        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;
}



//检查接收设备有无接收到数据包,设定没有收到应答信号是否重发
//unsigned char Check_ACK(bit clear)
//{
//        while(remote_IRQ);
//        sta = remote_SPI_Drive(NOP);                    // 返回状态寄存器
//        if(MAX_RT)                                                                                                  //1:最大重发计数中断关闭
//                if(clear)                          // 是否清除TX FIFO,没有清除在复位MAX_RT中断标志后重发
//                        remote_SPI_Drive(FLUSH_TX);
//        remote_Write_Read_Reg_Drive(WRITE_REG + STATUS, sta);  // 清除TX_DS或MAX_RT中断标志
//        remote_IRQ = 1;
//        if(TX_DS)
//                return(0x00);
//        else
//                return(0xff);
//}



void main(void)
{
        unsigned char _pwm,wheel,RxBuf[32]={0},TxBuf[32]; // 接收的数据 数组        
          delay(500);        
        remote_Init();         //模块初始化
        Init_ADC();                 //AD初始化
        while(1)
    {
                SetRX_Mode();          //设置成接受模式
                  nRF24L01_RxPacket(RxBuf);
                  delay(10);
                //电机
                ps2_vcc1=1;
                ps2_gnd1=0;
                ps2_vcc2=1;
                ps2_gnd2=0;
                _pwm=(unsigned char)((256-AD_av(0)+70)*0.92);          //这个参数可能以后要调
            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)       //右转
            {
         //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)     //左转
            {                                 
                 //TxBuf[2]=_pwm;
                 TxBuf[2]=2;
               TxBuf[3]=_pwm-(wheel-100);
            }
        nRF24L01_TxPacket(TxBuf);        //发送数据 Transmit Tx buffer data
        //        Check_ACK(1);
        delay(50);
        }
}
接受的代码:
#include "stc12c5a.h"
#include "intrins.h"
//#include "stc12_adc.h"


//这个是寄存器基地址
#define READ_REG        0x00          //读配置寄存器,低5位为寄存器地址
#define WRITE_REG       0x20          //写配置寄存器,低5位为寄存器地址
#define RD_RX_PLOAD     0x61          //读RX有效数据,1~32字节
#define WR_TX_PLOAD     0xA0          //写TX有效数据,1~32字节
#define FLUSH_TX        0xE1          //清除TX FIFO寄存器.发射模式下用
#define FLUSH_RX        0xE2          //清除RX FIFO寄存器.接收模式下用
#define REUSE_TX_PL     0xE3          //重新使用上一包数据,P_24L01_CE为高,数据包被不断发送.
#define NOP             0xFF          //空操作,可以用来读状态寄存器         


// SPI(nRF24L01) registers(addresses) 这个是寄存器偏移地址
#define CONFIG          0x00          //配置寄存器地址                             
#define EN_AA           0x01          //使能自动应答功能
#define EN_RXADDR       0x02          //接收地址允许
#define SETUP_AW        0x03          //设置地址宽度(所有数据通道)
#define SETUP_RETR      0x04          //建立自动重发
#define RF_CH           0x05          //RF通道
#define RF_SETUP        0x06          //RF寄存器
#define STATUS          0x07          //状态寄存器
#define OBSERVE_TX      0x08          // 发送检测寄存器
#define CD              0x09          // 载波检测寄存器
#define RX_ADDR_P0      0x0A          // 数据通道0接收地址
#define RX_ADDR_P1      0x0B          // 数据通道1接收地址
#define RX_ADDR_P2      0x0C          // 数据通道2接收地址
#define RX_ADDR_P3      0x0D          // 数据通道3接收地址
#define RX_ADDR_P4      0x0E          // 数据通道4接收地址
#define RX_ADDR_P5      0x0F          // 数据通道5接收地址
#define TX_ADDR         0x10          // 发送地址寄存器
#define RX_PW_P0        0x11          // 接收数据通道0有效数据宽度(1~32字节)
#define RX_PW_P1        0x12          // 接收数据通道1有效数据宽度(1~32字节)
#define RX_PW_P2        0x13          // 接收数据通道2有效数据宽度(1~32字节)
#define RX_PW_P3        0x14          // 接收数据通道3有效数据宽度(1~32字节)
#define RX_PW_P4        0x15          // 接收数据通道4有效数据宽度(1~32字节)
#define RX_PW_P5        0x16          // 接收数据通道5有效数据宽度(1~32字节)
#define FIFO_STATUS     0x17          // FIFO状态寄存器
#define STA_MARK_RX     0X40
#define STA_MARK_TX     0X20
#define STA_MARK_MX     0X10            


//AD转换
//#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转换完成标志
#define ADC_START 0x08          //ADC start control bit   ADC开始转换
#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芯片管脚



//定义输出管脚 电机驱动
sbit IN1=P1^0;
sbit IN2=P1^1;

//sg90 舵机
sbit Zheng=P2^0;
sbit Fu=P2^1;
sbit _pwm_=P2^2;



unsigned int  bdata sta;           //状态标志
sbit     RX_DR =sta^6;           //定义再可位寻址区的变量
sbit     TX_DS =sta^5;
sbit     MAX_RT =sta^4;


#define TX_DATA_WIDTH 32  //数据长度为32
#define RX_DATA_WIDTH 32
#define TX_ADR_WIDTH 5           //地址长度为5
#define RX_ADR_WIDTH 5
#define remote_TX_Mode 0x0e        //发送模式
#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}; //本机地址
u8 code  RX_ADDRESS[RX_ADR_WIDTH]  = {0x17,0x14,0x14,0x93,0xcd}; //接受端地址
//u8 Tx_Buffer1[DATA_WIDTH];
//u8 Tx_Buffer2[DATA_WIDTH];


//延时函数
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协议配置 设置spi写时序                                                                                                                                                                                
{
        u16 i;                                                        //定义循环量
        remote_SCK=0;                                   // 输出 8-bit
        for(i=0;i<8;i++)                          
        {
        remote_MOSI=Dat&0x80;                   // 输出 'Dat', 高位 进入 MOSI
        Dat<<=1;                                          // 进行移位 转换下一位数据为高位
        remote_SCK=1;                                  // spi时钟设为高
        Dat|=remote_MISO;                          // 读取当前的MISO位                     
        remote_SCK=0;                                  // spi时钟设为低
        }
  return Dat;
}


u16 remote_Write_Read_Reg_Drive(u8 reg,u8 value)          //NRF24L01用spi读写寄存器函数        
{
        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)        //用于读数据,
//reg 为寄存器地址,pBuf:为待读出数据地址,len:读出数据的个数
{
        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)    // 用于写数据:reg 为寄存器地址
//pBuf:为待写入数据地址,len:写入数据的个数
{
        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时钟
        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);          //设置接收数据长度 通道0接受32长度的数据
        remote_Write_Read_Reg_Drive(WRITE_REG + EN_AA, 0x01);      //  频道0自动              ACK应答允许 即自动应答            
    remote_Write_Read_Reg_Drive(WRITE_REG + EN_RXADDR, 0x01);  //  允许接收地址只有频道0,如果需要多频道可以参考Page21
        remote_Write_Read_Reg_Drive(WRITE_REG+RF_CH,55);                          //设置通信频率为2454HZ
        remote_Write_Read_Reg_Drive(WRITE_REG+RF_SETUP,0x0f);                  //数据传输率2Mbps,发射功率0dBm,最远
        remote_Write_Read_Reg_Drive(WRITE_REG+SETUP_RETR,0x0f);                  //建立自动重发 间隔250us 重发15次
}

//这个相当于remote_Init不传参数 将0x0f即 remote_RX_Mode赋值给函数
//即为接受函数
void SetRX_Mode(void)                                                                                                //数据接收配置
{
     remote_CE=0;
     remote_Write_Read_Reg_Drive(WRITE_REG + CONFIG, remote_RX_Mode);     // IRQ收发完成中断响应,16位CRC ,主接收 0x0f表示接收
     remote_CE = 1;
     inerDelay_us(130);
}


//数据读取后放如rx_buf接收缓冲区中
unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)                                 
{
        unsigned char revale=0;
    sta = remote_SPI_Drive(STATUS);              // 读取状态寄存 STATUS为状态寄存器 其来判断数据接收状况
    if(RX_DR)                                            // 判断是否接收到数据
    {
            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;                                           //读取数据完成标志
    }
    remote_Write_Read_Reg_Drive(WRITE_REG+STATUS,sta);       //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标志
    return revale;
}


//发送 tx_buf中数据
void nRF24L01_TxPacket(unsigned char * tx_buf)
{
        remote_CE=0;                                              //StandBy I 待机模式            
    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);                // 装载数据            
    remote_Write_Read_Reg_Drive(WRITE_REG + CONFIG, remote_TX_Mode);      // IRQ收发完成中断响应,16位CRC,remote_TX_Mode即0x0e  主发送
    remote_CE=1;                                            //置高CE,激发数据发送
    inerDelay_us(10);
}


////检查接收设备有无接收到数据包,设定没有收到应答信号是否重发
//unsigned char Check_ACK(bit clear)
//{
//        while(remote_IRQ);
//        sta = remote_SPI_Drive(NOP);                    // 返回状态寄存器
//        if(MAX_RT)                                                                                                  //1:最大重发计数中断关闭
//                if(clear)                          // 是否清除TX FIFO,没有清除在复位MAX_RT中断标志后重发
//                        remote_SPI_Drive(FLUSH_TX);
//        remote_Write_Read_Reg_Drive(WRITE_REG + STATUS, sta);  // 清除TX_DS或MAX_RT中断标志
//        remote_IRQ = 1;
//        if(TX_DS)
//                return(0x00);
//        else
//                return(0xff);
//}


//产生pwm波形
#define Stop 0    //宏定义,停止
#define Left 1          //宏定义,左转
#define Right 2          //宏定义,右转
unsigned char TimeOutCounter = 0; //TimeOutCounter:定时器溢出计数
unsigned char LeftOrRight = 0;  //  LeftOrRight:舵机左右旋转标志



void InitialTimer ( void )  //配置定时器1
{
        {
    TMOD=0x10;       //定时/计数器1工作于方式1
    TH1 = ( 65535 - 500 ) / 256;          //0.25ms
        TL1 = ( 65535 - 500 ) % 256;
    EA=1;          //开总中断
    ET1=1;         //允许定时/计数器1 中断
    TR1=1;         //启动定时/计数器1 中断
        }
}

//void ControlLeftOrRight ( void )   //控制舵机函数
//{
//        if( RxBuf[2] == 0 )
//        {
//                //while ( !KeyStop );           //使标志等于Stop(0),在中断函数中将用到
//                LeftOrRight = Stop;
//        }
//
//        if( RxBuf[2] == 1 )
//        {
//                //while ( !KeyLeft );           //使标志等于Left(1),在中断函数中将用到
//                LeftOrRight = Left;
//        }
//
//        if( RxBuf[2] == 2 )
//        {
//                //while ( !KeyRight );   //使标志等于Right(2),在中断函数中将用到
//                LeftOrRight = Right;
//        }
//
//}





void main(void)
{

        unsigned char RxBuf[32]={0}; // 接收的数据 数组
          delay(500);        
        remote_Init();        //模块初始化
        //PWM_init();
        //PWM_clock(2);      // PCA/PWM时钟源为定时器0的溢出
          while(1)
          {
            SetRX_Mode();          //设置成接受模式
                  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                                                            
              }
            //舵机
        InitialTimer();
        if( RxBuf[2] == 0 )
        {
                //while ( !KeyStop );           //使标志等于Stop(0),在中断函数中将用到
                LeftOrRight = Stop;
        }

        if( RxBuf[2] == 1 )
        {
                //while ( !KeyLeft );           //使标志等于Left(1),在中断函数中将用到
                LeftOrRight = Left;
        }

        if( RxBuf[2] == 2 )
        {
                //while ( !KeyRight );   //使标志等于Right(2),在中断函数中将用到
                LeftOrRight = Right;
        }
        switch ( LeftOrRight )
        {
                case 0 :          //为0时,舵机归位,脉宽1.5ms
                {
                        if( TimeOutCounter <= 3 )
                        {
                                Zheng=1;
                                Fu=0;
                                _pwm_ = 1;
                        }
                        else
                        {
                                _pwm_ = 0;
                        }
                        break;
                }
                case 1 :     //为1时,舵机左转,脉宽1ms(理论值),实际可以调试得出
                {
                        if( TimeOutCounter <= 1 )
                        {
                                Zheng=1;
                                Fu=0;
                                _pwm_ = 1;
                        }
                        else
                        {
                                _pwm_ = 0;
                        }
                        break;
                }
                case 2 :   //为2时,舵机右转,脉宽2ms(理论值),实际可以调试得出
                {
                        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  //定时器中断函数
{
                  TH1 = ( 65535 - 500 ) / 256;
        TL1 = ( 65535 - 500 ) % 256;
        TimeOutCounter ++;
}


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表