|
51单片机LCD1602液晶显示的温度计的仿真原理图(proteus工程文件可到本帖附件下载):
单片机源程序:
- //--------------------------------------------------------------------------------------------
- //程序名: LCD_TEMP09-1.c
- //程序功能:LCD温度计
- //--------------------------------------------------------------------------------------------
- #include <reg51.h>
- #include<intrins.h> //包含_nop_()函数定义的头文件
- sbit RS=P2^5; // 引脚定义
- sbit RW=P2^6;
- sbit EN=P2^7;
- sbit busy=P0^7; // "忙"标志位
- #define LCD P0 //命令或数据线
- sbit DQ=P2^0;
-
- //代码表
- unsigned char code TAB1[]={ 0x0c,0x12,0x12,0x0c,
- 0x00,0x00,0x00,0x00,
- };
- //字符表
- unsigned char code TAB2[]={"DS18B20 OK"};
- unsigned char code Error[]={"Error!Check!"}; //说明没有检测到DS18B20
- unsigned char code digit[10]={"0123456789"}; //定义字符数组显示数字
- unsigned char code TEMP[]={"TEMP:"}; //说明显示的是温度
- unsigned char fuhao;
- //------------------------------------ 延时函数 -------------------------------------------
- void delay(unsigned int t) //延时若干微秒
- {
- while(t--);
- }
- //---------------------------------- 判断液晶显示器是否忙函数 ----------------------------------
- CHECK_BF() //判断是否忙碌
- {
- do
- {
- LCD=0xff;
- RS=0; // RS=0,选择指令寄存器
- RW=1; // RW=1,选择读模式
- EN=0; // 执行显示命令
- EN=1; // 允许读/写
- }
- while(busy); //busy为高电平表示忙,循环等待
- }
- //-------------------------------------- 写命令函数 -----------------------------------
- WR_COMM() //写命令
- {
- RS=0; // RS=0,选择指令寄存器
- RW=0; // RW=0,选择写模式
- EN=0; // 执行显示命令
- CHECK_BF(); // 等待
- EN=1; // E=1,允许读/写LCD
- }
- //-------------------------------------- 写数据函数 -------------------------------------
- WR_DATA() //写数据
- {
- RS=1; // RS=1,选择数据寄存器
- RW=0; //准备写入数据
- EN=0; //执行显示命令
- CHECK_BF(); //判断液晶模块是否忙
- EN=1; // E=1,允许读/写LCD
- }
- //--------------------------------------- 初始化函数 ----------------------------------
- INIT_LCD() //初始化
- {
- unsigned char i=200;
- {
- while(--i);
- LCD=0x01; //清屏并光标复位
- WR_COMM(); //写入命令
- LCD=0x38; //设置显示模式:8位2行5x7点阵
- WR_COMM();
- LCD=0x0c; //开显示屏
- WR_COMM();
- LCD=0x06; //文字不动,光标自动右移
- WR_COMM(); //写入命令
- }
- }
-
- //-------------------------------- 显示温度标记字符C函数 ----------------------------
-
- TEMP_BJ() //显示字符C
- {
- LCD=0xce; //写入显示起始地址
- WR_COMM(); //写入命令
- LCD=('C' );
- WR_DATA(); //送出
- }
-
- //----------------------------------- 自定义温度标志符函数 --------------------------------
- STORE_DATA()
- {
- unsigned char i;
- LCD=0x40; // 指定CG RAM起始地址
- WR_COMM(); //写入命令
- for(i=0;i<9;i++)
- {
- LCD=TAB1[i]; //提取字符
- WR_DATA(); //送出
- }
- LCD=0xcd; //写入显示起始地址
- WR_COMM(); //写入命令
- LCD=0x00; //CGRAM内第0号图形
- WR_DATA(); //写入数据
-
- TEMP_BJ();
-
- }
-
- //------------------------------------------- DS18B20初始化函数 --------------------------------------
- bit INIT_1820(void)
- {
- bit flag; //flag为标志符
- DQ = 1; //DQ复位
- delay(3); //稍作延时
- DQ = 0; //将数据线从高拉低,保持480~960us
- delay(80);
- DQ = 1; //释放数据线
- delay(10);
- flag=DQ; //DQ=0表示存在
- delay(25);
- return (flag); //返回检测标志
- }
- //------------------------------------------ 读出DS18B20函数 ----------------------------------------
- unsigned char READ_1820(void)
- {
- unsigned char i=0;
- unsigned char dat; //储存读出的一个字节数据
- for (i=0;i<8;i++)
- {
- DQ =1; //将数据线拉高
- DQ = 0; //将数据线从高拉低,启动读时序
- dat>>=1;
- DQ = 1; //将数据线拉高,为输出电平作准备
- _nop_();
- if(DQ==1)
- dat|=0x80; //读数据,存入dat
- else
- dat|=0x00; //读数据,存入dat
- delay(3);
- }
- return(dat); //返回读出的十进制数据
- }
- //--------------------------------------------- 写入DS18B20函数 ---------------------------------------------
- WRITE_1820(unsigned char dat)
- {
- unsigned char i=0;
- for (i=0; i<8; i++)
- {
- DQ =1; // 先将数据线拉高
- DQ=0; //数据线从高拉低,开始写入
- DQ=dat&0x01; //利用与运算取出要写的某位二进制数据,
- delay(3);
- DQ=1; //释放数据线
- _nop_();
- dat>>=1; //将dat中的各二进制位数据右移1位
- }
- delay(3);
- }
- //---------------------------------------- 显示错误信息函数 ------------------------------------------
- void DISP_ERR(void)
- {
- unsigned char i;
-
- LCD=0x80; //写显示地在第1行第1列
- WR_COMM();
- i = 0; //从第一个字符开始显示
- while(Error[i] != '\0') //写到结束标志
- {
- LCD=(Error[i]); //将字符常量写入LCD
- WR_DATA();
- i++; //指向下一个字符
- delay(1000); //延时
- }
- while(1); //循环,等待查明原因
- }
- //-------------------------------------- 显示温度的小数点 ------------------------------------------
-
- void DISP_D(void)
- {
-
- LCD=0xc9; //写显示地址在第2行第10列
- WR_COMM();
- LCD=('.');
- WR_DATA();
- delay(200); //延时一点时间
- }
- //------------------------------------------ 显示TEMP字符函数 ------------------------------------------------
-
- void DISP_TEMP(void)
-
- {
- unsigned char i;
- LCD=0xc0; //写入显示起始地址
- WR_COMM(); //写入命令
- for(i=0;i<5;i++)
- {
- LCD=TEMP[i]; //提取字符
- WR_DATA(); //送出
- }
- }
-
- //------------------------------------------- 显示菜单函数 --------------------------------------------
- DISP_EXP( )
- {
- unsigned char i;
- LCD=0x83; //写入显示起始地址
- WR_COMM(); //写入命令
- for(i=0;i<11;i++)
- {
- LCD=TAB2[i]; //提取字符
- WR_DATA(); //送出
- }
- DISP_TEMP();
- DISP_D();
- }
-
- //---------------------------------------------- 读温度函数 -----------------------------------------
- RE_TEMP()
- {
- unsigned char time;
- INIT_1820(); //将DS18B20初始化
- WRITE_1820(0xCC); // 跳过读序号列号的操作
- WRITE_1820(0x44); // 启动温度转换
- for(time=0;time<100;time++);
- INIT_1820(); //将DS18B20初始化
- WRITE_1820(0xCC); //跳过读序号列号的操作
- WRITE_1820(0xBE); //读取温度的低位和高位
- }
-
- //------------------------------------------ 显示温度正负的符号 ---------------------------------------
-
- void DISP_ZF(unsigned char fuhao)
- {
- unsigned char show;
- show=fuhao;
- LCD=0xc5; //写显示地址在第2行第10列
- WR_COMM();
- LCD=(show); //将小数点的字符常量写入LCD
- WR_DATA();
- delay(200); //延时一点时间
- }
-
- //---------------------------------------- 显示温度的整数部分函数 ----------------------------------------
- void DISP_TEMP1(unsigned char x)
- {
- unsigned char j,k,l; //j,k,l分别储存温度的百位、十位和个位
- j=x/100; //取百位
- k=(x%100)/10; //取十位
- l=x%10; //取个位
- LCD=0xc6; //写显示地址在第2行第7列
- WR_COMM();
- LCD=(digit[j]);
- WR_DATA();
- LCD=0xc7;
- WR_COMM();
- LCD=(digit[k]);
- WR_DATA();
- LCD=0xc8;
- WR_COMM();
- LCD=(digit[l]);
- WR_DATA();
- delay(200); //延时一点时间
- }
- //---------------------------------------- 显示温度的小数数部分函数 -----------------------------------------
- void DISP_TEMP2(unsigned char x)
- {
- LCD=0xca; //写显示地址在第2行第11列
- WR_COMM();
- LCD=(digit[x]);
- WR_DATA(); //将小数部分写入LCD
- delay(200); //延时一点时间
- }
- //---------------------------------------- 温度数据转换显示函数 -------------------------------------------
-
- void CONV_TEMP(void)
- {
- unsigned char TL; //储存温度低位
- unsigned char TH; //储存温度高位
- unsigned char TN; //储存整数部分
- unsigned char TD; //储存小数部分
-
- while(1) //不断检测显示温度
- {
- RE_TEMP(); //读温度函数
- //-------------------
- TL=READ_1820(); //先读温度值低位
- TH=READ_1820(); //接着读温度值高位
- if(TH>=0xf8)
- {
- DISP_ZF('-');
- if(TL==0)
- {
- TH=(~TH+1)&0x03;
- TN=TH*16+TL/16;
- TD=(TL%16)*10/16;
- goto loopshow;
- }
-
- TH=~TH&0x03;
- TL=~TL+1;
- TN=TH*16+TL/16;
- TD=(TL%16)*10/16;
- goto loopshow;
- }
- DISP_ZF('+');
- TN=TH*16+TL/16; //计算温度值整数部分
- TD=(TL%16)*10/16; //计算温度的小数部分
- loopshow:
- //------------------------
- DISP_TEMP1(TN); //显示温度的整数部分
- DISP_TEMP2(TD); //显示温度的小数部分
- delay(100);
- }
- }
- //---------------------------------------- 主函数 ----------------------------------------------
- void main(void)
- {
- INIT_LCD(); //LCD初始化函数
- delay(100);
- if(INIT_1820()==1) //DS18B20初始化函数
- DISP_ERR(); //显示错误信息函数
- STORE_DATA(); //自定义温度标志符函数
- DISP_EXP(); //显示菜单函数
- CONV_TEMP(); //温度数据转换显示函数
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
该系列源码包含有很多非常经典,代码风格十分规范,而且注释详细的单片机例程,还带仿真,对于MCU学习特别是初学者是很有帮助的,全部源码下载(共25个项目):http://www.51hei.com/bbs/dpj-79328-1.html
本例程下载(含proteus仿真工程文件与源码):
单片机LCD1602温度计实验.rar
(76.76 KB, 下载次数: 291)
|
评分
-
查看全部评分
|