基于24L01+1302+1602的无线传输及显示的时钟日历的51单片机程序_第1页
基于24L01+1302+1602的无线传输及显示的时钟日历的51单片机程序_第2页
基于24L01+1302+1602的无线传输及显示的时钟日历的51单片机程序_第3页
基于24L01+1302+1602的无线传输及显示的时钟日历的51单片机程序_第4页
基于24L01+1302+1602的无线传输及显示的时钟日历的51单片机程序_第5页
已阅读5页,还剩15页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、/发射#include <reg52.h>/发射#include <intrins.h>typedef unsigned char uchar;typedef unsigned char uint;/*NRF24L01*/#define TX_ADR_WIDTH 5 / 5 uints TX address width#define RX_ADR_WIDTH 5 / 5 uints RX address width#define TX_PLOAD_WIDTH 14 / 20 uints TX payload#define RX_PLOAD_WIDTH 14 / 20 u

2、ints TX payload/*NRF24L01寄存器指令#define READ_REG 0x00 / 读寄存器指令#define WRITE_REG 0x20 / 写寄存器指令#define RD_RX_PLOAD 0x61 / 读取接收数据指令#define WR_TX_PLOAD 0xA0 / 写待发数据指令#define FLUSH_TX 0xE1 / 冲洗发送 FIFO指令#define FLUSH_RX 0xE2 / 冲洗接收 FIFO指令#define REUSE_TX_PL 0xE3 / 定义重复装载数据指令#define NOP 0xFF / 保留/*SPI(nRF24L

3、01)寄存器地址#define CONFIG 0x00 / 配置收发状态,CRC校验模式以及收发状态响应方式#define EN_AA 0x01 / 自动应答功能设置#define EN_RXADDR 0x02 / 可用信道设置#define SETUP_AW 0x03 / 收发地址宽度设置#define SETUP_RETR 0x04 / 自动重发功能设置#define RF_CH 0x05 / 工作频率设置#define RF_SETUP 0x06 / 发射速率、功耗功能设置#define STATUS 0x07 / 状态寄存器#define OBSERVE_TX 0x08 / 发送监测功

4、能#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接收数据长度#

5、define RX_PW_P1 0x12 / 接收频道0接收数据长度#define RX_PW_P2 0x13 / 接收频道0接收数据长度#define RX_PW_P3 0x14 / 接收频道0接收数据长度#define RX_PW_P4 0x15 / 接收频道0接收数据长度#define RX_PW_P5 0x16 / 接收频道0接收数据长度#define FIFO_STATUS 0x17 / FIFO栈入栈出状态寄存器设置/*NRF24L01端口定义*/sbitIRQ=P10;sbit MOSI=P11; sbitCSN=P12;sbit MISO=P13;sbitSCK =P14;sb

6、itCE =P15;/*定义1302管脚*/sbit IO = P05; /6sbit SCLK = P06;/7sbit RST = P04; /5/*定义1602管脚*/sbit RS = P33;/4sbit RW = P34;/5sbit EN = P35;/6/*定义调时键盘管脚*/sbit key1=P00;/选择sbit key2=P01;/加sbit key3=P02;/减 sbit key4=P03;/确定/*定义闹铃管脚*/sbit led = P07;/led代替闹铃/*状态标志*/uint bdata sta; sbitRX_DR=sta6;sbitTX_DS=sta5

7、;sbitMAX_RT=sta4;uint const TX_ADDRESSTX_ADR_WIDTH= 0x34,0x43,0x10,0x10,0x01;/本地地址uint const RX_ADDRESSRX_ADR_WIDTH= 0x34,0x43,0x10,0x10,0x01;/接收地址unsigned char x1=0;int hour=8,minute=0;/闹钟的初始时间8:00unsigned char DateTime9; /秒,分,时,日,周,月,年/*发送缓冲区uchar TxBuf14=0;unsigned char lcd1="DATE 00-00-00 &

8、quot;unsigned char lcd2="TIME 00:00:00 " /*/void inerDelay_us(unsigned char n);void init_NRF24L01(void);uint SPI_RW(uint uchar);uchar SPI_Read(uchar reg);void SetRX_Mode(void);uint SPI_RW_Reg(uchar reg, uchar value);uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars);uint SPI_Write_Buf

