关于LCD数字显示温度计的课程设计,急,重赏

关于LCD数字显示温度计的课程设计,急,重赏,第1张

/*电子时钟源代码*/

#include<graphics.h>

#include<stdio.h>

#include<math.h>

#include<dos.h>

#define PI 3.1415926 /*定义常量*/

#define UP 0x4800 /*上移↑键:修改时间*/

#define DOWN 0x5000 /*下移↓键:修改时间*/

#define ESC 0x11b /*ESC键 : 退出系统*/

#define TAB 0xf09 /*TAB键 : 移动光标*/

/*函数声明*/

int keyhandle(int,int)/*键盘按键判断,并调用相关函数处理*/

int timeupchange(int) /*处理上移按键*/

int timedownchange(int)/*处理下移按键*/

int digithour(double)/*将double型的小时数转换成int型*/

int digitmin(double) /*将double型的分钟数转换成int型*/

int digitsec(double) /*将double型的秒钟数转换成int型*/

void digitclock(int,int,int )/*在指定位置显示时钟或分钟或秒钟数*/

void drawcursor(int)/*绘制一个光标*/

void clearcursor(int)/*消除前一个光标*/

void clockhandle()/*时钟处理*/

double h,m,s/*全局变量:小时,分,秒*/

double x,x1,x2,y,y1,y2/*全局变量:坐标值*/

struct time t[1]/*定义一个time结构类型的数组*/

main()

{

int driver, mode=0,i,j

driver=DETECT/*自动检测显示设备*/

initgraph(&driver, &mode, "")/*初始化图形系统*/

setlinestyle(0,0,3)/*设置当前画线宽度和类型:设置三点宽实线*/

setbkcolor(0)/*用调色板设置当前背景颜色*/

setcolor(9)/*设置当前画线颜色*/

line(82,430,558,430)

line(70,62,70,418)

line(82,50,558,50)

line(570,62,570,418)

line(70,62,570,62)

line(76,56,297,56)

line(340,56,564,56) /*画主体框架的边直线*/

/*arc(int x, int y, int stangle, int endangle, int radius)*/

arc(82,62,90,180,12)

arc(558,62,0,90,12)

setlinestyle(0,0,3)

arc(82,418,180,279,12)

setlinestyle(0,0,3)

arc(558,418,270,360,12) /*画主体框架的边角弧线*/

setcolor(15)

outtextxy(300,53,"CLOCK")/*显示标题*/

setcolor(7)

rectangle(342,72,560,360)/*画一个矩形,作为时钟的框架*/

setwritemode(0)/*规定画线的方式。mode=0, 则表示画线时将所画位置的原来信息覆盖*/

setcolor(15)

outtextxy(433,75,"CLOCK")/*时钟的标题*/

setcolor(7)

line(392,310,510,310)

line(392,330,510,330)

arc(392,320,90,270,10)

arc(510,320,270,90,10)/*绘制电子动画时钟下的数字时钟的边框架*/

/*绘制数字时钟的时分秒的分隔符*/

setcolor(5)

for(i=431i<=470i+=39)

for(j=317j<=324j+=7){

setlinestyle(0,0,3)

circle(i,j,1)/*以(i, y)为圆心,1为半径画圆*/

}

setcolor(15)

line(424,315,424,325)/*在运行电子时钟前先画一个光标*/

/*绘制表示小时的圆点*/

for(i=0,m=0,h=0i<=11i++,h++){

x=100*sin((h*60+m)/360*PI)+451

y=200-100*cos((h*60+m)/360*PI)

setlinestyle(0,0,3)

circle(x,y,1)

}

/*绘制表示分钟或秒钟的圆点*/

for(i=0,m=0i<=59m++,i++){

x=100*sin(m/30*PI)+451

y=200-100*cos(m/30*PI)

setlinestyle(0,0,1)

circle(x,y,1)

}

/*在电子表的左边打印帮助提示信息*/

setcolor(4)

outtextxy(184,125,"HELP")

setcolor(15)

outtextxy(182,125,"HELP")

setcolor(5)

outtextxy(140,185,"TAB : Cursor move")

outtextxy(140,225,"UP : Time ++")

outtextxy(140,265,"DOWN: Time --")

outtextxy(140,305,"ESC : Quit system!")

outtextxy(140,345,"Version : 2.0")

setcolor(12)

outtextxy(150,400,"Nothing is more important than time!")

clockhandle()/*开始调用时钟处理程序*/

closegraph()/*关闭图形系统*/

return 0/*表示程序正常结束,向 *** 作系统返回一个0值*/

}

