分享基于51單片機的nrf24l01遙控小車的一些制作文件,帶發送和接受的源程序,及ad畫的原理圖和pcb文件等資料
Altium Designer畫的原理圖和PCB圖如下:(51hei附件中可下載工程文件)
單片機源程序如下:
- #include <reg52.h>
- #include <intrins.h>
- typedef unsigned int uint;
- typedef unsigned char uchar;
-
- #define TX_ADDR_WITDH 5//發送地址寬度設置為5個字節
- #define RX_ADDR_WITDH 5//接收地址寬度設置為5個字節
- #define TX_DATA_WITDH 8//
- #define RX_DATA_WITDH 8
- /******************************************************************
- // nRF24L01指令格式:
- *******************************************************************/
- #define R_REGISTER 0x00 // 讀寄存器
- #define W_REGISTER 0x20 // 寫寄存器
- #define R_RX_PLOAD 0x61 // 讀RX FIFO有效數據,1-32字節,當讀數據完成后,數據被清除,應用于接收模式
- #define W_TX_PLOAD 0xA0 // 寫TX FIFO有效數據,1-32字節,寫操作從字節0開始,應用于發射模式
- #define FLUSH_TX 0xE1 // 清除TX FIFO寄存器,應用于發射模式
- #define FLUSH_RX 0xE2 // 清除RX FIFO寄存器,應用于接收模式
- #define REUSE_TX_PL 0xE3 // 重新使用上一包有效數據,當CE為高過程中,數據包被不斷的重新發射
- #define NOP 0xFF // 空操作,可以用來讀狀態寄存器
- /******************************************************************
- // nRF24L01寄存器地址
- *******************************************************************/
- #define CONFIG 0x00 // 配置寄存器
- #define EN_AA 0x01 // "自動應答"功能寄存
- #define EN_RX_ADDR 0x02 // 接收通道使能寄存器
- #define SETUP_AW 0x03 // 地址寬度設置寄存器
- #define SETUP_RETR 0x04 // 自動重發設置寄存器
- #define RF_CH 0x05 // 射頻通道頻率設置寄存器
- #define RF_SETUP 0x06 // 射頻設置寄存器
- #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有效數據寬度設置寄存器
- #define RX_PW_P1 0x12 // 數據通道1有效數據寬度設置寄存器
- #define RX_PW_P2 0x13 // 數據通道2有效數據寬度設置寄存器
- #define RX_PW_P3 0x14 // 數據通道3有效數據寬度設置寄存器
- #define RX_PW_P4 0x15 // 數據通道4有效數據寬度設置寄存器
- #define RX_PW_P5 0x16 // 數據通道5有效數據寬度設置寄存器
- #define FIFO_STATUS 0x17 // FIFO狀態寄存器
- //*********************************************************************************
- uchar sta; // 狀態變量
- #define RX_DR (sta & 0x40) // 接收成功中斷標志
- #define TX_DS (sta & 0x20) // 發射成功中斷標志
- #define MAX_RT (sta & 0x10) // 重發溢出中斷標志
- sbit CE=P2^0;
- sbit IRQ=P1^0;
- sbit CSN=P2^1;
- sbit MOSI=P2^3;
- sbit MISO=P2^4;
- sbit SCK=P2^2;
- sbit LED=P0^0;
- sbit Key=P3^2;
-
- uchar code TX_Addr[]={0x34,0x43,0x10,0x10,0x01};
- uchar code TX_Buffer[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x00};
- uchar RX_Buffer[RX_DATA_WITDH];
-
- void _delay_us(uint x)
- {
- uint i,j;
- for (j=0;j<x;j++)
- for (i=0;i<12;i++);
- }
- void _delay_ms(uint x)
- {
- uint i,j;
- for (j=0;j<x;j++)
- for (i=0;i<120;i++);
- }
- /*nRF24L01初始化*/
- void nRF24L01_Init(void)
- {
- CE=0;//待機模式Ⅰ
- CSN=1;
- SCK=0;
- IRQ=1;
- }
- /*SPI時序函數*/
- uchar SPI_RW(uchar byte)
- {
- uchar i;
- for(i=0;i<8;i++)//一字節8位循環8次寫入
- {
- if(byte&0x80)//如果數據最高位是1
- MOSI=1;//向NRF24L01寫1
- else //否則寫0
- MOSI=0;
- byte<<=1;//低一位移到最高位
- SCK=1;//SCK拉高,寫入一位數據,同時讀取一位數據
- if(MISO)
- byte|=0x01;
- SCK=0;//SCK拉低
- }
- return byte;//返回讀取一字節
- }
- /*SPI寫寄存器一字節函數*/
- /*reg:寄存器地址*/
- /*value:一字節(值)*/
- uchar SPI_W_Reg(uchar reg,uchar value)
- {
- uchar status;//返回狀態
- CSN=0;//SPI片選
- status=SPI_RW(reg);//寫入寄存器地址,同時讀取狀態
- SPI_RW(value);//寫入一字節
- CSN=1;//
- return status;//返回狀態
- }
- /*SPI讀一字節*/
- uchar SPI_R_byte(uchar reg)
- {
- uchar reg_value;
- CSN=0;//SPI片選
- SPI_RW(reg);//寫入地址
- reg_value=SPI_RW(0);//讀取寄存器的值
- CSN=1;
- return reg_value;//返回讀取的值
- }
- /*SPI讀取RXFIFO寄存器數據*/
- /*reg:寄存器地址*/
- /*Dat_Buffer:用來存讀取的數據*/
- /*DLen:數據長度*/
- uchar SPI_R_DBuffer(uchar reg,uchar *Dat_Buffer,uchar Dlen)
- {
- uchar status,i;
- CSN=0;//SPI片選
- status=SPI_RW(reg);//寫入寄存器地址,同時狀態
- for(i=0;i<Dlen;i++)
- {
- Dat_Buffer[i]=SPI_RW(0);//存儲數據
- }
- CSN=1;
- return status;
- }
- /*SPI向TXFIFO寄存器寫入數據*/
- /*reg:寫入寄存器地址*/
- /*TX_Dat_Buffer:存放需要發送的數據*/
- /*Dlen:數據長度*/
- uchar SPI_W_DBuffer(uchar reg,uchar *TX_Dat_Buffer,uchar Dlen)
- {
- uchar status,i;
- CSN=0;//SPI片選,啟動時序
- status=SPI_RW(reg);
- for(i=0;i<Dlen;i++)
- {
- SPI_RW(TX_Dat_Buffer[i]);//發送數據
- }
- CSN=1;
- return status;
- }
- /*設置發送模式*/
- void nRF24L01_Set_TX_Mode(uchar *TX_Data)
- {
- CE=0;//待機(寫寄存器之前一定要進入待機模式或掉電模式)
- SPI_W_DBuffer(W_REGISTER+TX_ADDR,TX_Addr,TX_ADDR_WITDH);/*寫寄存器指令+接收節點地址+地址寬度*/
- SPI_W_DBuffer(W_REGISTER+RX_ADDR_P0,TX_Addr,TX_ADDR_WITDH);/*為了接收設備應答信號,接收通道0地址與發送地址相同*/
- SPI_W_DBuffer(W_TX_PLOAD,TX_Data,TX_DATA_WITDH);/*寫有效數據地址+有效數據+有效數據寬度*/
- SPI_W_Reg(W_REGISTER+EN_AA,0x01);/*接收通道0自動應答*/
- SPI_W_Reg(W_REGISTER+EN_RX_ADDR,0x01);/*使能接收通道0*/
- SPI_W_Reg(W_REGISTER+SETUP_RETR,0x0a);/*自動重發延時250US+86US,重發10次*/
- SPI_W_Reg(W_REGISTER+RF_CH,0);/*(2400+40)MHZ選擇射頻通道0X40*/
- SPI_W_Reg(W_REGISTER+RF_SETUP,0x07);/*1Mbps速率,發射功率:0DBM,低噪聲放大器增益*/
- SPI_W_Reg(W_REGISTER+CONFIG,0x0e);/*發送模式,上電,16位CRC校驗,CRC使能*/
- CE=1;//啟動發射
- _delay_ms(5);/*CE高電平持續時間最少10US以上*/
- }
-
- uchar Check_Rec(void)
- {
- uchar status;
- sta=SPI_R_byte(R_REGISTER+STATUS);
- if(RX_DR)
- {
- CE=0;
- SPI_R_DBuffer(R_RX_PLOAD,RX_Buffer,RX_DATA_WITDH);
- status=1;
- }
- SPI_W_Reg(W_REGISTER+STATUS,0xff);
- return status;
- }
- /*檢測應答信號*/
- uchar Check_Ack(void)
- {
- sta=SPI_R_byte(R_REGISTER+STATUS);/*讀取寄存狀態*/
- if(TX_DS||MAX_RT)/*如果TX_DS或MAX_RT為1,則清除中斷和清除TX_FIFO寄存器的值*/
- {
- SPI_W_Reg(W_REGISTER+STATUS,0xff);
- CSN=0;
- SPI_RW(FLUSH_TX);/*如果沒有這一句只能發一次數據,大家要注意*/
- CSN=1;
- return 0;
- }
- else
- return 1;
- }
-
- void main(void)
- {
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
nrf24l01小車項目.zip
(11.15 MB, 下載次數: 293)
2017-5-23 21:27 上傳
點擊文件名下載附件
遙控車
|