9、(uchar reg, uchar *pBuf, uchar uchars);unsigned char nRF24L01_RxPacket(unsigned char* rx_buf);void nRF24L01_TxPacket(unsigned char * tx_buf);/*长延时void delayms(unsigned int x)/延时毫秒程序 unsigned j; unsigned int i; for(i=x;i>0;i-) for(j=110;j>0;j-); void inerDelay_us(unsigned char n)for(;n>0;n-)

10、_nop_();/*/*/*/*/void init_NRF24L01(void) inerDelay_us(100); CE=0; / chip enable CSN=1; / Spi disable SCK=0; / Spi clock line init highSPI_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 +

11、EN_AA, 0x01); / 频道0自动ACK应答允许SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); / 允许接收地址只有频道0,如果需要多频道可以参考Page21 SPI_RW_Reg(WRITE_REG + RF_CH, 0); / 设置信道工作为2.4GHZ,收发必须一致SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); /设置接收数据长度,本次设置为32字节SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); /设置发射速率为1MHZ,发射功率为最大值0dBSPI_RW_Reg

12、(WRITE_REG + CONFIG, 0x0e); / IRQ收发完成中断响应,16位CRC,主发送/*/*函数:uint SPI_RW(uint uchar)/*功能:NRF24L01的SPI写时序/*/uint SPI_RW(uint uchar)uint bit_ctr; for(bit_ctr=0;bit_ctr<8;bit_ctr+) / output 8-bit MOSI = (uchar & 0x80); / output 'uchar', MSB to MOSIuchar = (uchar << 1); / shift next b

13、it into MSB.SCK = 1; / Set SCK high.uchar |= MISO; / capture current MISO bitSCK = 0; / .then set SCK low again return(uchar); / return read uchar/*NRF24L01的SPI时序*uchar SPI_Read(uchar reg)uchar reg_val;CSN = 0; / CSN low, initialize SPI communication.SPI_RW(reg); / Select register to read from.reg_v

14、al = SPI_RW(0); / .then read registervalueCSN = 1; / CSN high, terminate SPI communicationreturn(reg_val); / return register value*/*/*功能:NRF24L01读写寄存器函数/*/uint SPI_RW_Reg(uchar reg, uchar value)uint status;CSN = 0; / CSN low, init SPI transactionstatus = SPI_RW(reg); / select registerSPI_RW(value);

15、 / .and write value to it.CSN = 1; / CSN high againreturn(status); / return nRF24L01 status uchar/* 用于读数据,reg:为寄存器地址,pBuf:为待读出数据地址,uchars:读出数据的个数*uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)uint status,uchar_ctr;CSN = 0; / Set CSN low, init SPI tranactionstatus = SPI_RW(reg); / Select reg

16、ister to write to and read status ucharfor(uchar_ctr=0;uchar_ctr<uchars;uchar_ctr+)pBufuchar_ctr = SPI_RW(0); / CSN = 1; return(status); / return nRF24L01 status uchar */*/*函数:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)/*功能: 用于写数据:为寄存器地址,pBuf:为待写入数据地址,uchars:写入数据的个数/*/uint SPI_Write_

17、Buf(uchar reg, uchar *pBuf, uchar uchars)uint status,uchar_ctr;CSN = 0; /SPI使能 status = SPI_RW(reg); for(uchar_ctr=0; uchar_ctr<uchars; uchar_ctr+) /SPI_RW(*pBuf+);CSN = 1; /关闭SPIreturn(status); / /*数据接收配置 *void SetRX_Mode(void)CE=0;SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f); / IRQ收发完成中断响应,16位CRC,主接收CE

18、 = 1; inerDelay_us(130); /延时不能太短 */*unsigned char nRF24L01_RxPacket(unsigned char* rx_buf) unsigned char revale=0;sta=SPI_Read(STATUS);/ 读取状态寄存其来判断数据接收状况if(RX_DR)/ 判断是否接收到数据 CE = 0; /SPI使能SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);/ read receive payload from RX_FIFO bufferrevale =1;/读取数据完成标志SPI

