欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136
標題:
nRF24L01程序
[打印本頁]
作者:
涵明云天
時間:
2017-5-15 20:31
標題:
nRF24L01程序
#include <reg51.h>
#include <intrins.h>
#include "spi.h"
#include "ds18b20.h"
/***************************************************/
//#define uchar unsigned char
//#define uint unsigned int
#define TX_ADR_WIDTH 5 // 收發地址5 字節寬TX(RX)
#define TX_PLOAD_WIDTH 20 // 發送數據包20 字節
uchar const TX_ADDRESS[TX_ADR_WIDTH] = {0x34,0x43,0x10,0x10,0x01};// 定義發送地址
uchar rx_buf[TX_PLOAD_WIDTH];//接收緩沖數組
uchar tx_buf[TX_PLOAD_WIDTH];//發送緩沖數組
uchar flag;//中斷標志
/**************************************************/
//nRF24L01 SPI口定義//
sbit CE = P1^7;
sbit CSN= P1^6;
sbit SCK= P1^5;
sbit MOSI= P1^4;
sbit MISO= P1^3;
sbit IRQ = P3^2;
sbit S2= P1^2;//發送按鈕
sbit LEDG= P3^7;
sbit LEDR= P3^5;
/**************************************************/
uchar bdata sta;
sbit RX_DR =sta^6;
sbit TX_DS =sta^5;
sbit MAX_RT =sta^4;
/**************************************************/
/**************************************************
函數: init_nRF24L01();
說明:
nRF24L01待機模式,
Spi 不能,Spi 時鐘線高
/**************************************************/
void init_nRF24L01(void)
{
CE=0; // 片選使能
CSN=1; // Spi 禁止
SCK=0; // Spi 時鐘初始化
}
/**************************************************/
/**************************************************
函數: init_int0();
說明:
開int0中斷;
/**************************************************/
void init_int0(void)
{
EA=1;
EX0=1; //開int0中斷.
}
/**************************************************/
void delay_ms(unsigned int x) //ms延時
{
unsigned int i,j;
i=0;
for(i=0;i<x;i++)
{
j=108;
;
while(j--);
}
}
/**************************************************/
/**************************************************
函數: SPI_RW();
說明:
寫單字節到nRF24L01, 同時返回從nRF24L01讀出的一字節
/**************************************************/
uchar SPI_RW(uchar byte)
{
uchar bit_ctr;
for(bit_ctr=0;bit_ctr<8;bit_ctr++) // 輸出 8-bit
{
MOSI = (byte & 0x80); // 輸出字節到MOSI, 最高位開始
byte = (byte << 1); // 左移一位
SCK = 1; // 時鐘置高
byte |= MISO; // 由MISO讀入1bit
SCK = 0; // 時鐘置低
}
return(byte); // 返回讀入的字節
}
/**************************************************/
/**************************************************
函數: SPI_RW_Reg();
說明:
寫一字節值'value'到地址為'reg'的寄存器
/**************************************************/
uchar SPI_RW_Reg(BYTE reg, BYTE value)
{
uchar status;
CSN = 0; // SPI 使能
status = SPI_RW(reg); // 選寄存器,并讀狀態值
SPI_RW(value); // 寫該寄存器
CSN = 1; // SPI禁止
return(status); // 返回狀態值
}
/**************************************************/
/**************************************************
函數: SPI_Read();
說明:
從 nRF24L01內地址為 'reg'的寄存器讀出一字節數據
/**************************************************/
BYTE SPI_Read(BYTE reg)
{
BYTE reg_val;
CSN = 0; // SPI 使能
SPI_RW(reg); // 選寄存器
reg_val = SPI_RW(0); // 讀寄存器
CSN = 1; // SPI 禁止
return(reg_val); // 返回寄存器值
}
/**************************************************/
/**************************************************
函數: SPI_Read_Buf();
說明:
從地址為'reg'的寄存器中讀出若干字節的數據到數組,例如從
RX payload 中讀出數據包。
/**************************************************/
uchar SPI_Read_Buf(BYTE reg, BYTE *pBuf, BYTE bytes)
{
uchar status,byte_ctr;
CSN = 0; // SPI 使能
status = SPI_RW(reg); // 選寄存器,并讀狀態值
for(byte_ctr=0;byte_ctr<bytes;byte_ctr++)
pBuf[byte_ctr] = SPI_RW(0); // 由nRF24L01讀出若干字節數據到數組
CSN = 1; // SPI 禁止
return(status); // 返回狀態字
}
/**************************************************/
/**************************************************
函數: SPI_Write_Buf();
說明:
把緩沖數組'*pBuf'中的數據寫入nRF24L01中的TX payload
/**************************************************/
uchar SPI_Write_Buf(BYTE reg, BYTE *pBuf, BYTE bytes)
{
uchar status,byte_ctr;
CSN = 0; // SPI 使能
status = SPI_RW(reg); // 選寄存器,并讀狀態值
for(byte_ctr=0; byte_ctr<bytes; byte_ctr++)// 把buffer(*pBuf)中的字節寫入
SPI_RW(*pBuf++);
CSN = 1; // SPI 禁止
return(status); // 返回狀態字節
}
/**************************************************/
/**************************************************
函數: RX_Mode();
說明:
初始化nRF24L01 為RX Mode,設定接收地址、RX payload 長度,
選擇RF 通道, 數據速率和LNA HCURR。然后置CE為高, 等待接收數據包
/**************************************************/
void RX_Mode(void)
{
CE=0;
// 收發設置相同的地址
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH);
SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // 使能自動應答Pipe0
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // Pipe0使能
SPI_RW_Reg(WRITE_REG + RF_CH, 40); // 選 射頻通道40
// 設置接收和發送 payload寬度相同
SPI_RW_Reg(WRITE_REG + RX_PW_P0, TX_PLOAD_WIDTH);
// 發送功率:0dBm, 數據速率:2Mbps, LNA:HCURR
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);
// 置位 PWR_UP, 使能CRC(2 bytes) 和主接收Prim:RX. 使能RX_DR
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f);
CE = 1; // 接收使能
// 器件已經準備好由發送方發來的16字節數據
// 自動應答'3443101001', 重發次數為10, 射頻通道為 40,數據速率 = 2Mbps.
}
/**************************************************/
/**************************************************
函數: TX_Mode();
說明:
初始化 nRF24L01 為TX mode, 設置 TX 地址、接收地址、自動應答,
向TX payload寫入數據, 選擇 RF 通道, 數據速率和 TX 發送功率.
加電, CRC(2 字節) 使能, 發送為PRIM:TX.當CE置高(>10us)之后
即發送數據包,然后轉入接收模式等待接收方的應答。
/**************************************************/
void TX_Mode(void)
{
CE=0;
// 寫發送地址TX_Address 到nRF24L01
SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);
// 自動應答的接收地址RX_Addr0 和 TX_Adr 相同
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH);
SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH); // 寫數據到 TX payload
SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // 使能自動應答到Pipe0
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // 使能Pipe0
SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x1a); // 500us + 86us, 10次重發
SPI_RW_Reg(WRITE_REG + RF_CH, 40); // 選射頻通道 40
// 發送功率:0dBm, 數據速率:2Mbps, LNA:HCURR
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);
// 置位 PWR_UP, 使能CRC(2 bytes) 和主發送Prim:TX. 使能MAX_RT 和 TX_DS
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e);
CE=1;
}
/**************************************************/
/**************************************************
函數: Send_uart();
說明:
寫數據到串口 SBUF
/**************************************************/
void Send_uart(uchar x)
{
SBUF=x;// write data x to SBUF
while(TI==0);
TI=0;
}
/**************************************************/
/**************************************************
函數: display();
說明:
在 LED數碼管上顯示數據
/**************************************************/
void display(uchar idata *p)
{
uchar code table[23]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,
0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0x8c,0xc1,0x89,0xc7,0x91,0xbf,0xff};
//共陽碼表,前16位是0~F,后面的如下:
//0x8c,0xc1,0x89,0xc7,0x91,0xbf,0xff
//P, U, H, L, Y, -, 不顯示
//10H, 11H, 12H, 13H, 14H, 15H, 16H
uchar adc,i;
for(i=0;i<4;i++)
{ adc=table[*p];//segement code
if(i==1)
{
adc=adc-0x80;//加小數點
}
Send_uart(adc);
p++;
}
}
/**************************************************/
/**************************************************
函數: CheckButtons();
說明:
檢查按鈕 ,若按鈕按下讀ds18b20溫度值并發送,綠燈閃亮。
發送后清TX_DS中斷標志并轉入接收模式 RX Mode;
/**************************************************/
void CheckButtons()
{
if(S2==0)
{
delay_ms(10);
if(S2==0)
{
Do_Temp();//讀溫度數據
tx_buf[0]=dis_buf[0]; // 存溫度數據到顯示緩存
tx_buf[1]=dis_buf[1];
tx_buf[2]=dis_buf[2];
tx_buf[3]=dis_buf[3];
TX_Mode(); // 發送模式
display(dis_buf); //在LED顯示溫度數據
// 清中斷標志(TX_DS)
SPI_RW_Reg(WRITE_REG+STATUS,SPI_Read(READ_REG+STATUS));
RX_Mode(); // 轉入接收模式
LEDG=0; //綠LED:亮
delay_ms(200);
LEDG=1; //綠LED:滅
}
}
}
/**************************************************/
/**************************************************
函數: main();
說明:
主函數;
/**************************************************/
void main(void)
{
init_nRF24L01();// 初始化nRF24L01
init_int0(); // int0 中斷使能
RX_Mode(); // 接收模式
while(1)
{
CheckButtons(); // 等待發送按鍵并發送
if(flag) // 是否收到
{
flag=0; //收到標志清零
LEDR=0; //紅LED:亮
delay_ms(200);
LEDR=1; //紅LED:滅
dis_buf[0]=rx_buf[0];//小數位
dis_buf[1]=rx_buf[1];//個位
dis_buf[2]=rx_buf[2];//十位
dis_buf[3]=rx_buf[3];//百位或負號
display(dis_buf);//在LED顯示收到的溫度值
}
}
}
/**************************************************/
/**************************************************
函數: ISR_int0() interrupt 0;
說明:中斷服務函數
若 RX_DR=1,由RX_FIFO 讀數據包并置位flag;
/**************************************************/
void ISR_int0(void) interrupt 0
{
sta=SPI_Read(STATUS); // 讀狀態 STATUS'值
if(RX_DR) // 如果有接收數據中斷(RX_DR)
{ // 由 RX_FIFO 緩存讀數據
SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);
flag=1;
}
if(MAX_RT) // 如果重發次數超過(MAX_RT)
{
SPI_RW_Reg(FLUSH_TX,0); //FLUSH_TX清零
}
// 清零RX_DR 或 TX_DS 或 MAX_RT 中斷標志
SPI_RW_Reg(WRITE_REG+STATUS,sta);
}
作者:
後輪追前輪
時間:
2017-7-1 20:41
樓主有頭文件程序嗎
歡迎光臨 (http://www.raoushi.com/bbs/)
Powered by Discuz! X3.1