void clockhandle()

{

int k=0,count

setcolor(15)

gettime(t)/*取得系统时间,保存在time结构类型的数组变量中*/

h=t[0].ti_hour

m=t[0].ti_min

x=50*sin((h*60+m)/360*PI)+451/*时针的x坐标值*/

y=200-50*cos((h*60+m)/360*PI)/*时针的y坐标值*/

line(451,200,x,y)/*在电子表中绘制时针*/

x1=80*sin(m/30*PI)+451/*分针的x坐标值*/

y1=200-80*cos(m/30*PI)/*分针的y坐标值*/

line(451,200,x1,y1)/*在电子表中绘制分针*/

digitclock(408,318,digithour(h))/*在数字时钟中,显示当前的小时值*/

digitclock(446,318,digitmin(m))/*在数字时钟中,显示当前的分钟值*/

setwritemode(1)

/*规定画线的方式,如果mode=1,则表示画线时用现在特性的线

与所画之处原有的线进行异或(XOR) *** 作,实际上画出的线是原有线与现在规定

的线进行异或后的结果。因此, 当线的特性不变, 进行两次画线 *** 作相当于没有

画线,即在当前位置处清除了原来的画线*/

for(count=2k!=ESC){ /*开始循环,直至用户按下ESC键结束循环*/

setcolor(12)/*淡红色*/

sound(500)/*以指定频率打开PC扬声器,这里频率为500Hz*/

delay(700)/*发一个频率为500Hz的音调,维持700毫秒*/

sound(200)/*以指定频率打开PC扬声器,这里频率为200Hz*/

delay(300)

/*以上两种不同频率的音调,可仿真钟表转动时的嘀哒声*/

nosound()/*关闭PC扬声器*/

s=t[0].ti_sec

m=t[0].ti_min

h=t[0].ti_hour

x2=98*sin(s/30*PI)+451/*秒针的x坐标值*/

y2=200-98*cos(s/30*PI)/*秒针的y坐标值*/

line(451,200,x2,y2)

/*绘制秒针*/

/*利用此循环,延时一秒*/

while(t[0].ti_sec==s&&t[0].ti_min==m&&t[0].ti_hour==h)

{ gettime(t)/*取得系统时间*/

if(bioskey(1)!=0){

k=bioskey(0)

count=keyhandle(k,count)

if(count==5) count=1

}

}

setcolor(15)

digitclock(485,318,digitsec(s)+1)/*数字时钟增加1秒*/

setcolor(12)/*淡红色*/

x2=98*sin(s/30*PI)+451

y2=200-98*cos(s/30*PI)

line(451,200,x2,y2)

/*用原来的颜色在原来位置处再绘制秒针,以达到清除当前秒针的目的*/

/*分钟处理*/

if(t[0].ti_min!=m){ /*若分钟有变化*/

/*消除当前分针*/

setcolor(15)/*白色*/

x1=80*sin(m/30*PI)+451

y1=200-80*cos(m/30*PI)

line(451,200,x1,y1)

/*绘制新的分针*/

m=t[0].ti_min

digitclock(446,318,digitmin(m))/*在数字时钟中显示新的分钟值*/

x1=80*sin(m/30*PI)+451

y1=200-80*cos(m/30*PI)

line(451,200,x1,y1)

}

/*小时处理*/

if((t[0].ti_hour*60+t[0].ti_min)!=(h*60+m)){ /*若小时数有变化*/

/*消除当前时针*/

setcolor(15)/*白色*/

x=50*sin((h*60+m)/360*PI)+451/*50:时钟的长度(单位:像素),451:圆心的x坐标值*/

y=200-50*cos((h*60+m)/360*PI)

line(451,200,x,y)

/*绘制新的时针*/

h=t[0].ti_hour

digitclock(408,318,digithour(h))

x=50*sin((h*60+m)/360*PI)+451

y=200-50*cos((h*60+m)/360*PI)

line(451,200,x,y)

}

}

}