19、_RW_Reg(WRITE_REG+STATUS,sta); /接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标志return revale; */*/void nRF24L01_TxPacket(unsigned char * tx_buf)CE=0;/StandBy 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(WR

20、ITE_REG + CONFIG, 0x0e); / IRQ收发完成中断响应,16位CRC,主发送CE=1; /置高CE,激发数据发送inerDelay_us(10);/*/*/*/*1302的驱动程序*/写入数据,dat:要写入的数据void DS1302WriteByte(unsigned char dat) unsigned char i; SCLK=0;/初始时钟线置为0 inerDelay_us(2); for(i=0;i<8;i+)/开始传输8个字节的数据 IO=dat&0x01;/取最低位,注意 DS1302的数据和地址都是从最低位开始传输的 inerDelay_u

21、s(2); SCLK=1;/时钟线拉高,制造上升沿,SDA的数据被传输 inerDelay_us(2); SCLK=0;/时钟线拉低,为下一个上升沿做准备 dat>>=1;/数据右移一位,准备传输下一位数据 /*1302的驱动程序*/功能: 读取数据,dat:读取的数据unsigned char DS1302ReadByte() unsigned char i; unsigned char dat; inerDelay_us(2); for(i=0;i<8;i+) dat>>=1;/要返回的数据左移一位 if(IO=1)/当数据线为高时,证明该位数据为 1 dat

22、|=0x80;/要传输数据的当前值置为 1,若不是,则为 0 SCLK=1;/拉高时钟线 inerDelay_us(2); SCLK=0;/制造下降沿 inerDelay_us(2); return dat;/返回读取出的数据/16*10+dat%16 /*1302的驱动程序*/从cmd相应地址中读取一个字节的数据unsigned char DS1302Read(unsigned char cmd)/cmd:要写入的控制字节,dat:读取的数据 unsigned char dat; RST=0;/初始 CE线置为0 SCLK=0;/初始时钟线置为0 RST=1;/初始 CE置为 1,传输开始

23、DS1302WriteByte(cmd);/传输命令字,要读取的时间/日历地址 dat=DS1302ReadByte();/读取要得到的时间/日期 SCLK=1;/时钟线拉高 RST=0;/读取结束,CE置为 0,结束数据的传输 return dat;/返回得到的时间/日期 /*1302的驱动程序*/向cmd相应地址中写一个字节的数据void DS1302Write(unsigned char cmd, unsigned int dat)/cmd:要写入的控制字,dat:要写入的数据 RST=0; /初始 CE线置为 0 SCLK=0; /初始时钟线置为0 RST=1; /初始 CE置为 1,

24、传输开始 DS1302WriteByte(cmd); /传输命令字,要写入的时间/日历地址 DS1302WriteByte(dat); /写入要修改的时间/日期 SCLK=1; /时钟线拉高 RST=0; /读取结束,CE置为0,结束数据的传输 /*初始化ds1302*/给1302写入日期和时钟的值void chushihuaDS1302(void) DS1302Write(0x8e,0x00);/写保护关 DS1302Write(0x80,0x10); /初始秒 DS1302Write(0x82,0x44);/初始分钟 DS1302Write(0x84,0x21); /初始为24小时模式,初

25、始时 DS1302Write(0x86,0x22); /1日 DS1302Write(0x88,0x08);/8月 DS1302Write(0x8c,0x13);/2013年 DS1302Write(0x8a,0x04);/星期4 / DS1302Write(0x90,0x01); /充电 /DS1302Write(0xc0,0xf0); /初始化一次标示 /DS1302Write(0x8e,0x80);/写保护开 /*以下是1602的程序*/*/向1602内写命令void write_order(unsigned char order) RS=0; P2=order; delayms(5);

