久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2111|回復: 1
打印 上一主題 下一主題
收起左側

NRF控制的遙控車發射程序

[復制鏈接]
跳轉到指定樓層
樓主

#include <reg52.h>
#include <Intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit MISO=P1^4; //主收從發
sbit MOSI=P1^3; //主發從收
sbit SCK=P1^2; //串行時鐘信號
sbit CE=P1^1; //芯片使能
sbit CSN=P1^5; //片選信號
sbit IRQ=P1^6; //中斷查詢
/*************************************************************/
uchar seg[10]={~0x3f,~0x06,~0x5b,~0x4f,~0x66};
bit TxBufEndFlg = 1; //數據發送完成標志
uchar checkack();
uchar TxBuf[20]={0};
uchar RxBuf[20]={0};
uchar SPI_RW(uchar uchars);
uchar SPI_Read(uchar reg);
uchar SPI_RW_Reg(uchar reg, uchar value);
uchar SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars);
uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars);
uchar KeyScanPrg();
uchar KeyInState,KeyStateCnt;
/************************************************************/
#define TX_ADR_WIDTH    5   //發送地址長度為5個字節
#define RX_ADR_WIDTH    5   //接收地址長度為5個字節
#define TX_PLOAD_WIDTH  20  //發送數據長度為20個字節
#define RX_PLOAD_WIDTH  20  //接收數據長度為20個字節
uchar code TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //本地地址
uchar code RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //接收地址
//SPI命令
#define READ_REG        0x00  //讀第0個寄存器
#define WRITE_REG       0x20  //寫第0個寄存器
#define RD_RX_PLOAD     0x61  //在接收模式下使用,讀有效數據
#define WR_TX_PLOAD     0xA0  //在發送模式下使用,寫有效數據
#define FLUSH_TX        0xE1  //在發送模式下使用,清TX FIFO寄存器
#define FLUSH_RX        0xE2  //在接收模式下使用,清RX FIFO寄存器
#define REUSE_TX_PL     0xE3  //發送方使用,重復發送最后的數據
#define NOP             0xFF  //空操作,用于讀狀態寄存器STATUS的值
//NRF24L01寄存器地址
#define CONFIG          0x00  //配置寄存器,8bit
#define EN_AA           0x01  //自動應答設置寄存器,8bit
#define EN_RXADDR       0x02  //接收地址設置寄存器,8bit
#define SETUP_AW        0x03   //地址寬度設置寄存器,8bit
#define SETUP_RETR      0x04   //自動重復發送設置寄存器,8bit
#define RF_CH           0x05   // RF通道寄存器,8bit(工作頻率設置)
#define RF_SETUP        0x06   //RF設置寄存器,8bit(發射速率、功耗功能設置)
#define STATUS          0x07   //狀態寄存器,8bit
#define OBSERVE_TX      0x08   //發送檢測寄存器,8bit
#define CD              0x09   //載波檢測寄存器,8bit         
#define RX_ADDR_P0      0x0A   //接收地址數據通道0,40bit
#define RX_ADDR_P1      0x0B
#define RX_ADDR_P2      0x0C
#define RX_ADDR_P3      0x0D
#define RX_ADDR_P4      0x0E
#define RX_ADDR_P5      0x0F            
#define TX_ADDR         0x10   //發送地址,發送方使用,40bit
#define RX_PW_P0        0x11   //通道0接收的有效數據字節長度(1-32字節),8bit
#define RX_PW_P1        0x12
#define RX_PW_P2        0x13
#define RX_PW_P3        0x14
#define RX_PW_P4        0x15
#define RX_PW_P5        0x16
#define FIFO_STATUS     0x17   //FIFO棧入棧出狀態寄存器,8bit
//*********************************************************************************
void Delay(uint s);
void delayms(uchar z);
void inerDelay_us(uchar n);
void init_NRF24L01();
void nRF24L01_TxPacket(uchar * tx_buf);
void KeyDealPrg(uchar KeyState);
//**********************************************************************************
void inerDelay_us(uchar n)
{
  for(;n>0;n--)
   _nop_();
}