int keyhandle(int key,int count) /*键盘控制 */

{ switch(key)

{case UP: timeupchange(count-1)/*因为count的初始值为2,所以此处减1*/<br> break<br> case DOWN:timedownchange(count-1)/*因为count的初始值为2,所以此处减1*/<br>break<br> case TAB:setcolor(15)<br> clearcursor(count)/*清除原来的光标*/<br> drawcursor(count) /*显示一个新的光标*/<br> count++<br> break<br> }

return count

}

int timeupchange(int count) /*处理光标上移的按键*/

{

if(count==1){

t[0].ti_hour++

if(t[0].ti_hour==24) t[0].ti_hour=0

settime(t)/*设置新的系统时间*/

}

if(count==2){

t[0].ti_min++

if(t[0].ti_min==60) t[0].ti_min=0

settime(t)/*设置新的系统时间*/

}

if(count==3){

t[0].ti_sec++

if(t[0].ti_sec==60) t[0].ti_sec=0

settime(t)/*设置新的系统时间*/

}

}

int timedownchange(int count) /*处理光标下移的按键*/

{

if(count==1) {

t[0].ti_hour--

if(t[0].ti_hour==0) t[0].ti_hour=23

settime(t)/*设置新的系统时间*/

}

if(count==2) {

t[0].ti_min--

if(t[0].ti_min==0) t[0].ti_min=59

settime(t)/*设置新的系统时间*/

}

if(count==3) {

t[0].ti_sec--

if(t[0].ti_sec==0) t[0].ti_sec=59

settime(t)/*设置新的系统时间*/

}

}

int digithour(double h)/*将double型的小时数转换成int型*/

{int i<br>for(i=0i<=23i++)<br> {if(h==i) return i}

}

int digitmin(double m)/*将double型的分钟数转换成int型*/

{int i<br>for(i=0i<=59i++)<br> {if(m==i) return i}

}

int digitsec(double s) /*将double型的秒钟数转换成int型*/

{int i<br>for(i=0i<=59i++)<br> {if(s==i) return i}

}

void digitclock(int x,int y,int clock)/*在指定位置显示数字时钟:时\分\秒*/

{char buffer1[10]<br>setfillstyle(0,2)<br>bar(x,y,x+15,328)<br>if(clock==60) clock=0<br>sprintf(buffer1,"%d",clock)<br>outtextxy(x,y,buffer1)<br>}

void drawcursor(int count)/*根据count的值,画一个光标*/

{switch(count)<br>{<br> case 1:line(424,315,424,325)break<br> case 2:line(465,315,465,325)break<br> case 3:line(505,315,505,325)break<br> }

}

void clearcursor(int count)/*根据count的值,清除前一个光标*/

{switch(count)<br>{<br> case 2:line(424,315,424,325)break<br> case 3:line(465,315,465,325)break<br> case 1:line(505,315,505,325)break<br> }

}

/***********ds18b20子程序*************************/

/***********ds18b20延迟子函数(晶振12MHz )*******/

#include<reg51.h>

sbit DQ=P1^2

#define uchar unsigned char

void delay_18B20(unsigned int i)

{

while(i--)

}

/**********ds18b20初始化函数**********************/

void Init_DS18B20(void)

{

unsigned char x=0

DQ = 1 //DQ复位

delay_18B20(8) //稍做延时

DQ = 0 //单片机将DQ拉低

delay_18B20(80)//精确延时 大于 480us

DQ = 1 //拉高总线

delay_18B20(4)

x=DQ //稍做延时后 如果x=0则初始化成功 x=1则初始化失败

delay_18B20(20)

}

/***********ds18b20读一个字节**************/

unsigned char ReadOneChar(void)

{

uchar i=0

uchar dat = 0

for (i=8i>0i--)

{

DQ = 0// 给脉冲信号

dat>>=1

DQ = 1// 给脉冲信号

if(DQ)

dat|=0x80

delay_18B20(4)

}

return(dat)

}

/*************ds18b20写一个字节****************/

void WriteOneChar(uchar dat)

{

unsigned char i=0

for (i=8i>0i--)

{

DQ = 0

DQ = dat&0x01

delay_18B20(5)

DQ = 1

dat>>=1

}

}

