51(52)单片机 DS18B20温度传感器与LCD1602液晶显示屏的综合使用
单片机小白
第一行向左滚动
第二行固定不动
右下角笑脸顺时针旋转一周,第一行向左滚动一个字符,且温度刷新一次
单片机存储空间不同,u8 a[16+sizeof(str)+16] 处可能会报溢出,改成
u8 pdata a[16+sizeof(str)+16] 就行
pdata:外部扩展RAM的低256个字节
运行效果:
为动态滚动效果,以下为截图
主函数main.c:
#include <reg52.h>
#include "ds18b20.h"
#include "lcd1602.h"u8 code cg_addr[]={0x40,0x48,0x50,0x58,0x60,0x68,0x70,0x78};//其中八个CGRom的地址u8 code read_cg[]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07};//以上八个CGRom的编号u8 code user[][8]={{0x1F,0x0A,0x0A,0x1F,0x0A,0x0A,0x12,0x02}, //开{0x00,0x00,0x00,0x00,0x00,0x02,0x06,0x00}, //心{0x00,0x00,0x04,0x01,0x10,0x11,0x1F,0x00},{0x07,0x05,0x07,0x00,0x00,0x00,0x00,0x00} //摄氏度的点};u8 code xiao[][8]={{0x03,0x04,0x0A,0x08,0x0A,0x09,0x04,0x03}, //变幻左部笑脸{0x03,0x04,0x09,0x0A,0x0A,0x09,0x04,0x03},{0x03,0x04,0x09,0x0A,0x08,0x0A,0x04,0x03},{0x03,0x04,0x0A,0x08,0x08,0x0A,0x04,0x03},{0x18,0x04,0x0A,0x02,0x0A,0x12,0x04,0x18}, //变幻右部笑脸{0x18,0x04,0x0A,0x02,0x02,0x0A,0x04,0x18},{0x18,0x04,0x12,0x0A,0x02,0x0A,0x04,0x18},{0x18,0x04,0x12,0x0A,0x0A,0x12,0x04,0x18}};u8 code str[]="tempereture :";//自定义图形函数
/*思路是1.选中一个CGRAM(地址)01 ... ... 设置第3.4.5位选中前8个CGROM设置低三位选CGRAM的8行像素点(文章用的是设置初地址然后for(...8...)循环选中)2.向CGRAM填充图形(字符型为5*7,高电平亮)先填充行,自上而下依次重复操作0x1.. .....(8421 8421码)例如 dian[] = {0x07,0x05,0x07,0x00,0x00,0x00,0x00,0x00}只有低5位有效0x07=000 00111代表第一行的从右自左的第1.2.3个像素点亮 0 0 00x05=000 00101代表第一行的从右自左的第1.3个像素点亮 0 00x07=000 00111代表第三行的从右自左的第1.2.3个像素点亮 0 0 03.设置要显示的位置4。从相应的CGRAM中取出自定义图形显示 ( 0000 0000 设置低三位选中前八个CGRAM编码)
*/
void user_xie(u8 x,u8 y,u8 cg,u8 *User)
{u8 i;LcdWriteCmd(cg_addr[cg]); //设定 CGRAM 地址for(i=0;i<8;i++ ){LcdWriteData(User[i]); //写入自定义图形}LcdSetCursor(x,y); //显示的位置,x为列,y为行LcdWriteData(read_cg[cg]); //从 CGRAM 里取出自定义图形显示}//延时函数
//主要是引脚P2^5与蜂鸣器共用,不设置一下太吵人了
void delay_ds(unsigned short ms){u8 T;while(ms--){for(T=0;T<250;T++);}}void xiao_xz() //笑脸旋转+延时(相当于四帧动画)
{user_xie(14,1,5,xiao[0]);user_xie(15,1,6,xiao[4]);delay_ds(125);user_xie(14,1,5,xiao[1]);user_xie(15,1,6,xiao[5]);delay_ds(100);user_xie(14,1,5,xiao[2]);user_xie(15,1,6,xiao[6]);delay_ds(100);user_xie(14,1,5,xiao[3]);user_xie(15,1,6,xiao[7]);delay_ds(100);
}//主函数
void main()
{u8 a[16+sizeof(str)+16]; //为数组a定义空间,前16位与后十六位均为空字符,中间为要显示的字符串//这里不能用strlen,sizeof为运算符,strlen为函数u8 df[8];s16 qw;u8 i,j,index;i=j=index=0;InitLcd1602(); //lcd1602初始化for(i=0;i<16;i++) //前16位与后十六位均为空字符,中间为要显示的字符串a[i]= ' ';for(i=0;i<(sizeof(str)-1);i++)a[16+i]=str[i];for(i=(16+sizeof(str)-1);i<sizeof(a);i++)a[i]= ' ';while(1){ qw=datapros(DS18B20temp_data()); //DS18B20温度数据tostring(df,qw); //数字转字符串函数,添加小数点(保留一位小数)LcdShowStr(11,1,"C"); //从CGROM中选中相应字符显示user_xie(0,1,0,user[0]); //自定义图形函数user_xie(1,1,1,user[1]);user_xie(2,1,2,user[2]);user_xie(10,1,3,user[3]); if(j==0) //开机画面{LcdShowStr(5,1,"....");LcdShowStr(0,0,"Make By LuDeYue!");user_xie(14,1,5,xiao[0]);user_xie(15,1,6,xiao[4]);delay_ds(450);}j-=1;LcdShowStr_Shift(0,0,a+index,16); /*滚动显示函数,lcd的列数为16,所以每次只能选取16位字符进行显示a+index类似指针(a为初地址,index为偏移量),指向所偏移的地址后向后取15个(从指向地址处算共16个)字符出来显示*/index++;//显示一次后指向下一处地址,同理可更改为向右滚动if(index>=(16+sizeof(str)-1))//如果字符串已全部左移的话(显示后16个空字符)置零,重新开始{index=0;}LcdShowStr(5,1,df); //温度数据显示xiao_xz(); //笑脸旋转+延时}
}
ds18b20.h:
#include <reg52.h>
#include <intrins.h>#define u8 unsigned char
#define u16 unsigned int
#define s16 signed intsbit IO_18B20=P3^7;u8 DQ;void Delay(u16 i)//延时
{while(i--);
}void init_18B20()//DS18B20初始化
{IO_18B20=0;Delay(100); IO_18B20=1;Delay(5); DQ=IO_18B20;Delay(80); }void write_cmd(u8 cmd)//DS18B20写时序
{u8 i;for(i=0;i<8;i++){IO_18B20=0;_nop_(); IO_18B20=cmd&0x01;Delay(6); IO_18B20=1;cmd>>=1;}}u8 read_cmd()//DS18B20读时序
{u8 j,by,byte;for(j=0;j<8;j++){IO_18B20=0;_nop_(); IO_18B20=1;_nop_(); _nop_(); by=IO_18B20;byte=(byte>>1)|(by<<7);Delay(4); }return byte;}void change_temper()//温度转换
{init_18B20();if(DQ==0){write_cmd(0xcc);//跳过ROMwrite_cmd(0x44);//温度转换后存储在暂存寄存器的2个字节长度的温度寄存器中}}void read_temper()//读温度
{init_18B20();if(DQ==0){write_cmd(0xcc);//跳过ROMwrite_cmd(0xbe);//读取暂存寄存器}
}s16 DS18B20temp_data()//采集DS18B20中cache温度数据
{s16 temp;u8 temph,templ;change_temper();read_temper();templ=read_cmd();temph=read_cmd();temp=temph;temp<<=8;temp|=templ;return temp;}s16 datapros(s16 temp)//将采集的数据按照规定的分辨率转化为数字
{s16 tp;if(temp<0){ temp=~temp;temp+=1;tp=temp;temp=tp*0.0625*10+0.5;}else{tp=temp;temp=tp*0.0625*10+0.5; //0.0625为分辨率 10:保留一位小数 0.5:精度}return temp;}
lcd1602.h:
#include <reg52.h>
#include <intrins.h>#define LCD1602_DB P0sbit LCD1602_RW=P2^5;sbit LCD1602_RS=P2^6;sbit LCD1602_E=P2^7;//lcd1602忙闲状态判断
void LcdWaitReady()
{u8 sta;LCD1602_DB=0xFF;LCD1602_RS=0;LCD1602_RW=1;do{LCD1602_E=1;sta=LCD1602_DB;LCD1602_E=0;}while(sta&0x80);}//写命令
void LcdWriteCmd(u8 cmd)
{LcdWaitReady();LCD1602_RS=0;LCD1602_RW=0;LCD1602_DB=cmd;LCD1602_E=1;LCD1602_E=0;}//写数据(1602字符输入(CGROM固定字库))
void LcdWriteData(u8 dat)
{LcdWaitReady();LCD1602_RS=1;LCD1602_RW=0;LCD1602_DB=dat;LCD1602_E=1;LCD1602_E=0;}//lcd1602初始化
void InitLcd1602()
{LcdWriteCmd(0x38); //功能设置命令 LcdWriteCmd(0x38); //有时候LCD1602不听话,只显示一行,那就在说几次 LcdWriteCmd(0x0C); //显示开/关及光标设置 、LcdWriteCmd(0x06); //显示模式设置LcdWriteCmd(0x01); //清屏指令}//显示的位置设置
void LcdSetCursor(u8 x,u8 y)//x为列,y为行
{u8 addr;if(y==0)addr=0x80+x;//第一行elseaddr=0xC0+x;//第二行LcdWriteCmd(addr);}//显示
void LcdShowStr(u8 x,u8 y,u8 *str)
{LcdSetCursor(x,y);while(*str!='\0'){LcdWriteData(*str++);}}//滚动的显示
void LcdShowStr_Shift(u8 x,u8 y,u8 *str,u8 len)
{LcdSetCursor(x,y);while(len--){LcdWriteData(*str++);}
}void tostring(u8 *str, int dat)//数字转字符串并添加小数点
{signed char i = 0;u8 buf[6];if (dat < 0) {dat = -dat;*str++ = '-';}do { buf[i++] = dat % 10;dat /= 10;} while (dat > 0);while (i-- > 0) { if(i==0){*str++='.';*str++ = buf[i] + '0';} else*str++ = buf[i] + '0';}*str = '\0'; }
51(52)单片机 DS18B20温度传感器与LCD1602液晶显示屏的综合使用相关推荐
- 51单片机~DS18B20温度传感器
51单片机~DS18B20温度传感器 (一)简介说明: (二)接线: 1. 内部结构: 正温度前五位是0. 负温度前五位是1. 由LS,MS组成的四位十六进制数,和16位二进制数.(先MS后LS) 结 ...
- 51单片机DS18B20温度传感器及数码管显示温度
51单片机DS18B20温度传感器及数码管显示温度 大家好,今天给大家带来的代码及原理解释是,在51单片机在接收DS18B20温度传感器数据,并且在数码管上实时显示温度 DS18B20及数码管显示温度 ...
- 实物1操作:stc8a单片机和普通51/52单片机的异同以及下载步骤(点亮一盏LED为例)
1.stc8a系列单片机,比普通的51/52单片机运行速度快: stc8a单片机是1T单片机,普通的51/52单片机,比如stc89c82RC等单片机是12T单片机. 1T和12T单片机是什么意思呢? ...
- AutoLeaders控制组——51单片机学习笔记(DS18B20温度传感器、LCD1602、直流电机+PWM)
本篇内容是观看B站江科大自化协UP主的教学视频所做的笔记,对其中内容有所引用,并结合自己的单片机板块进行了更改调整. 以下笔记内容以一个视频为一个片段(内容较多,可能不适合速食,望见谅) 一些内容涉及 ...
- 51单片机DS18B20温度传感器使用及数码管温度计、LCD1602温度显示代码详解
温馨提示:读者若要彻底理解并会灵活使用DS18B20温度传感器,请详细阅读中文手册,并且对照代码注释充分分析代码.请不要觉得中文手册内容繁多!如能静心分析,定能深有体会,获益匪浅! 一.DS18B20 ...
- 51单片机 | DS18B20 温度传感器实验
文章目录 一.DS18B20介绍 二.硬件设计 三.软件设计 1.数码管显示函数 2.DS18B20 初始化函数及温度读取函数 4.主函数 四.实验现象 这一节我们来学习精度较高的外部 DS18B ...
- 基于C51单片机+DS18B20温度传感器+LCD1602显示器的智能水温控制系统(PID)
基于AT89C52的温度控制系统 一.DS18B20传感器相关介绍 DS18B20特性 封装形式与引脚说明 供电方式(外部电源供电.寄生电源供电.寄生电源强上拉) DS18B20指令(ROM指令操作) ...
- 4.5 51单片机-DS18B20温度传感器
4.5 DS18B20温度传感器 4.5.1 原理图介绍 图4-5-1 图4-5-2 实验板上的DS18B20模块接在单片机的P3.5 IO口上,在插入DS18B20芯片时,圆弧朝上插入,具体效果可以 ...
- 51单片机DS18B20温度传感器详解
DS18B20是一种单总线数字温度传感器,测试温度范围-55℃-125℃,具有体积小,硬件开销低,抗干扰能力强,精度高的特点.单总线,意味着没有时钟线,只有一根通信线.单总线读写数据是靠控制起始时间和 ...
最新文章
- 把button伪装成超链接
- php学习之Model类
- Python爬虫(十一)_案例:使用XPath的爬虫
- nginx 学习笔记(6) nginx配置文件中的度量单位
- CentOS 6.9 搭建 Presto
- mysql为字段值添加或者去除前缀、后缀(查询字段拼值)
- 推荐算法--利用用户行为数据(02)
- Android Camera (13)---MTK平台相机插值修改
- IOS开发学习笔记027-UITableView 使用模型对象
- 如何解决苹果Mac安装Ps错误代码182?
- Solaris 10的第二次更新要点
- 字节跳动 Go 语言面试高频题
- elementui二维表动态渲染
- 华为P40与周冬雨排列
- linux学习日志,linux学习日记范文
- android 文本倒影,Android 生成倒影图片
- 九麟SDK 接入文档
- html实现微信扫一扫,JS 实现微信扫一扫功能
- PDF转Word,Word转PDF
- 成本低廉的深度学习与渲染显卡购买方案--英伟达矿卡P106