//************************************************************************************
uchar  bdata sta;   //狀態標志
sbit RX_DR =sta^6;
sbit TX_DS =sta^5;
sbit MAX_RT =sta^4;
//***************************checkack函數********************************************
uchar checkack()
{
sta=SPI_Read(STATUS);   // 返回狀態寄存器
  if(TX_DS || MAX_RT)   // 發送完畢中斷
  {
  if(MAX_RT)
  init_NRF24L01();
  TxBufEndFlg = 1;
     SPI_RW_Reg(WRITE_REG+STATUS,0xff);   // 清除TX_DS或MAX_RT中斷標志
   CSN=0;
         SPI_RW(FLUSH_TX); //在接收模式下,清空RX FIFO寄存器。在傳輸應答信號時不應執行此操作,否則不能傳輸完整的應答信號
      CSN=1;  
    return(1);
  }
  else
     return(0);
}
//***************************NRF24L01初始化********************************************
void init_NRF24L01(void)
{
  inerDelay_us(100);
  CE=0;    //芯片啟動
  CSN=1;   //終止SPI讀寫
  SCK=0;   //低電平為空閑時刻  
SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);    //寫本地地址
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); //寫接收端地址
  SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x4a); //自動延時1250us,自動重發10次
  SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);      //ENAA_P0=1,數據通道0自動應答
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);  // EN_RXADDR=1,接收地址允許
SPI_RW_Reg(WRITE_REG + RF_CH, 0);        //設置信道工作為2.4GHZ,收發必須一致
  SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //設置接收數據長度,本次設置為20字節
  SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);     //設置發射速率為1MHZ,發射功率為0dBm,低噪聲放大器增益
}
//***************************************SPI操作***********************************************
  
uchar SPI_RW(uchar uchars)//寫一個字節到NRF24L01,并返回此時NRF24L01的狀態及數據
{
  uchar bit_ctr;
     for(bit_ctr=0;bit_ctr<8;bit_ctr++)  //先寫字節的高位,再寫低位
     {
   MOSI = (uchars & 0x80);         //MOSI取uhcars最高位
   uchars = (uchars << 1);           //uchars左移一位
   SCK = 1;                      //SCK從高到低時開始寫入
   uchars |= MISO;           // 獲取MISO位,從MOSI寫命令的同時,MISO返回NRF24L01的狀態及數據
   SCK = 0;               
    }
     return(uchars);
}
  
uchar SPI_Read(uchar reg)//讀寄存器reg狀態字
{
  uchar reg_val;
  CSN = 0;                //CSN為0時,才能進行SPI讀寫
  SPI_RW(reg);            //選擇寄存器reg
  reg_val = SPI_RW(0);    //寫0,什么操作也不進行,僅僅為了讀寄存器狀態
  CSN = 1;                //終止SPI讀寫
  return(reg_val);      
}

uchar SPI_RW_Reg(uchar reg, uchar value)//將字節value寫入寄存器reg
{
  uchar status;
  CSN = 0;                   //CSN為0時,才能進行SPI讀寫
status = SPI_RW(reg);      //選擇寄存器reg
  SPI_RW(value);             //寫字節value到該寄存器.
  CSN = 1;                   //終止SPI讀寫
  return(status);           
}
  
uchar SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)//從寄存器reg讀出數據,典型應用是讀RX數據或RX/TXF地址
{
  uchar status,uchar_ctr;
  CSN = 0;                      //CSN為0時,才能進行SPI讀寫
  status = SPI_RW(reg);         //選擇寄存器reg并返回其狀態字
  for(uchar_ctr=0;uchar_ctr<uchars;uchar_ctr++)
  pBuf[uchar_ctr] = SPI_RW(0);    //從寄存器讀數據
  CSN = 1;                         //終止SPI讀寫
return(status);                    //返回狀態值
}

uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)//將數據寫入寄存器,如TX數據,RX/TX地址等
{
  uchar status,uchar_ctr;
  CSN = 0;            // CSN為0時,才能進行SPI讀寫
     status = SPI_RW(reg);  //選擇寄存器reg并返回其狀態字
  for(uchar_ctr=0; uchar_ctr<uchars; uchar_ctr++)
  SPI_RW(*pBuf++); //寫數據到寄存器
CSN = 1;           //終止SPI讀寫
  return(status);    //返回狀態值
}