/**************读取ds18b20当前温度************/

ReadTemp(void)

{ float val

uchar temp_value,value

unsigned char a=0

unsigned char b=0

unsigned char t=0

Init_DS18B20()

WriteOneChar(0xCC) // 跳过读序号列号的 *** 作

WriteOneChar(0x44) // 启动温度转换

delay_18B20(100) // this message is wery important

Init_DS18B20()

WriteOneChar(0xCC) //跳过读序号列号的 *** 作

WriteOneChar(0xBE) //读取温度寄存器等(共可读9个寄存器) 前两个就是温度

delay_18B20(100)

a=ReadOneChar() //读取温度值低位

b=ReadOneChar() //读取温度值高位

temp_value=b<<4

temp_value+=(a&0xf0)>>4

value=a&0x0f

val=temp_value+value

return(val)

}

以上是DS18B20的驱动程序。然后在主程序中直接调用函数就可以了。

以上是在主程序中的调用,你看关于温度的那个就可以。

#include "reg51.h"

#include "18b20.h"

#define uchar unsigned char

#define uint unsigned int

uchar code table[]="Welcome To" //初始化日期和星期

uchar code table1[]="Our System!"//初始化时间

uchar code table2[]="Temperature is:"//初始化时间

//以下三个是定义LCD的引脚

sbit lcden=P2^2

sbit lcdwrite=P2^1

sbit lcdrs=P2^0

char wendu

//延时程序

void delay(uint z)

{ uint x,y

for(x=zx>0x--)

for(y=110y>0y--)

}

//lcd的写指令

void write_com(uchar com)

{

lcdrs=0

lcden=0

P0=com

delay(5)

lcden=1

delay(5)

lcden=0

}

//lcd的写数据

void write_data(uchar da)

{ lcdrs=1

lcden=0

P0=da

delay(5)

lcden=1

delay(5)

lcden=0

}

//初始化

void init()

{

uchar num

lcdwrite=0

lcden=0

write_com(0x38)//16*2显示,5*7点阵,8位数据

write_com(0x0c)//显示开,关光标

write_com(0x06)//移动光标

write_com(0x01)//清除LCD的显示内容

write_com(0x80)

for (num=0num<10num++)

{

write_data(table[num])

delay(5)

}

write_com(0x80+0x40)

for (num=0num<11num++)

{

write_data(table1[num])

delay(5)

}

}

void write_wendu(uchar add, char da)

{

uchar shi,ge

shi=da/10

ge=da%10

write_com(0x80+0x40+add)

write_data(0x30+shi)

write_data(0x30+ge)

}

//主函数

void main ()

{

uchar num

init()

delay(2000)

delay(2000)

delay(2000)

write_com(0x01)//清除LCD的显示内容

while(1)

{

write_com(0x80)

for (num=0num<15num++)

{

write_data(table2[num])

delay(5)

}

wendu = ReadTemp( )

write_wendu(2,wendu)

}

}

//------------------------------------------------------------------

//DS18B20温度传感器输出显示,运行本例时,外界温度将显示在1602LCD上

//------------------------------------------------------------------

#include <reg52.h>

#include <intrins.h>

#define uchar unsigned char

#define uint unsigned int

#define delayNOP() {_nop_()_nop_()_nop_()_nop_()}

sbit DQ=P2^2

sbit dula=P2^6//定义锁存器锁存端

sbit wela=P2^7

sbit rs=P3^5 //定义1602液晶RS端

sbit lcden=P3^4//定义1602液晶LCDEN端

sbit s1=P3^0 //定义按键--功能键

sbit s2=P3^1//定义按键--增加键

sbit s3=P3^2//定义按键--减小键

sbit s4=P3^6//闹钟查看键

sbit rd=P3^7

sbit beep=P2^3//定义蜂鸣器端

uchar code Temp_Disp_Title[]={" Current Temp : "}

uchar Current_Temp_Display_Buffer[]={" TEMP: "}

uchar code Alarm_Temp[]={"ALARM TEMP Hi Lo"}

uchar Alarm_HI_LO_STR[]={"Hi:Lo:"}

uchar temp_data[2]={0x00,0x00}

uchar temp_alarm[2]={0x00,0x00}

