标题:
单片机ds18b20测温oled显示程序
[打印本页]
作者:
孙文超
时间:
2020-12-20 17:00
标题:
单片机ds18b20测温oled显示程序
D0 P0.0
D1 P0.1
RES P0.2
DC P0.3
CS P0.4
DS18B20 P0.7
80F86B74AD9ED0C058A20CAC2B3CA4CA.jpg
(218.1 KB, 下载次数: 59)
下载附件
2020-12-20 17:00 上传
单片机源程序如下:
#include<reg52.h>
#define u8 unsigned char
#define u32 unsigned int
sbit DQ = P0^7;
sbit CS=P0^4; //片选
sbit RST =P0^2;//复位
sbit DC =P0^3;//数据/命令控制
sbit SCL=P0^0;//时钟 D0(SCLK?
sbit SDIN=P0^1;//D1(MOSI) 数据
u8 TempData[7]; //温度存储显示值
bit ReadTempFlag; //读时间标志
void WriteOneChar(u8 dat); //写入DS18B20一个字节
u8 ReadOneChar(void); //读取DS18B20一个字节
u32 ReadTemperature(void); //读取DS18B20温度值
bit Init_DS18B20(void); //初始化DS18B20
void Time0(void); //定时器初始化
void Delay2us(u8 t); //2微秒延时函数
void Delay1ms(u8 t); //1毫秒延时函数
void OLED_Init(); //设置显示模式
void delay100us(u32 x); //100us延时程序
unsigned char code Hzk[][32]={
{0x10 ,0x22, 0x64 ,0xC ,0x80, 0x0 ,0xFE, 0x92, 0x92, 0x92 ,0x92, 0x92 ,0xFF ,0x2 ,0x0, 0x0 }, /* wen */
{0x4, 0x4, 0xFE, 0x1, 0x40, 0x7E, 0x42 ,0x42 ,0x7E, 0x42, 0x7E, 0x42, 0x42, 0x7E, 0x40, 0x0}, /*1*/
{0x0, 0x0, 0xFC, 0x24 ,0x24, 0x24 ,0xFC ,0xA5 ,0xA6, 0xA4 ,0xFC, 0x24, 0x34, 0x26, 0x4, 0x0}, /* du */
{0x40 ,0x20, 0x9F, 0x80, 0x42, 0x42, 0x26, 0x2A, 0x12, 0x2A, 0x26, 0x42, 0x40, 0xC0, 0x40, 0x0}, /*2*/
{0x0, 0x0 ,0x0 ,0x0, 0x80, 0xC0 ,0xC0, 0x80 ,0x0, 0x0 ,0x0 ,0x0, 0x0, 0x0, 0x0, 0x0}, /* : */
{0x0, 0x0, 0x0, 0x0, 0x31 ,0x7B, 0x7B ,0x31, 0x0 ,0x0, 0x0, 0x0 ,0x0 ,0x0, 0x0, 0x0}, /*3*/
};
unsigned char code Sz[][32]={
{0x0, 0x0 ,0xC0 ,0xE0 ,0xF0 ,0x18 ,0x8, 0x8 ,0x8, 0x8 ,0x8, 0x30, 0xF0, 0xE0, 0xC0, 0x0},
{0x0 ,0x0 ,0x7, 0x1F, 0x1F, 0x30, 0x20 ,0x20, 0x20 ,0x20 ,0x20, 0x38, 0x1F ,0xF ,0x7, 0x0},
{0x0 ,0x0, 0x0 ,0x0 ,0x10, 0x10 ,0x10, 0xF0, 0xF8, 0xF8, 0x0 ,0x0, 0x0, 0x0 ,0x0, 0x0},
{0x0 ,0x0 ,0x0, 0x0, 0x20, 0x20 ,0x20 ,0x3F, 0x3F, 0x3F, 0x20, 0x20, 0x20, 0x0, 0x0, 0x0},
{0x0, 0x0, 0x20, 0x70 ,0x78, 0x8, 0x8 ,0x8, 0x8, 0x8 ,0x8 ,0xD8, 0xF0, 0x70, 0x0 ,0x0},
{0x0 ,0x0 ,0x30 ,0x30, 0x28 ,0x28 ,0x24 ,0x24, 0x22, 0x22, 0x21, 0x21, 0x30, 0x38, 0x0, 0x0},
{0x0, 0x0, 0x20, 0x30, 0x38, 0x0, 0x8 ,0x8, 0x8, 0x88, 0x88, 0xF8, 0x70, 0x20, 0x0 ,0x0},
{0x0, 0x0, 0x18, 0x18, 0x38 ,0x20 ,0x20, 0x21, 0x21 ,0x21 ,0x21 ,0x33 ,0x1E, 0x1E ,0x0 ,0x0},
{0x0 ,0x0, 0x0, 0x0 ,0x0, 0x80, 0x40, 0x20, 0x20, 0xF0, 0xF8 ,0xF8, 0x0, 0x0, 0x0, 0x0},
{0x0, 0x0, 0x6 ,0x2, 0x1, 0x0, 0x0 ,0x20, 0x20 ,0x3F ,0x3F, 0x3F, 0x20, 0x20 ,0x20, 0x0},
{0x0, 0x0, 0x0, 0xF8, 0xF8, 0x88, 0x88 ,0x88, 0x88, 0x88 ,0x88 ,0x88, 0x8 ,0x8, 0x0, 0x0},
{0x0, 0x0, 0x18, 0x19, 0x39 ,0x20 ,0x20, 0x20 ,0x20 ,0x20 ,0x20, 0x31 ,0x1F, 0xF, 0x4, 0x0},
{0x0, 0x0, 0xC0, 0xE0, 0xF0, 0x10, 0x88 ,0x88, 0x88, 0x88, 0x88, 0x98, 0x98, 0x10, 0x0, 0x0},
{0x0 ,0x0 ,0xF ,0x1F, 0x1F, 0x31, 0x20 ,0x20 ,0x20, 0x20 ,0x20 ,0x21 ,0x1F, 0x1F ,0xE, 0x0},
{0x0, 0x0, 0x20, 0x38, 0x18, 0x8 ,0x8, 0x8, 0x8 ,0x88 ,0xC8, 0x28, 0x18 ,0x18, 0x8 ,0x0},
{0x0 ,0x0, 0x0, 0x0, 0x0, 0x0, 0x3C, 0x3E, 0x3F ,0x1 ,0x0 ,0x0, 0x0, 0x0, 0x0, 0x0},
{0x0, 0x0, 0x60, 0x70, 0xD8, 0x88, 0x88, 0x88, 0x88 ,0x8, 0x88, 0x88, 0xF0, 0x70, 0x0, 0x0 },
{0x0 ,0x8 ,0x1C ,0x1E, 0x23 ,0x21, 0x21, 0x21, 0x21, 0x21, 0x23, 0x23, 0x1E, 0x1C, 0x8, 0x0},
{0x0, 0x40, 0xE0, 0xF0, 0x18, 0x8, 0x8, 0x8, 0x8 ,0x8, 0x8, 0x18 ,0xF0, 0xE0, 0xC0, 0x0},
{0x0 ,0x0, 0x1, 0x31, 0x33, 0x32, 0x22, 0x22 ,0x22, 0x22, 0x33 ,0x1D ,0xF, 0x7 ,0x3, 0x0},
};
void delay_ms(unsigned int ms)
{
unsigned int a;
while(ms)
{
a=1800;
while(a--);
ms--;
}
return;
}
void OLED_WR_Byte(u8 dat,u8 cmd)
{
u8 i;
if(cmd)
DC=1;
else
DC=0;
CS=0;
for(i=0;i<8;i++)
{
SCL=0;
if(dat&0x80)
{
SDIN=1;
}
else
SDIN=0;
SCL=1;
dat<<=1;
}
CS=1;
DC=1;
}
void OLED_Clear(void)
{
u8 i,n;
for(i=0;i<8;i++)
{
OLED_WR_Byte (0xb0+i,0); //设置页地址(0~7)
OLED_WR_Byte (0x00,0); //设置显示位置—列低地址
OLED_WR_Byte (0x10,0); //设置显示位置—列高地址
for(n=0;n<128;n++)OLED_WR_Byte(0,1);
} //更新显示
}
void OLED_Set_Pos(unsigned char x, unsigned char y)
{
OLED_WR_Byte(0xb0+y,0);
OLED_WR_Byte(((x&0xf0)>>4)|0x10,0);
OLED_WR_Byte((x&0x0f)|0x01,0);
}
void OLED_ShowCHinese(u8 x,u8 y,u8 no)
{
u8 t,adder=0;
OLED_Set_Pos(x,y);
for(t=0;t<16;t++)
{
OLED_WR_Byte(Hzk[2*no][t],1);
adder+=1;
}
OLED_Set_Pos(x,y+1);
for(t=0;t<16;t++)
{
OLED_WR_Byte(Hzk[2*no+1][t],1);
adder+=1;
}
}
void OLED_Showshuzi(u8 m,u8 n,u8 su)
{
u8 p,adder=0;
OLED_Set_Pos(m,n);
for(p=0;p<16;p++)
{
OLED_WR_Byte(Sz[2*su][p],1);
adder+=1;
}
OLED_Set_Pos(m,n+1);
for(p=0;p<16;p++)
{
OLED_WR_Byte(Sz[2*su+1][p],1);
adder+=1;
}
}
void OLED_Init(void)
{
RST=1;
delay_ms(100);
RST=0;
delay_ms(100);
RST=1;
OLED_WR_Byte(0xAE,0);//--turn off oled panel
OLED_WR_Byte(0x00,0);//---set low column address
OLED_WR_Byte(0x10,0);//---set high column address
OLED_WR_Byte(0x40,0);//--set start line address Set Mapping RAM Display Start Line (0x00~0x3F)
OLED_WR_Byte(0x81,0);//--set contrast control register
OLED_WR_Byte(0xCF,0); // Set SEG Output Current Brightness
OLED_WR_Byte(0xA1,0);//--Set SEG/Column Mapping 0xa0左右反置 0xa1正常
OLED_WR_Byte(0xC8,0);//Set COM/Row Scan Direction 0xc0上下反置 0xc8正常
OLED_WR_Byte(0xA6,0);//--set normal display
OLED_WR_Byte(0xA8,0);//--set multiplex ratio(1 to 64)
OLED_WR_Byte(0x3f,0);//--1/64 duty
OLED_WR_Byte(0xD3,0);//-set display offset Shift Mapping RAM Counter (0x00~0x3F)
OLED_WR_Byte(0x00,0);//-not offset
OLED_WR_Byte(0xd5,0);//--set display clock divide ratio/oscillator frequency
OLED_WR_Byte(0x80,0);//--set divide ratio, Set Clock as 100 Frames/Sec
OLED_WR_Byte(0xD9,0);//--set pre-charge period
OLED_WR_Byte(0xF1,0);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
OLED_WR_Byte(0xDA,0);//--set com pins hardware configuration
OLED_WR_Byte(0x12,0);
OLED_WR_Byte(0xDB,0);//--set vcomh
OLED_WR_Byte(0x40,0);//Set VCOM Deselect Level
OLED_WR_Byte(0x20,0);//-Set Page Addressing Mode (0x00/0x01/0x02)
OLED_WR_Byte(0x02,0);//
OLED_WR_Byte(0x8D,0);//--set Charge Pump enable/disable
OLED_WR_Byte(0x14,0);//--set(0x10) disable
OLED_WR_Byte(0xA4,0);// Disable Entire Display On (0xa4/0xa5)
OLED_WR_Byte(0xA6,0);// Disable Inverse Display On (0xa6/a7)
OLED_WR_Byte(0xAF,0);//--turn on oled panel
OLED_WR_Byte(0xAF,0); /*display ON*/
OLED_Clear();
OLED_Set_Pos(0,0);
}
void main()
{
u32 temp,i,j;
long tempM;
u8 TempH;
Time0(); //定时器初始化
OLED_Init(); //设置显示模式
while(1)
{
if(ReadTempFlag==1) //定时标志
{
ReadTempFlag=0;
temp=ReadTemperature();//读取温度
tempM=temp*0.0625*100; //换算为10进制温度值再放大100倍 12位精度直接乘0.625
TempH=tempM/100; //取整数
i=(TempH%100)/10; //显示十位温度
j=(TempH%100)%10; //显示个位温度
// k=TempL/10; //显示温度小数1位
OLED_ShowCHinese(0,0,0);
OLED_ShowCHinese(18,0,1);
OLED_ShowCHinese(36,0,2);
OLED_Showshuzi(54,0,0);
OLED_Showshuzi(72,0,i);
OLED_Showshuzi(90,0,j);
OLED_ShowCHinese(108,0,1);
}
}
}
/*------------------------------------------------
定时器初始化子程序
------------------------------------------------*/
void Time0(void)
{
TMOD = 0x01; //使用模式1,16位定时器
TH0=(65536-5000)/256; //给定初值,定时5ms
TL0=(65536-5000)%256;
EA=1; //总中断打开
ET0=1; //定时器中断打开
TR0=1; //定时器T0开关打开
}
/*------------------------------------------------
定时器中断子程序
------------------------------------------------*/
void Time0r(void) interrupt 1
{
static u32 num; //局部变量定义
TH0=(65536-5000)/256; //重新赋值 5ms
TL0=(65536-5000)%256;
num++;
if(num>=25)
{
num = 0;
ReadTempFlag=1; //读标志位置1
}
}
void Delay2us(u8 t)
{
while(--t);
}
void Delay1ms(u8 t)
{
while(t--)
{
//大致延时1mS
Delay2us(245);
Delay2us(245);
}
}
/*------------------------------------------------
18b20初始化
------------------------------------------------*/
bit Init_DS18B20(void)
{
bit dat=0;
DQ = 1; //DQ复位
Delay2us(5); //稍做延时
DQ = 0; //单片机将DQ拉低
Delay2us(200); //精确延时 大于 480us 小于960us
Delay2us(200);
DQ = 1; //拉高总线
Delay2us(50); //15~60us 后 接收60-240us的存在脉冲
dat=DQ; //如果x=0则初始化成功, x=1则初始化失败
Delay2us(25); //稍作延时返回
return dat;
}
/*------------------------------------------------
读取一个字节
------------------------------------------------*/
u8 ReadOneChar(void)
{
u8 i=0;
u8 dat = 0;
for (i=8;i>0;i--)
{
DQ = 0; // 给脉冲信号
dat>>=1;
DQ = 1; // 给脉冲信号
if(DQ)
dat|=0x80;
Delay2us(25);
}
return(dat);
}
/*------------------------------------------------
写入一个字节
------------------------------------------------*/
void WriteOneChar(u8 dat)
{
u8 i=0;
for(i=8; i>0; i--)
{
DQ = 0;
DQ = dat&0x01;
Delay2us(25);
DQ = 1;
dat>>=1;
}
Delay2us(25);
}
/*------------------------------------------------
读取温度
------------------------------------------------*/
u32 ReadTemperature(void)
{
u8 a=0;
u32 b=0;
u32 t=0;
Init_DS18B20();
WriteOneChar(0xCC); // 跳过读序号列号的操作
WriteOneChar(0x44); // 启动温度转换 44H开启温度转换
Delay1ms(10);
Init_DS18B20();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
a=ReadOneChar(); //低位
b=ReadOneChar(); //高位
b<<=8;
t=a+b;
return(t);
}
/*******100us延时程序********/
void delay100us(u32 x)
{
u32 a,b;
for(a=x;a>0;a--)
for(b=10;b>0;b--);
}
复制代码
所有程序51hei提供下载:
新建文件夹.rar
(41.09 KB, 下载次数: 54)
2020-12-20 17:00 上传
点击文件名下载附件
下载积分: 黑币 -5
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1