基于单片机的无线温度计设计报告Word下载.docx
- 文档编号:21880183
- 上传时间:2023-02-01
- 格式:DOCX
- 页数:30
- 大小:191.17KB
基于单片机的无线温度计设计报告Word下载.docx
《基于单片机的无线温度计设计报告Word下载.docx》由会员分享,可在线阅读,更多相关《基于单片机的无线温度计设计报告Word下载.docx(30页珍藏版)》请在冰豆网上搜索。
晶振电路复位电路
显示电路:
显示电路采用LCD1602,滑动电阻R6用来调节背光亮度。
显示电路
报警电路
当单片机通电后,进入温度报警上下限调节,此时显示软件设置的温度报警上线,按s2对报警温度进行加一,按s3对报警温度进行减一。
当实际温度超过所设温度上下限时,单片机P3.0口会输出高电平,红色led灯会亮起。
温度传感器:
DS18B20温度传感器是美国DALLAS半导体公司最新推出的一种改进型智能温度传感器,与传统的热敏电阻等测温元件相比,它能直接读出被测温度,并且可根据实际要求通过简单的编程实现9~12位的数字值读数方式。
DS18B20的性能特点如下:
1、独特的单线接口仅需要一个端口引脚进行通信;
2、多个DS18B20可以并联在惟一的三线上,实现多点组网功能
3、无须外部器件;
4、可通过数据线供电,电压范围为3.0~5.5V;
5、零待机功耗;
6、温度以9或12位数字;
7、用户可定义报警设置;
8、报警搜索命令识别并标志超过程序限定温度(温度报警条件)的器件;
9、负电压特性,电源极性接反时,温度计不会因发热而烧毁,但不能正常工作;
DS18B20采用寄生电源供电方式,此时DS18B20的1脚接地,2脚作为信号线,3脚接电源。
由于单线制只有一根线,因此发送接口必须是三态的。
温度传感器
无线收发模块nrf24l01
输出功率频道选择和协议的设置可以通过SPI接口进行设置,单片机可通过IRQ引脚快判断是否完成数据接收和数据发送。
四、总原理图及元器件清单
发送端:
接收端:
2.元件清单
序号
元器件名称
型号
主要参数
数量
备注
1
无线收发模块
NRF24L01
2
智能温度传感器
DS18B20
3
单片机
STC89C52
4
显示器
LCD1602
5
电容
22nf
6
排阻
10K
7
晶振
12MHZ
8
稳压器
az1117t-3.3
9
按键开关
10
LED
11
蜂鸣器
12
电阻
五、安装与调试
1.调试过程描述
一开始接收端单片机通电后显示屏背光亮,内容无显示,经检测电路后发现信号控制线断裂。
修复后显示屏能显示学号、字母信息,但是无法显示温度数字。
初步判断是程序出问题,导致无线模块没有正确接收信号。
之后更改程序,编程控制端口收发信号,最终调试成功。
2.实物照片
六、性能测试与分析
在本次设计中,利用单片机实现了温度测量,测量精度为0.1℃,在发送端温度传感器的数据能实时发送到接收端,无线传输距离达到10m以上,符合设计要求。
七、结论与心得
从确定题目,研究原理图,制作电路板,到焊接调试,当中出现不少问题,但是我迎难而上,把问题逐个解决,最终完成课程设计,我从中积累了很多解决问题的宝贵经验。
其中最大的问题是无线接收模块在接收温度信息时延迟比较大,后来通过查阅资料修改信道,问题得以解决。
另一个问题是当温度计一通上电后,LED灯就会一直亮。
在确定电路连接和原理图正确后依然不能解决,于是我跟同学讨论,发现是程序出错,使得单片机与LED相连的I/O口一直输出高电平,修改程序后温度计才正常工作!
在排查问题过程中我的耐心得到了锻炼,并且与同学们的讨论更是让我受益匪浅!
通过这次课程设计我进一步熟悉了单片机的内部结构和工作原理,了解到无线收发模块的使用方法,掌握了单片机应用系统设计的基本方法和步骤,让自己的理论水平和实践能力上升到一个新的台阶,同时我也认识到实践的重要性。
程序(程序本身没问题,只是排版乱了,大家下载回来注意修改一下双斜杠,双斜杠后面的内容会变成注释,不需要删减内容,只需要修正好回车键,都是行数的问题)
#include<
reg51.h>
intrins.h>
//#include"
api.h"
#defineucharunsignedchar
#defineTX_ADR_WIDTH5//发射地址的字节个数
#defineTX_PLOAD_WIDTH2//发射字节
ucharconstTX_ADDRESS[TX_ADR_WIDTH]={0x34,0x55,0x10,0x10,0x01};
ucharrx_buf[TX_PLOAD_WIDTH];
uchartx_buf[TX_PLOAD_WIDTH];
uchardistance_data[2];
ucharflag;
//标志
sbitCE=P1^0;
//发射高电平大于10MS接收高电平
sbitCSN=P1^1;
//低电平ISP使能
sbitSCK=P1^2;
//下降沿
sbitMOSI=P1^3;
//MCU出
sbitMISO=P1^4;
//MCU入
sbitIRQ=P1^5;
//中断
ucharbdatasta;
sbitRX_DR=sta^6;
//接收数据准备就绪
sbitTX_DS=sta^5;
//已发送数据
sbitMAX_RT=sta^4;
sbitDQ=P3^0;
unsignedchartime;
//设置全局变量,专门用于严格延时
//*********************************************NRF24L01***********************
//***************************************NRF24L01寄存器指令
#defineREAD_REG0x00//读寄存器指令
#defineWRITE_REG0x20//写寄存器指令
#defineRD_RX_PLOAD0x61//读取接收数据指令
#defineWR_TX_PLOAD0xA0//写待发数据指令
#defineFLUSH_TX0xE1//冲洗发送FIFO指令
#defineFLUSH_RX0xE2//冲洗接收FIFO指令
#defineREUSE_TX_PL0xE3//定义重复装载数据指令
#defineNOP0xFF//保留
//*************************************SPI(nRF24L01)寄存器地址
#defineCONFIG0x00//配置收发状态,CRC校验模式以及收发状态响应方式
#defineEN_AA0x01//自动应答功能设置
#defineEN_RXADDR0x02//可用信道设置
#defineSETUP_AW0x03//收发地址宽度设置
#defineSETUP_RETR0x04//自动重发功能设置
#defineRF_CH0x05//工作频率设置
#defineRF_SETUP0x06//发射速率、功耗功能设置
#defineSTATUS0x07//状态寄存器
#defineOBSERVE_TX0x08//发送监测功能
#defineCD0x09//地址检测
#defineRX_ADDR_P00x0A//频道0接收数据地址
#defineRX_ADDR_P10x0B//频道1接收数据地址
#defineRX_ADDR_P20x0C//频道2接收数据地址
#defineRX_ADDR_P30x0D//频道3接收数据地址
#defineRX_ADDR_P40x0E//频道4接收数据地址
#defineRX_ADDR_P50x0F//频道5接收数据地址
#defineTX_ADDR0x10//发送地址寄存器
#defineRX_PW_P00x11//接收频道0接收数据长度
#defineRX_PW_P10x12//接收频道0接收数据长度
#defineRX_PW_P20x13//接收频道0接收数据长度
#defineRX_PW_P30x14//接收频道0接收数据长度
#defineRX_PW_P40x15//接收频道0接收数据长度
#defineRX_PW_P50x16//接收频道0接收数据长度
#defineFIFO_STATUS0x17//FIFO栈入栈出状态寄存器设置
//*****************************************************************************
voidinit_io(void)
{
CE=0;
CSN=1;
SCK=0;
}
voiddelay_ms(unsignedintx)
unsignedinti,j;
for(i=0;
i<
x;
i++)
{j=108;
while(j--);
ucharSPI_RW(ucharbyte)//发送指令,接受状态,返回值为状态值
ucharbit_ctr;
for(bit_ctr=0;
bit_ctr<
8;
bit_ctr++)
MOSI=(byte&
0x80);
byte=(byte<
<
1);
SCK=1;
byte|=MISO;
return(byte);
ucharSPI_RW_Reg(ucharreg,ucharvalue)
ucharstatus;
CSN=0;
status=SPI_RW(reg);
SPI_RW(value);
CSN=1;
return(status);
ucharSPI_Read(ucharreg)
ucharreg_val;
SPI_RW(reg);
//写指令
reg_val=SPI_RW(0);
//读reg的内容
return(reg_val);
ucharSPI_Read_Buf(ucharreg,uchar*pBuf,ucharbytes)
ucharstatus,byte_ctr;
for(byte_ctr=0;
byte_ctr<
bytes;
byte_ctr++)
pBuf[byte_ctr]=SPI_RW(0);
ucharSPI_Write_Buf(ucharreg,uchar*pBuf,ucharbytes)
byte_ctr<
byte_ctr++)
SPI_RW(*pBuf++);
voidTX_Mode(void)
SPI_Write_Buf(WRITE_REG+TX_ADDR,TX_ADDRESS/*接收模块的地址*/,
TX_ADR_WIDTH/*地址宽度5*/);
SPI_Write_Buf(WRITE_REG+RX_ADDR_P0/*通道0接收数据地址*/,TX_ADDRESS,
TX_ADR_WIDTH);
SPI_Write_Buf(WR_TX_PLOAD,/*写待发数据指令a0*/tx_buf,
TX_PLOAD_WIDTH/*20*/);
SPI_RW_Reg(WRITE_REG+EN_AA,0x01);
//数据通道0应答允许
SPI_RW_Reg(WRITE_REG+EN_RXADDR,0x01);
//接收数据通道0允许
SPI_RW_Reg(WRITE_REG+SETUP_RETR,0x1a);
//等待500+86us自动重发10次
SPI_RW_Reg(WRITE_REG+RF_CH,40);
SPI_RW_Reg(WRITE_REG+RF_SETUP,0x07);
//数据传输率1Mbps,发射功率0dBm
SPI_RW_Reg(WRITE_REG+CONFIG,0x0e);
//配置寄存器
CE=1;
voidcheckflag()
{sta=SPI_Read(STATUS);
//读状态寄存器
//if(RX_DR)
//{
//SPI_Read_Buf(RD_RX_PLOAD/*读取接收数据指令*/,rx_buf/*数组[20]*/,TX_PLOAD_WIDTH/*20*/);
//flag=1;
//}
if(MAX_RT)
SPI_RW_Reg(FLUSH_TX/*冲洗发送FIFO指令*/,0);
SPI_RW_Reg(WRITE_REG+STATUS,sta);
//清除中断
//以下是DS18B20的操作程序//************************************************************************/
voiddelay1ms()
unsignedchari,j;
4;
for(j=0;
j<
33;
j++)
;
/*****************************************************
函数功能:
延时若干毫秒
入口参数:
n
***************************************************/
voiddelaynms(unsignedcharn)
unsignedchari;
n;
delay1ms();
将DS18B20传感器初始化,读取应答信号
出口参数:
flag
bitInit_DS18B20(void)
bitflag;
//储存DS18B20是否存在的标志,flag=0,表示存在;
flag=1,表示不存在
DQ=1;
//先将数据线拉高
for(time=0;
time<
2;
time++)//略微延时约6微秒
DQ=0;
//再将数据线从高拉低,要求保持480~960us
200;
time++)//略微延时约600微秒
//以向DS18B20发出一持续480~960us的低电平复位脉冲
//释放数据线(将数据线拉高)
10;
time++)
//延时约30us(释放总线后需等待15~60us让DS18B20输出存在脉冲)
flag=DQ;
//让单片机检测是否输出了存在脉冲(DQ=0表示存在)
time++)//延时足够长时间,等待存在脉冲输出完毕
return(flag);
//返回检测成功标志
从DS18B20读取一个字节数据
dat***************************************************/
unsignedcharReadOneChar(void)
unsignedchari=0;
unsignedchardat;
//储存读出的一个字节数据
for(i=0;
DQ=1;
//先将数据线拉高
_nop_();
//等待一个机器周期
//单片机从DS18B20读书据时,将数据线从高拉低即启动读时序
//将数据线"
人为"
拉高,为单片机检测DS18B20的输出电平作准备
//延时约6us,使主机在15us内采样
dat>
>
=1;
if(DQ==1)
dat|=0x80;
//如果读到的数据是1,则将1存入dat
else
dat|=0x00;
//如果读到的数据是0,则将0存入dat
//将单片机检测到的电平信号DQ存入r[i]
//延时3us,两个读时序之间必须有大于1us的恢复期
return(dat);
//返回读出的十六进制数据
向DS18B20写入一个字节数据
dat
WriteOneChar(unsignedchardat)
i<
i++)
DQ=0;
//将数据线从高拉低时即启动写时序
DQ=dat&
0x01;
//利用与运算取出要写的某位二进制数据,
//并将其送到数据线上等待DS18B20采样
//延时约30us,DS18B20在拉低后的约15~60us期间从数据线上采样
DQ=1;
//释放数据线
1;
time++);
//延时3us,两个写时序间至少需要1us的恢复期
//将dat中的各二进制位数据右移1位
//稍作延时,给硬件一点反应时间
做好读温度的准备
voidReadyReadTemp(void)
Init_DS18B20();
//将DS18B20初始化
WriteOneChar(0xCC);
//跳过读序号列号的操作
WriteOneChar(0x44);
//启动温度转换
delaynms(150);
//转换一次需要延时一段时间
WriteOneChar(0xBE);
//读取温度寄存器,前两个分别是温度的低位和高位
voiddwend(void)
{ucharTL;
//储存暂存器的温度低位
ucharTH;
//储存暂存器的温度高位
TL=ReadOneChar();
//先读的是温度值低位
TH=ReadOneChar();
//接着读的是温度值高位
distance_data[0]=TH;
//测量结果的高8位
distance_data[1]=TL;
//放入16位的高8位
voidmain(void)
ucharxx;
init_io();
while
(1)
ReadyReadTemp();
dwend();
checkflag();
for(xx=0;
xx<
xx++)
tx_buf[xx]=distance_data[xx];
//发数据之前必须把要发送的数据装入它
TX_Mode();
//必须启动发送模块
delay_ms(5);
ucharcodedigit[11]={"
0123456789-"
};
//定义字符数组显示数字
ucharcodeStr[]={"
3113001731"
//说明显示的是温度
//unsignedcharcodeError[]={"
DS18B20ERROR"
//说明没有检测到DS18B20
//unsignedcharcodeError1[]={"
PLEASECHECK"
ucharcodeTemp[]={"
wendu:
"
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于 单片机 无线 温度计 设计 报告
![提示](https://static.bdocx.com/images/bang_tan.gif)