26、 EN=1; delayms(5); EN=0; /*/向1602内写数据void write_date(unsigned char date) RS=1; P2=date; delayms(5); EN=1; delayms(5); EN=0; /*/lcd1602的初始化void chushihuaLCD1602() EN=0; write_order(0x38); write_order(0x0c); write_order(0x06); write_order(0x01); /*其他操作*/void gettime() unsigned char i,n; for(i=0,n=1;i&

27、lt;7,n<15;i+,n=n+2) DateTimei=DS1302Read(0x80+n); inerDelay_us(1); void zhuanhuan() gettime(); lcd15=(DateTime6>>4)+0x30);lcd16=(DateTime6&0x0f)+0x30);inerDelay_us(2);/年lcd114=(DateTime5>>4)+0x30);lcd115=(DateTime5&0x0f)+0x30);inerDelay_us(2);/周lcd111=(DateTime3>>4)+0x30

28、);lcd112=(DateTime3&0x0f)+0x30);inerDelay_us(2);/日lcd18=(DateTime4>>4)+0x30);lcd19=(DateTime4&0x0f)+0x30);inerDelay_us(2);/月lcd25=(DateTime2>>4)+0x30);lcd26=(DateTime2&0x0f)+0x30);inerDelay_us(2);/时lcd28=(DateTime1>>4)+0x30);lcd29=(DateTime1&0x0f)+0x30);inerDelay_us

29、(2);/分 lcd211=(DateTime0>>4)+0x30);lcd212=(DateTime0&0x0f)+0x30);inerDelay_us(2);/秒TxBuf12=lcd211;TxBuf13=lcd212;/秒的个位和十位TxBuf0=lcd29;TxBuf1=lcd28;/分的个位和十位TxBuf2=lcd26;TxBuf3=lcd25;/时的个位和十位TxBuf4=lcd112;TxBuf5=lcd111;/天的个位和十位TxBuf6=lcd115;TxBuf7=lcd114;/周的个位和十位TxBuf8=lcd19;TxBuf9=lcd18;/月的

30、个位和十位TxBuf10=lcd16;TxBuf11=lcd15;/年的个位和十位/*/if(DateTime7=DateTime2 & DateTime8=DateTime1)/闹钟 led = 1; delayms(150); led = 0; /*键盘调时+闹钟调时*/void jianpan() unsigned char x2,address,max,min; int item; if(key1=0) delayms(10); if(key1=0) x1+; if(x1>=9) x1=1;switch(x1) case 1: lcd213=' 'lcd2

31、14=' 'lcd215='Y'x2=1;address=0x8c; max=99;min=0;break;/年 case 2: lcd213=' 'lcd214=' 'lcd215='M'x2=2;address=0x88; max=12;min=1;break;/月 case 3: lcd213=' 'lcd214=' 'lcd215='D'x2=3;address=0x86; max=31;min=1;break;/天 case 4: lcd213='

32、'lcd214=' 'lcd215='H'x2=4;address=0x84; max=23;min=0;break;/时 case 5: lcd213=' 'lcd214=' 'lcd215='F'x2=5;address=0x82; max=59;min=0;break;/分 case 6: lcd213=' 'lcd214=' 'lcd215='W'x2=6;address=0x8A; max=7;min=1;break;/周 /*/ case 7: l