uchar display[5]={0x00,0x00,0x00,0x00,0x00}

uchar display1[3]={0x00,0x00,0x00}

uchar code df_Table[]={0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9}

uchar CurrentT=0//当前读取的温度整数部分

uchar Temp_Value[]={0x00,0x00}//从DS18B20读取的温度值

uchar Display_Digit[]={0,0,0,0} //待显示的各温度数位

bit DS18B20_IS_OK=1//传感器正常标志

//-------------------------------------

//延时1

//-------------------------------------

void delay1(uint x)

{

uchar i

while(x--) for(i=0i<200i++)

}

//-------------------------------------

//延时2

//-------------------------------------

void Delay(uint x)

{

while(x--)

}

//------------------------------------

//忙检查

//------------------------------------

void write_com(uchar com)//液晶写命令函数

{

rs=0

lcden=0

P0=com

delay1(5)

lcden=1

delay1(5)

lcden=0

}

void Write_LCD_Data(uchar date)//液晶写数据函数

{

rs=1

lcden=0

P0=date

delay1(5)

lcden=1

delay1(5)

lcden=0

}

//-----------------------------

//设置LCD显示位置

//---------------------------------

void Set_Disp_Pos(uchar Pos)

{

write_com(Pos|0x80)

}

//-----------------------------

//LCD初始化

//---------------------------------

void Initialize_LCD()

{

uchar num

rd=0 //软件将矩阵按键第4列一端置低用以分解出独立按键

dula=0//关闭两锁存器锁存端,防止 *** 作液晶时数码管会出乱码

wela=0

lcden=0

write_com(0x38)//初始化1602液晶

write_com(0x0c)

write_com(0x06)

write_com(0x01)

write_com(0x80)//设置显示初始坐标

for(num=0num<14num++)//显示年月日星期

{

Write_LCD_Data(Temp_Disp_Title[num])

delay1(5)

}

}

//-------------------------------------

//函数功能:初始化DS18B20

//出口参数:status---DS18B20是否复位成功的标志

//-------------------------------------

uchar Init_DS18B20()

{

uchar status //储存DS18B20是否存在的标志,status=0,表示存在;status=1,表示不存在

DQ=1Delay(8) //先将数据线拉高 //略微延时约6微秒

DQ=0Delay(90) //再将数据线从高拉低,要求保持480~960us

//略微延时约600微秒 以向DS18B20发出一持续480~960us的低电平复位脉冲

DQ=1Delay(8) //释放数据线(将数据线拉高) //延时约30us(释放总线后需等待15~60us让DS18B20输出存在脉冲)

status=DQDelay(100) //让单片机检测是否输出了存在脉冲(DQ=0表示存在) //延时足够长时间,等待存在脉冲输出完毕

DQ=1 // 将数据线拉高

return status//返回检测成功标志

}

//-------------------------------------

//函数功能:读一字节

//出口参数:dat---读出的数据

//-------------------------------------

uchar ReadOneByte()

{

uchar i,dat=0

DQ=1_nop_() // 先将数据线拉高 //等待一个机器周期

for (i=0i<8i++)

{

DQ=0 //单片机从DS18B20读书据时,将数据线从高拉低即启动读时序

dat>>=1

_nop_()//等待一个机器周期

DQ=1 //将数据线"人为"拉高,为单片机检测DS18B20的输出电平作准备

_nop_()_nop_()//延时约6us,使主机在15us内采样

if (DQ) dat|=0x80 //如果读到的数据是1,则将1存入dat,如果是0则保持原值不变

Delay(30)//延时3us,两个读时序之间必须有大于1us的恢复期

DQ=1 // 将数据线拉高,为读下一位数据做准备

}

return dat

}

//-------------------------------------

//函数功能:写一字节

//入口参数:dat---待写入的数据

//-------------------------------------

void WriteOneByte(uchar dat)

{

uchar i

for (i=0i<8i++)

{

DQ=0 //将数据线从高拉低时即启动写时序

DQ=dat &0x01//利用与运算取出要写的某位二进制数据,

//并将其送到数据线上等待DS18B20采样

Delay(5) //延时约30us,DS18B20在拉低后的约15~60us期间从数据线上采样

DQ=1 //释放数据线

dat>>=1//将dat中的各二进制位数据右移1位

}

}

