单片机源程序如下:
- #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)
|