/***********************************************************************************************************
/*函數:void nRF24L01_TxPacket(unsigned char * tx_buf)
/*功能:發送 tx_buf中數據
/**********************************************************************************************************/
void nRF24L01_TxPacket(unsigned char * tx_buf)
{
    if(TxBufEndFlg)
  {
  CE=0;   //待機模式I
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); //裝載接收端地址
  SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH);     //裝載數據
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e);      //CRC使能,CRC校驗值為2字節,上電,設置為發射模式
  CE=1;   //置高CE,激發數據發送
  TxBufEndFlg = 0; //標志位清0
  inerDelay_us(1000);
  }
}
/*****************************************************************************/
/*函數:
/*功能:按鍵采集掃描
/*****************************************************************************/
uchar KeyScanPrg(void)
{
  uchar KeyStateRAM,KeyState=0;
KeyStateRAM  = P2;
  KeyStateRAM &= 0xf0; //用到的其實是P2.7 2.6 2.5 2.4這四個按鍵
  if(KeyStateRAM==KeyInState)
     {
   if(KeyStateCnt>20)
   {
   KeyState = KeyInState;
   }
   else
   KeyStateCnt++;
     }
  else
     {
     KeyInState = KeyStateRAM;
     KeyStateCnt = 0;
     }
  return(KeyState);
}
/*****************************************************************************/
/*函數:
/*功能:按鍵處理
/*****************************************************************************/
void KeyDealPrg(uchar KeyState)
{
  switch(KeyState&0xf0)
   {
   case 0x70:P3=seg[1];TxBuf[1]=1;TxBuf[5]=0;
    break;
   case 0xb0:P3=seg[2];TxBuf[2]=1;TxBuf[5]=0;
    break;
   case 0xd0:P3=seg[3];TxBuf[3]=1;TxBuf[5]=0;
    break;
   case 0xe0:P3=seg[4];TxBuf[4]=1;TxBuf[5]=0;
    break;
   default  :P3=seg[0];
    TxBuf[1]=0;
    TxBuf[2]=0;
    TxBuf[3]=0;
    TxBuf[4]=0;
    TxBuf[5]=1;
   }
   nRF24L01_TxPacket(TxBuf);
   checkack();
}
/*****************************************************************************/
/*函數:
/*功能:主函數
/*****************************************************************************/
  void main(void)
{
    init_NRF24L01();
  while(1 )
  {
  KeyDealPrg(KeyScanPrg());
  }
}


timgPD97UI14.jpg (28.92 KB, 下載次數: 29)

timgPD97UI14.jpg
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:292673 發表于 2018-6-22 09:56 | 只看該作者
樓主可不可以把代碼。接收和發射的都給貼出來,好讓我們膜拜,學習下
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 天天色天天 | 国产精品久久久久久一级毛片 | 国产一区二区毛片 | av黄色免费在线观看 | 日韩在线免费播放 | va在线| 久久久免费观看视频 | 亚洲成人第一页 | 午夜精品久久久久久久久久久久 | 国产视频1区2区 | 亚洲九九精品 | 国产剧情一区 | 91 久久 | 伊人一区 | 国产一级视屏 | 国产精品久久久久久久久久久久久 | 国产亚洲黄色片 | 精品视频一区二区三区在线观看 | 91久久精品国产91久久性色tv | 91在线一区| 日韩电影a | 国产在线精品一区二区三区 | 午夜精品久久久久久久99黑人 | 国产精品爱久久久久久久 | 久久久综合色 | 国产精品免费一区二区三区四区 | 日韩a在线 | 国产成人精品一区二区三区在线 | 黄色一级大片在线观看 | 欧美精品三区 | 国产欧美精品一区二区 | 亚洲视频二区 | 中文字幕一区二区三区四区五区 | 黄色免费观看网站 | 国产成都精品91一区二区三 | 色999日韩 | 午夜视频在线免费观看 | 欧美日韩电影免费观看 | 日本精品一区二区 | 天天操夜夜操 | 一级黄色毛片免费 |