我上周弄的温度传感器课程设计
里面包含单片机代码
Altium Designer画的原理图和PCB图如下:(51hei附件中可下载工程文件)
单片机源程序如下:
- #include"reg52.h"
- #include "intrins.h"
- /*******************宏定义**************************************************/
- #define uchar unsigned char
- #define uint unsigned int //宏定义
- #define IE_value 0x82
- #define XIA 20
- #define SHANG 90
- //#define P0_value 0x3f
- /*******************端口定义及开辟相应的存储单元***************************/
- sbit DQ = P2^0; //DS18B20单总线接入点
- bit flag; //检测芯片是否存在的标志位
- bit signal; //温度符号标志位
- sbit L1=P2^4; //芯片存在P1.0置0点亮LED灯
- sbit L2=P2^3; //芯片不存在P1.1置0点亮LED灯
- uchar buf[3] ; //存储转换后温度的高8位与低8位
- uchar buf1[3];
- uchar temper_value; //存储转化后温度的结果值
- sbit lcd_ce=P2^7; //使能端
- sbit lcd_rs=P2^5; //数据/命令选择端
- sbit lcd_rw=P2^6; //读/写选择端
- sbit K1=P1^0;
- sbit K2=P1^1;
- sbit K3=P1^2;
- sbit K4=P1^3;
- sbit beep=P2^2;
- uchar count,k1num,beepp;
- char shi,fen,miao;
- uchar code table[]=" 00-00-00 ";
- uchar code table1[]="T: 00C S:90 X:00";
- uchar num,aa,gao,di;
- uchar shang,xia; //上下限温度设置
- void chushihua(); //申明初始化子函数
- void delay_1(uint z); //申明延时函数
- void write_ml(uchar m); //申明写命令子函数
- void write_data(uchar s); //申明写数据子函数
- void write_sfm(uchar add,uchar da);
- void write_fsm2(uchar add,uchar dat);
- /********************************************************************
- 函 数 名:蜂鸣器控制
- 功 能:蜂鸣器箱
- 说 明:
- 入口参数: 无
- 返 回 值:无
- 日 期:2018-1-2
- ***********************************************************************/
- void beepf()
- {
- if(temper_value<=xia || temper_value>=shang)
- {
- beepp=1;
- }
- else
- {
- beepp=0;
- }
- if(beepp==1){
- ET1=1; //开定时器0中断
- TR1=1; //启动定时器0
- }
-
- else{
- ET1=0; //开定时器0中断
- TR1=0; //启动定时器0
- }
- }
- /********************************************************************
- 函 数 名:按键控制
- 功 能:判断按键
- 说 明:
- 入口参数: 无
- 返 回 值:无
- 日 期:2018-1-2
- ***********************************************************************/
- void anjian()
- {
- if(K1==0)
- {
- xia++;
- while(K1!=1);
- }
- if(K2==0)
- {
- xia--;
- while(K2!=1);
- }
- if(K3==0)
- {
- shang++;
- while(K3!=1);
- }
- if(K4==0)
- {
- shang--;
- while(K4!=1);
- }
- }
- /********************************************************************
- 函 数 名:延时子函数delay
- 功 能:延时
- 说 明:
- 入口参数: i
- 返 回 值:无
- 日 期:2018-1-2
- ***********************************************************************/
- void delay(uchar i)
- {
- while(--i);
- }
- /********************************************************************
- 函 数 名:初始化子函数 reset_signal
- 功 能:信号复位进行初始化
- 说 明:
- 入口参数:
- 返 回 值:无
- 设 计: 日 期:2018-1-2
- ***********************************************************************/
- reset_signal()
- {
- DQ = 1;
- _nop_(); //空语句延时1uS
- DQ = 0; //主机发送复位脉冲至少持续480uS
- delay(250); //480uS~960uS之间
- DQ = 1; //复位结束,将单总线拉高
- delay(20); //延时至少16uS
- flag = DQ; //等待16uS后发送存在脉冲(低电平)持续60uS~240uS,DS18B20与MCU达成基本协议
- if(flag==0) //若flag=0则表示存在
- {
- L1= 0; //P1.4亮
- delay(90); //延时60uS~240uS之间
- }
- else
- L2=0;
- //不存在则P2.3亮
- DQ = 1;
- }
- /********************************************************************
- 函 数 名: w_order
- 功 能:写入将要执行操作的命令
- 说 明:
- 入口参数:cmd
- 返 回 值:无
- 设 计: 日 期:2018-1-2
- ***********************************************************************/
- void w_order(uchar cmd)
- {
- uchar i;
- for(i=0;i<8;i++)
- {
- if(cmd&(0x01<<i)) //写1
- {
- DQ = 0; //主机将数据线拉至低电平产生写时间片
- _nop_(); //最好是拉至低电平后就释放(但延时至少1uS以上),这样才能在15uS内恢复到高电平
- _nop_();
- DQ = 1; //15uS内必须拉至高电平(因为DS18B20在15uS~60uS之间对数据线进行采样)
- delay(28); //延时60uS(因为一个写周期至少延时60uS)
- }
- else //写0
- {
- DQ = 0; //主机将数据线拉至低电平产生写时间片
- delay(40); //延时60uS以上(因为一个写周期至少延时60uS)
- DQ = 1;
- _nop_(); //恢复延时(因为个写周期之间至少有1uS的恢复时间)
- _nop_();
- _nop_();
- _nop_();
- }
- }
- }
- /********************************************************************
- 函 数 名:r_data
- 功 能:读出转换后的温度结果存入 buf 1中
- 说 明:
- 入口参数:
- 返 回 值:无
- 设 计: 日 期:2018-1-2
- ***********************************************************************/
- void r_data()
- {
- uint i,j;
- for(j=0;j<2;j++)
- {
- buf[j] = 0;
- for(i=0;i<8;i++)
- {
- DQ = 1;
- _nop_();
- DQ = 0; //主机将数据线拉至低电平产生读时间片
- _nop_(); //最好是拉至低电平后就释放(但延时至少1uS以上),这样才能在15uS内恢复到高电平
- _nop_(); //15uS内必须驱动至高电平(因为DS18B20输出数据在读时间片下降沿后15uS有效)
- DQ = 1;
- _nop_();
- if(DQ) //提高总线后马上读取
- {
- buf[j]|=(1<<i);
- }
- else
- {
- buf[j]&=~(1<<i);
- }
- delay(28); //每个读周期至少持续60uS
- DQ = 1;
- _nop_(); //恢复延时(因为个读周期之间至少有1uS的恢复时间)
- }
- }
- }
- /********************************************************************
- 函 数 名:get_temper_value
- 功 能:获得当前的温度值
- 说 明:
- 入口参数:
- 返 回 值:无
- 设 计: 日 期:2018-1-2
- ***********************************************************************/
- void get_temper_value()
- {
- DQ = 1;
- reset_signal(); //初始化 ,检测是否存在 DS18B20
- if(flag==0)
- {
- w_order(0xcc); //跳过ROM
- w_order(0x44); //启动温度变换
- reset_signal(); //复位
- w_order(0xcc); //跳过ROM
- w_order(0xbe); //准备读暂存器
- r_data(); //读暂存器中温度变化的结果
- }
- }
- /********************************************************************
- 函 数 名:二-十进制转换子函数Conversion
- 功 能:将二进制数转入十进制中
- 说 明:
- 入口参数:
- 返 回 值:无
- 设 计: 日 期:2018-1-2
- ***********************************************************************/
- void Conversion()
- {
- signal = (buf[1]&0xf8); //检温度测是正还是负
- buf1[2] = 0; //温度的符号位
- if(signal)
- {
- buf[0]=~buf[0];
- buf[1]=~buf[1];
- buf1[2]=10;
- }
- buf[0]=(buf[0]>>4); //将温度转换结果的低8位的高4位移入低4位
- //这里我们抛弃了温度转换结果的第四位(小数部分,因为我们不需要那么准确)
- buf[0]=(buf[0]&0x0f); //保留低4位并存入buf[0]中
- buf[1]=(buf[1]<<4); //将温度转换结果的高8位的低4位移入高4位
- buf[1]=(buf[1]&0xf0); //保留高4位并存入buf[1]中
- temper_value=(buf[0]|buf[1]); //将buf[0]与buf[1]相或得温度转换结果存入temper_value中
- if(signal)
- {temper_value++;} //为负时取反加1
- buf1[0]=temper_value%10; //将个位保存在buf1[0]中
- buf1[1]=temper_value/10; //将十位保存在buf1[1]中
- }
- /********************************************************************
- 函 数 名:void timer0() interrupt 1
- 功 能:定时对DS18B20的转换温度进行更新
- 说 明:定时器0中断
- 入口参数:
- 返 回 值:无
- 设 计: 日 期:2018-1-2
- ***********************************************************************/
- void timer0() interrupt 1
- {
- TH0 =0x3c; //(65536-50000)/256;
- TL0 =0xb0; //(65536-50000)%256;
- get_temper_value();
- Conversion();
- count++;
- aa++;
- if(aa==18) //大约1S
- {
- aa=0;
- write_ml(0x80+0x47);
- /*write_ml(0x80+0x00);
- for(num=0;num<15;num++)
- {write_data(table[num]);delay_1(5);}
- write_ml(0x80+0x40); //重新设置数据指针
- for(num=0;num<16;num++)
- {write_data(table1[num]);delay_1(5);} */
- write_sfm(3,gao);
- write_sfm(4,di);
- write_fsm2(14,xia);
- write_fsm2(9,shang);
- }
- }
- void timer1() interrupt 3
- {
- TH1 =0xfd; //(65536-50000)/256;
- TL1 =0xfd; //(65536-50000)%256;
- beep=~beep;
- }
- /********************************************************************
- 函 数 名:void chushihua()
- 功 能:初始化子函数
- 说 明: 见注释
- 返 回 值:无
- 设 计: 日 期:2018-1-2
- ***********************************************************************/
- void chushihua() //初始化子函数
- {
- TMOD=0x11; //定时器0设为工作方式1
- TH0 =0x3c; //(65536-50000)/256;
- TL0 =0xb0; //(65536-50000)%256;
- TH1 =0x3c; //(65536-50000)/256;
- TL1 =0xb0; //(65536-50000)%256;
- EA=1; //开总中断
- ET0=1; //开定时器0中断
- TR0=1; //启动定时器0
- IE = IE_value;
- shang=SHANG;
- xia=XIA;
- beepp=0;
- beep=0;
- lcd_ce=0;
- lcd_rw=0;
- write_ml(0x38); //显示模式设置
- //write_ml(0x08); //显示关闭
- write_ml(0x0c); //显示开关及光标设置
- write_ml(0x06); //地址加1整屏不移动
- write_ml(0x01); //清零
- //write_ml(0x80); //将数据指针移动
- write_ml(0x80+0x00);
- for(num=0;num<15;num++)
- {
- write_data(table[num]);delay_1(5);}
- write_ml(0x80+0x40); //重新设置数据指针
- for(num=0;num<16;num++)
- {write_data(table1[num]);delay_1(5);}
- }
- /********************************************************************
- 函 数 名:void write_sfm(uchar add,uchar da)
- 功 能:函数
- 说 明: 见注释
- 返 回 值:无
- 设 计: 日 期:2018-1-2
- ***********************************************************************/
- void write_sfm(uchar add,uchar da)
- {
- //uchar shi,ge;
- //shi=da/10;
- //ge=da%10;
- write_ml(0x80+0x40+add);
- write_data(0x30+da);
- //write_data(0x30+da);
- }
- void write_fsm1(uchar add,uchar date)
- {
- uchar shi,ge;
- shi=date/10;
- ge=date%10;
- write_ml(0x80+add);
- write_data(0x30+shi);
- write_data(0x30+ge);
- }
- void write_fsm2(uchar add,uchar dat)
- {
- uchar shi,ge;
- shi=dat/10;
- ge=dat%10;
- write_ml(0x80+0x40+add);
- write_data(0x30+shi);
- write_data(0x30+ge);
- }
- /********************************************************************
- 函 数 名:void write_ml(uchar m)
- 功 能:写命令子函数
- 说 明: 见注释
- 返 回 值:无
- 设 计: 日 期:2018-1-2
- ***********************************************************************/
- void write_ml(uchar m)
- {
- lcd_rs=0;
- P0=m;
- delay_1(5);
- lcd_ce=1;
- delay_1(5);
- lcd_ce=0;
- }
- /********************************************************************
- 函 数 名:void write_data(uchar s)
- 功 能:写数据子函数
- 说 明: 见注释
- 返 回 值:无
- 设 计: 日 期:2018-1-2
- ***********************************************************************/
- void write_data(uchar s)
- {
- lcd_rs=1;
- P0=s;
- delay_1(5);
- lcd_ce=1;
- delay_1(5);
- lcd_ce=0;
- }
- /********************************************************************
- 函 数 名:void delay_1(uint z)
- 功 能:延时ms函数
- 说 明:
- 入口参数:延时时间
- 返 回 值:无
- 设 计: 日 期:2018-1-2
- ***********************************************************************/
- void delay_1(uint z) //延时子函数
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=110;y>0;y--); //大约1毫秒
- }
- /********************************************************************
- 函 数 名:jianxian()
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
程序和图.zip
(992.91 KB, 下载次数: 191)
|