33、cd213='M' x2=7;max=59;min=0; lcd214=(minute>>4)+0x30); lcd215=(minute&0x0f)+0x30); inerDelay_us(2);break;/分 case 8: lcd213='H' x2=8;max=23;min=0; lcd214=(hour>>4)+0x30); lcd215=(hour&0x0f)+0x30); inerDelay_us(2);break;/时 while(!key1); item=(DS1302Read(address+1)/1

34、6)*10 + (DS1302Read(address+1)%16;if(key2=0) delayms(10); if(key2=0) if(x2=1) item+; else if(x2=2) item+; else if(x2=3) item+; else if(x2=4) item+; else if(x2=5) item+; else if(x2=6) item+; /*/ else if(x2=7)/分 minute=(minute/16)*10)+(minute%16); minute+; if(minute>max) minute=min; minute=(minute/

35、10)*16+minute%10; lcd214=(minute>>4)+0x30); lcd215=(minute&0x0f)+0x30); inerDelay_us(2); else if(x2=8)/时 hour=(hour/16)*10)+(hour%16); hour+; if(hour>max) hour=min; hour=(hour/10)*16+hour%10; lcd214=(hour>>4)+0x30); lcd215=(hour&0x0f)+0x30); inerDelay_us(2); while(!key2);if(ke

36、y3=0) delayms(10); if(key3=0) if(x2=1) item-; else if(x2=2) item-; else if(x2=3) item-; else if(x2=4) item-; else if(x2=5) item-; else if(x2=6) item-; /*/ else if(x2=7)/分 minute=(minute/16)*10)+(minute%16); minute-; if(minute<min) minute=max; minute=(minute/10)*16+minute%10; lcd214=(minute>>

37、;4)+0x30); lcd215=(minute&0x0f)+0x30); inerDelay_us(2); else if(x2=8)/时 hour=(hour/16)*10)+(hour%16); hour-; if(hour<min) hour=max; hour=(hour/10)*16+hour%10; lcd214=(hour>>4)+0x30); lcd215=(hour&0x0f)+0x30); inerDelay_us(2); while(!key3); if(key4=0) delayms(10); if(key4=0) lcd213=&

38、#39; 'lcd214=' 'lcd215=' ' x1=0; x2=0; while(!key4); DateTime7=hour;DateTime8=minute; if(item>max) item=min; if(item<min) item=max; DS1302Write(0x8e,0x00);/允许写操作 delayms(10); DS1302Write(address,(item/10)*16+item%10); /写入DS1302 /转成BCD码 delayms(20); DS1302Write(0x8e,0x80);/写

39、保护,禁止写操作 void wzd0() interrupt 0/外部中断0 jianpan();/ /*主函数 /发射void main(void)unsigned char k;EA=1;EX0=1;IT0=1; RW=0;led=0; init_NRF24L01() ;/nRF24L01_TxPacket(TxBuf);/ Transmit Tx buffer datachushihuaLCD1602();/1602初始化 if( (DS1302Read(0x81) & 0x80) ) chushihuaDS1302();/1302初始化delayms(85);while(1)

40、zhuanhuan(); write_order(0x80);/lcd的第一行 for(k=0;k<16;k+) write_date(lcd1k); inerDelay_us(2); write_order(0x80+0x40);/lcd的第二行 for(k=0;k<16;k+) write_date(lcd2k); inerDelay_us(2); /*/nRF24L01_TxPacket(TxBuf);/ Transmit Tx buffer datadelayms(30); /可变SPI_RW_Reg(WRITE_REG+STATUS,0XFF); delayms(12);

41、 /接收#include <reg52.h> /接收#include <intrins.h>typedef unsigned char uchar;typedef unsigned char uint;/*/#define TX_ADR_WIDTH 5 / 5 uints TX address width#define RX_ADR_WIDTH 5 / 5 uints RX address width#define TX_PLOAD_WIDTH 14 / 20 uints TX payload#define RX_PLOAD_WIDTH 14 / 20 uints TX

42、 payload/*NRF24L01寄存器指令#define READ_REG 0x00 / 读寄存器指令#define WRITE_REG 0x20 / 写寄存器指令#define RD_RX_PLOAD 0x61 / 读取接收数据指令#define WR_TX_PLOAD 0xA0 / 写待发数据指令#define FLUSH_TX 0xE1 / 冲洗发送 FIFO指令#define FLUSH_RX 0xE2 / 冲洗接收 FIFO指令#define REUSE_TX_PL 0xE3 / 定义重复装载数据指令#define NOP 0xFF / 保留/*SPI(nRF24L01)寄存器地址#define CONFIG 0x00 / 配置收发状态,CRC校验模式以及收发状态响应方式#define EN_AA 0x01 / 自动应答功能设置#define EN_RXADDR 0x02 / 可用信道设置#define SETUP_AW 0x03 / 收发地址宽度设置#define SETUP_RETR 0x04 / 自动重发功能设置#define RF_CH 0x05 / 工作频率设置#define RF_SETUP 0x06 / 发射速率、功耗功

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论