單片機源程序如下:
- #include <reg51.h>
- #include <intrins.h>
- #include "nrf24l01.h"
- #include "12864.h"
- /***************************************************
- *This file is distributed in the hope that it will be useful, but WITHOUT ANY WARRANT;
- *
- *UART:9600BPS
- /***************************************************/
- #define uchar unsigned char
- #define uint unsigned int
- #define TX_ADR_WIDTH 5 // 5 bytes TX(RX) address width
- #define TX_PLOAD_WIDTH 20 // 20 bytes TX payload 發送的字節數
- uchar quanshu=0; //用來記錄圈數
- uchar xian=0; //用來記錄經過了幾條線
- uchar const TX_ADDRESS[TX_ADR_WIDTH] = {0x34,0x43,0x10,0x10,0x86}; // Define a static TX address 靜態地址
- uchar code dis1[] = {0xc8,0xa6,0xca,0xfd}; //圈數
- uchar code dis2[] = {"濕度 初始化中"};
- //uchar code dis3[] = {"無障礙物"};
- uchar code dis4[10]={0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9};
- uchar code dis5[] = {"黑線"};
- uchar code dis6[]={"溫度 初始化中"};
- uchar code digit[10]={"0123456789"};
- uchar code dis7[]={"傳感器異常"};
- uchar rx_buf[TX_PLOAD_WIDTH];
- uchar tx_buf[TX_PLOAD_WIDTH];
- uchar flag;
- /**************************************************/
- sbit CE = P1^0;
- sbit CSN= P1^4;
- sbit SCK= P1^7;
- sbit MOSI= P1^5;
- sbit MISO= P1^6;
- sbit IRQ = P3^2;
- /**************************************************/
- uchar bdata sta;
- sbit RX_DR =sta^6;
- sbit TX_DS =sta^5;
- sbit MAX_RT =sta^4;
- /**************************************************/
- sbit LED1=P2^5;
- sbit LED2=P2^6;
- /**************************************************
- Function: Init_IO();
- Description:
- flash led one time,chip enable(ready to TX or RX Mode),
- Spi disable,Spi clock line init high
- 描述:
- 閃光燈一次,芯片使能(準備進入TX或RX模式)
- Spi禁用,Spi時鐘線初始化高
- /**************************************************/
- #define KEY 0x60 // 0x60 0110 0000
- void dislap(uchar q);
- void Init_IO(void)
- {
- P0=KEY; // led light
- CE=0; // chip enable
- CSN=1; // Spi disable
- SCK=0; // Spi clock line init high
- P0=0xff; // led close
- }
- /**************************************************
- Function: Init_uart();
- Description:
- set uart working mode
- 描述:
- 設置定時計數器工作模式
- /**************************************************/
- void Init_uart(void)
- {
- TMOD = 0x20; //timer1 working mode 1
- TL1 = 0xfd; //f7=9600 for 16mhz Fosc,and ...
- TH1 = 0xfd; //...fd=19200 for 11.0592mhz Fosc
- SCON = 0xd8; //uart mode 3,ren==1
- PCON = 0x80; //smod=0
- TR1 = 1; //start timer1
- }
- /**************************************************
- Function: Init_int0();
- Description:
- enable int0 interrupt;
- 中斷0使能
- /**************************************************
- void Init_int0(void)
- {
- EA=1;
- EX0=1; // Enable int0 interrupt.
- }
- /**************************************************/
- /**************************************************
- Function: delay100();
- Description:
- delay 100ms
- 延時100毫秒
- /**************************************************
- void delay100(void)
- {
- uchar x;
- uchar y;
- for(x=0;x<100;x++)
- {
- for(y=0;y<100;y++)
- _nop_();
- }
- }
- /**************************************************/
- /**************************************************
- Function: delay_ms();
- Description:
- delay x ms
- 延時X毫秒
- /**************************************************/
- void delay_ms(unsigned int x)
- {
- unsigned int i,j;
- i=0;
- for(i=0;i<x;i++)
- {
- j=108;
- ;
- while(j--);
- }
- }
- /**************************************************
- Function: SPI_RW();
- Description:
- Writes one byte to nRF24L01, and return the byte read
- from nRF24L01 during write, according to SPI protocol
- 根據SPI協議寫一個字節到nRF24L01,
- 并在寫期間返回從nRF24L01讀取的字節
- /**************************************************/
- uchar SPI_RW(uchar byte)
- {
- uchar bit_ctr;
- for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit 輸出8位
- {
- MOSI = (byte & 0x80); // output 'byte', MSB to MOSI 最高位寫入主輸出從輸入
- byte = (byte << 1); // shift next bit into MSB.. 將下一位移到最高位
- SCK = 1; // Set SCK high.. 同步時鐘置高位
- byte |= MISO; // capture current MISO bit 捕獲主輸入從輸出位
- SCK = 0; // ..then set SCK low again 同步時鐘置0
- }
- return(byte); // return read byte
- }
- /**************************************************
- Function: SPI_RW_Reg();
- Description:
- Writes value 'value' to register 'reg'
- /**************************************************/
- uchar SPI_RW_Reg(uchar reg, uchar value)
- {
- uchar status;
- CSN = 0; // CSN low, init SPI transaction SPI片選
- status = SPI_RW(reg); // select register
- SPI_RW(value); // ..and write value to it..
- CSN = 1; // CSN high again
- return(status); // return nRF24L01 status byte
- }
- /**************************************************
- Function: SPI_Read();
- Description:
- Read one byte from nRF24L01 register, 'reg'
- /**************************************************/
- uchar SPI_Read(uchar reg)
- {
- uchar reg_val;
- CSN = 0; // CSN low, initialize SPI communication...
- SPI_RW(reg); // Select register to read from..
- reg_val = SPI_RW(0); // ..then read registervalue
- CSN = 1; // CSN high, terminate SPI communication
- return(reg_val); // return register value
- }
- /**************************************************
- Function: SPI_Read_Buf();
- Description:
- Reads 'bytes' #of bytes from register 'reg'
- Typically used to read RX payload, Rx/Tx address
- /**************************************************/
- uchar SPI_Read_Buf(uchar reg, uchar *pBuf, uchar bytes)
- {
- uchar status,byte_ctr;
- CSN = 0; // Set CSN low, init SPI tranaction SPI片選
- status = SPI_RW(reg); // Select register to write to and read status byte
- for(byte_ctr=0;byte_ctr<bytes;byte_ctr++)
- pBuf[byte_ctr] = SPI_RW(0); // Perform SPI_RW to read byte from nRF24L01 從nRF24L01讀取字節
- CSN = 1; // Set CSN high again
- return(status); // return nRF24L01 status byte
- }
- /**************************************************
- Function: SPI_Write_Buf();
- Description:
- Writes contents of buffer '*pBuf' to nRF24L01 將緩沖區'* pBuf'的內容寫入nRF24L01
- Typically used to write TX payload, Rx/Tx address
- /**************************************************/
- uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar bytes)
- {
- uchar status,byte_ctr;
- CSN = 0; // Set CSN low, init SPI tranaction SPI片選
- status = SPI_RW(reg); // Select register to write to and read status byte
-
- for(byte_ctr=0; byte_ctr<bytes; byte_ctr++) // then write all byte in buffer(*pBuf) 將所有字節寫入緩沖區
- SPI_RW(*pBuf++);
-
- CSN = 1; // Set CSN high again
-
- return(status); // return nRF24L01 status byte
- }
- /**************************************************
- Function: RX_Mode();
- Description:
- This function initializes one nRF24L01 device to
- RX Mode, set RX address, writes RX payload width,
- select RF channel, datarate & LNA HCURR.
- After init, CE is toggled high, which means that
- this device is now ready to receive a datapacket.
- 該函數將一個nRF24L01器件初始化為RX模式,設置RX地址,
- 寫入RX有效負載寬度,選擇RF通道,數據速率和LNA HCURR。
- 在init之后,CE被切換為高電平,這意味著該設備現在準備好
- 接收數據包
- /**************************************************/
- void RX_Mode(void)
- {
- CE=0;
- SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // Use the same address on the RX device as the TX device 在RX設備上使用與TX設備相同的地址
- SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // Enable Auto.Ack:Pipe0
- SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // Enable Pipe0
- SPI_RW_Reg(WRITE_REG + RF_CH, 40); // Select RF channel 40
- SPI_RW_Reg(WRITE_REG + RX_PW_P0, TX_PLOAD_WIDTH); // Select same RX payload width as TX Payload width 數據寬度相同
- SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); // TX_PWR:0dBm, Datarate:2Mbps, LNA:HCURR 發射功率,數據率
- SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f); // Set PWR_UP bit, enable CRC(2 bytes) & Prim:RX. RX_DR enabled..
- CE = 1; // Set CE pin high to enable RX device 使能接受
- // This device is now ready to receive one packet of 16 bytes payload from a TX device sending to address
- // '3443101001', with auto acknowledgment, retransmit count of 10, RF channel 40 and datarate = 2Mbps.
- //此設備現在準備好從發送到地址'3443101001'的TX設備接收一個16字節有效載荷的包,其具有自動確認,重傳計數為10,RF信道40和數據速率= 2Mbps。
- }
- /**************************************************
- Function: TX_Mode();
- Description:
- This function initializes one nRF24L01 device to
- TX mode, set TX address, set RX address for auto.ack,
- fill TX payload, select RF channel, datarate & TX pwr.
- PWR_UP is set, CRC(2 bytes) is enabled, & PRIM:TX.
- ToDo: One high pulse(>10us) on CE will now send this
- packet and expext an acknowledgment from the RX device.
- 該函數將一個nRF24L01器件初始化為TX模式,設置TX地址,
- 為auto.ack設置RX地址,填充TX有效負載,選擇RF通道,
- 數據和TX pwr。 PWR_UP置1,CRC(2字節)使能,&PRIM:TX。
- ToDo:CE上的一個高脈沖(> 10us)現在將發送此數據包,并從RX設備展開確認。
- /**************************************************/
- void TX_Mode(void)
- {
- CE=0;
-
- SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // Writes TX_Address to nRF24L01 將發送地址寫入nRF24L01
- SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // RX_Addr0 same as TX_Adr for Auto.Ack
- SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH); // Writes data to TX payload 將數據寫到發送區
- SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // Enable Auto.Ack:Pipe0
- SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // Enable Pipe0
- SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x1a); // 500us + 86us, 10 retrans...
- SPI_RW_Reg(WRITE_REG + RF_CH, 40); // Select RF channel 40
- SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); // TX_PWR:0dBm, Datarate:2Mbps, LNA:HCURR
- SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // Set PWR_UP bit, enable CRC(2 bytes) & Prim:TX. MAX_RT & TX_DS enabled..
- CE=1;
- xian=0;
- }
- /**************************************************
- Function: check_ACK();
- Description:
- check if have "Data sent TX FIFO interrupt",if TX_DS=1,
- all led light and after delay 100ms all led close
- 檢查是否有“數據發送TX FIFO中斷”,如果TX_DS = 1,
- 所有LED指示燈和延時100ms后全部LED關閉
- /**************************************************
- void check_ACK()
- {
- uchar test;
- test=SPI_Read(READ_REG+STATUS); // read register STATUS's
- test=test&0x20; // check if have Data sent TX FIFO interrupt (TX_DS=1)
- if(test==0x20) // TX_DS =1
- {
- P0=0x00; // turn on all led
- delay100(); // delay 100ms
- P0=0xff;
- }
- }
- /**************************************************/
- /**************************************************
- Function: TxData();
- Description:
- write data x to SBUF
- /**************************************************
- void TxData (uchar x)
- {
- SBUF=x; // write data x to SBUF
- while(TI==0);
- TI=0;
- }
- /**************************************************/
- /**************************************************
- Function: CheckButtons();
- Description:
- check buttons ,if have press,read the key values,
- turn on led and transmit it; after transmition,
- if received ACK, clear TX_DS interrupt and enter RX Mode;
- turn off the led
- 檢查按鈕,如果有按下,讀取鍵值,打開led并發送;
- 發送后,如果收到ACK,清除TX_DS中斷并進入RX模式;關閉led
- /**************************************************/
- void CheckButtons()
- {
- uchar Temp,Tempi;
- Temp=P3&KEY; //讀鍵值
- if (Temp!=KEY)
- {
- delay_ms(10);
- Temp=P3&KEY; // 讀鍵值
- if (Temp!=KEY)
- {
- switch(Temp)
- {
- case 0x20:Tempi=0x01;
- break;
- case 0x40:Tempi=0x02;dislap(++quanshu);
- break;
- default:Tempi=0xff;
- }
- tx_buf[0]=Tempi;
- TX_Mode(); // 置發射模式并開始發射數據
- delay_ms(10);
- SPI_RW_Reg(WRITE_REG+STATUS,SPI_Read(READ_REG+STATUS)); // 清除(TX_DS)中斷標志
- delay_ms(500);
- RX_Mode(); // 置位接收模式
- while((P3&KEY)!=KEY);
- }
- }
- }
- /**************************************************
- Function: main();
- Description:
- control all subprogrammes;
- /**************************************************/
- void displayInist()
- {
- uchar i;
- lcd_pos(0,0); //設置顯示位置為第一行的第1個字符
- i = 0;
- while(i<5)
- { //顯示圈數
- lcd_wdat(dis1[i]);
- i++;
- }
- lcd_pos(1,0); //設置顯示位置為第二行的第1個字符
- i = 0;
- while(dis5[i] != '\0')
- {
- lcd_wdat(dis5[i]); //顯示經過了幾條線
- i++;
- }
- lcd_wdat('0');
- lcd_pos(2,0); //設置顯示位置為第三行的第1個字符
- i = 0;
- while(dis2[i] != '\0')
- {
- lcd_wdat(dis2[i]); //顯示濕度初始化
- i++;
- }
- lcd_pos(3,0); //設置顯示位置為第四行的第1個字符
- i = 0;
- while(dis6[i] != '\0')
- {
- lcd_wdat(dis6[i]); //顯示溫度初始化
- i++;
- }
- }
- //顯示圈數的數字
- void dislap(uchar q)
- {
- uchar tq;
- if(q<10)
- {
- lcd_pos(0,2);
- lcd_wdat(0xa3);
- lcd_wdat(dis4[q]);
- }
- else
- {
- tq=q/10;
- lcd_pos(0,2);
- lcd_wdat(0xa3);
- lcd_wdat(dis4[tq]);
- tq=q%10;
- lcd_pos(0,3);
- lcd_wdat(0xa3);
- lcd_wdat(dis4[tq]);
- }
- }
- //判斷接收的數據給出反應
- void display(uchar xx,uchar yy)
- {
- uchar i,T,H;
- uchar t=0;
- if(xx==0xff)
- return;
- if(xx==0x01)
- {
- lcd_pos(1,2);
- lcd_wdat(0xa3);
- lcd_wdat(dis4[++xian]);
- }
- if(xx==0x02)
- {
- lcd_pos(2,0); //設置顯示位置為第三行的第1個字符
- i = 0;
- while(dis2[i] != '\0')
- {
- lcd_wdat(dis2[i]); //顯示有擋板
- i++;
- }
- }
- if(xx==0x03)
- {
- lcd_pos(3,2);
- for(i=0;i<12;i++)
- {
- lcd_wdat(' '); //清除“初始化中”
- }
- lcd_pos(3,3); //設置顯示位置為第三行的第1個字符
- i = 0;
- while(dis7[i] != '\0')
- {
- lcd_wdat(dis7[i]); //顯示傳感器異常
- i++;
- }
- }
- if(xx!=0x01&&xx!=0x02&&xx!=0x03) //顯示溫度情況
- {
- T=xx%100;
- H=yy%100;
- lcd_pos(2,2);
- for(i=0;i<12;i++)
- {
- lcd_wdat(' '); //清除內容以便顯示濕度
- }
- lcd_pos(3,2);
- for(i=0;i<12;i++)
- {
- lcd_wdat(' '); //清除內容以便顯示溫度
- }
- lcd_pos(2,2);
- lcd_wdat(digit[H/10]);
- lcd_wdat(digit[H%10]);
- lcd_wdat(0xa3);
- lcd_wdat(0xa5);
- lcd_pos(3,2);
- lcd_wdat(digit[T/10]);
- lcd_wdat(digit[T%10]);
- lcd_wdat(0xa1);
- lcd_wdat(0xe6);
- }
- }
- void main(void)
- {
- uchar xx,yy;
- Init_IO(); // Initialize IO port 初始化IO端口
- Init_uart(); // Initialize 232 uart
- //Init_int0(); // enable int0 interrupt
- RX_Mode(); // set RX mode
- delay_ms(20); //延時
- lcd_init(); //初始化LCD
- displayInist(); //初始化顯示界面。
- while(1)
- {
- CheckButtons(); // scan key value and transmit 掃描鍵值和發送
- sta=SPI_Read(STATUS); // read register STATUS's value 讀寄存器STATUS的值
- //---------------------------------- 余下見附件-----------------------//
復制代碼
所有資料51hei提供下載:
遙控器接收溫濕度.rar
(53.99 KB, 下載次數: 6)
2018-4-23 13:57 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|