//-------------------------------------

//函数功能:读取温度值

//出入口参数:无

//-------------------------------------

void Read_Temperature()

{

if(Init_DS18B20() == 1) //DS18B20故障

DS18B20_IS_OK=0

else

{

WriteOneByte(0xCC) // 跳过读序号列号的 *** 作

WriteOneByte(0x44) // 启动温度转换

Init_DS18B20() //将DS18B20初始化

WriteOneByte(0xCC) //跳过读序号列号的 *** 作

WriteOneByte(0xBE) //读取温度寄存器,前两个分别是温度的低位和高位

Temp_Value[0]=ReadOneByte() //温度低8位

Temp_Value[1]=ReadOneByte() //温度高8位

DS18B20_IS_OK=1

}

}

//-------------------------------------

//函数功能:在LCD上显示当前温度

//入口参数:

//-------------------------------------

void Display_Temperature()

{

uchar i

//延时值与负数标识

uchar t=150,ng=0

//高5位全为1(0xF8)则为负数,为负数时取反加1,并设置负数标示

if ((Temp_Value[1] &0xF8)==0xF8)

{

Temp_Value[1]=~Temp_Value[1]

Temp_Value[0]=~Temp_Value[0]+1

if(Temp_Value[0]==0x00) Temp_Value[1]++ //加1后如果低字节为00表示有进位,进位位再加到高字节上

ng=1 //负数标示置1

}

Display_Digit[0]=df_Table[Temp_Value[0] &0x0F]//查表得到温度小数部分

//获取温度整数部分(高字节的低3位与低字节中的高4位,无符号)

CurrentT=((Temp_Value[0] &0xF0)>>4)|((Temp_Value[1] &0x07)<<4)

//将整数部分分解为3位待显示数字

Display_Digit[3]=CurrentT/100//百位 digit[CurrentT/100]

Display_Digit[2]=CurrentT%100/10//十位

Display_Digit[1]=CurrentT%10//个位

//刷新LCD显示缓冲

Current_Temp_Display_Buffer[11]=Display_Digit[0]+'0'//先将'0'转换成整数48,然后与前面数字相加,得到相应数字的ASCII字符

Current_Temp_Display_Buffer[10]='.'

Current_Temp_Display_Buffer[9]=Display_Digit[1]+'0' //个位

Current_Temp_Display_Buffer[8]=Display_Digit[2]+'0' //十位

Current_Temp_Display_Buffer[7]=Display_Digit[3]+'0' //百位

//高位为0时不显示

if(Display_Digit[3]==0) Current_Temp_Display_Buffer[7]=' '

//高位为0且次高位为0时,次高位不显示

if(Display_Digit[2]==0 &&Display_Digit[3]==0)

Current_Temp_Display_Buffer[8]=' '

//负数符号显示在恰当位置

if(ng)

{

if (Current_Temp_Display_Buffer[8]==' ')

Current_Temp_Display_Buffer[8]='-'

else if(Current_Temp_Display_Buffer[7]==' ')

Current_Temp_Display_Buffer[7]='-'

else

Current_Temp_Display_Buffer[6]='-'

}

//在第一行显示标题

Set_Disp_Pos(0x00)

for(i=0i<16i++)

{

Write_LCD_Data(Temp_Disp_Title[i])

}

Set_Disp_Pos(0x40) //在第二行显示当前温度

for(i=0i<16i++)

{

Write_LCD_Data(Current_Temp_Display_Buffer[i])

}

//显示温度符号

//Set_Disp_Pos(0x4D)Write_LCD_Data(0x00)

Set_Disp_Pos(0x4D)Write_LCD_Data(0xdf)

Set_Disp_Pos(0x4E)Write_LCD_Data('C')

}

//-------------------------------------

//函数功能:主函数

//入口参数:

//-------------------------------------

void main()

{

Initialize_LCD()

Read_Temperature()

Delay(50000)

Delay(50000)

while (1)

{

Read_Temperature()

if (DS18B20_IS_OK) Display_Temperature()

delay1(100)

}

}


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/yw/11327127.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-15
下一篇2023-05-15

发表评论

登录后才能评论

评论列表(0条)

    保存