标题:
基于单片机1602温度计实验源码
[打印本页]
作者:
和路雪
时间:
2017-10-24 14:21
标题:
基于单片机1602温度计实验源码
这时我做的关于1602显示其 的相关实验。可以通过单片机读取相关的温度以及序码。
一个是关于温度显示的源代码,一个是可以切换的实验结果。
单片机源程序如下:
/**********************BST-V51实验开发板例程************************
* 平台:BST-V51 + Keil U3 + STC89C52
* 名称:18B20实时温度计1602显示
* 晶振:11.0592MHZ
* 说明:免费开源,不提供源代码分析.
******************************************************************/
#include <reg52.H>
#include <intrins.H>
#include <math.H>
#define uchar unsigned char
#define uint unsigned int
#define GPIO_KEY P3 //独立键盘用P1口
sbit dula = P2^6;
sbit wela = P2^7;
sbit RW = P1^1;
sbit RS = P1^0;
sbit LCD2 = P1^2;
sbit LCDEN = P2^5;
sbit DQ = P2^2; //定义DS18B20端口DQ
sbit BEEP=P2^3 ; //蜂鸣器驱动线
bit presence ;
sbit K1 = P3^4;
sbit K2 = P3^5;
sbit K3 = P3^6;
sbit K4 = P3^7;
uchar code cdis1[ ] = {" DS18B20 OK "};
uchar code cdis2[ ] = {" "};
uchar code cdis3[ ] = {" DS18B20 ERR0R "};
uchar code cdis4[ ] = {" PLEASE CHECK "};
uchar code cdis5[ ] = {" xianzaiwendu: "};
unsigned char data display[2] = {0x00,0x00};
unsigned char data RomCode[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
unsigned char Temp;
unsigned char crc;
void beep();
#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};
/*******************************************************************/
/* */
/*us级延时函数 */
/* */
/*******************************************************************/
void Delay(unsigned int num)
{
while( --num );
}
void delayUs()
{
_nop_();
}
void delayMs(uint a)
{
uint i, j;
for(i = a; i > 0; i--)
for(j = 100; j > 0; j--);
}
/******************************************************************/
/* */
/*检查LCD忙状态 */
/*lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据。 */
/* */
/******************************************************************/
bit lcd_busy()
{
bit result;
RS = 0;
// LCD1 = 1;
LCDEN = 1;
delayNOP();
result = (bit)(P0&0x80);
LCDEN = 0;
return(result);
}
void writeComm(uchar comm)
{
RS = 0;
P0 = comm;
LCDEN = 1;
delayUs();
LCDEN = 0;
delayMs(1);
}
//写数据:RS=1, RW=0;
void writeData(uchar dat)
{
RS = 1;
P0 = dat;
LCDEN = 1;
delayUs();
LCDEN = 0;
delayMs(1);
}
/*******************************************************************/
/* */
/* LCD初始化设定 */
/* */
/*******************************************************************/
void lcd_init()
{
RW = 0;
delayMs(15);
writeComm(0x01); //清除LCD的显示内容
writeComm(0x38); //16*2显示,5*7点阵,8位数据
delayMs(5);
writeComm(0x38);
delayMs(5);
writeComm(0x38);
delayMs(5);
writeComm(0x0c); //显示开,关光标
delayMs(5);
writeComm(0x06); //移动光标
delayMs(5);
writeComm(0x01); //清除LCD的显示内容
delayMs(5);
}
void init()
{
RW = 0;
dula = wela = 0;
writeComm(0x38);
writeComm(0x0c);
writeComm(0x06);
writeComm(0x01);
}
Init_DS18B20(void)
{
DQ = 1; //DQ复位
Delay(8); //稍做延时
DQ = 0; //将DQ拉低
Delay(90); //精确延时 大于 480us
DQ = 1; //拉高总线
Delay(8);
presence = DQ; //读取存在信号
Delay(100);
DQ = 1;
return(presence); //返回信号,0=presence,1= no presence
}
void writeString(uchar * str, uchar length)
{
uchar i;
for(i = 0; i < length; i++)
{
writeData(str[i]);
}
}
/*******************************************************************/
/* */
/* 设定显示位置 */
/* */
/*******************************************************************/
void lcd_pos(uchar pos)
{
writeComm(pos | 0x80); //数据指针=80+地址变量
}
/**//*****************************DS18B20*******************************/
void dsInit()
{
unsigned int i;
DQ = 0;
i = 100;
while(i>0) i--;
DQ = 1;
i = 4;
while(i>0) i--;
}
void dsWait()
{
unsigned int i;
while(DQ);
while(~DQ);
i = 4;
while(i > 0) i--;
}
bit readBit()
{
unsigned int i;
bit b;
DQ = 0;
i++;
DQ = 1;
i++; i++;
b = DQ;
i = 8;
while(i>0) i--;
return b;
}
unsigned char readByte()
{
unsigned int i;
unsigned char j, dat;
dat = 0;
for(i=0; i<8; i++)
{
j = readBit();
dat = (j << 7) | (dat >> 1);
}
return dat;
}
void writebit(char bitval) {
DQ = 0; // 将DQ 拉低开始写时间隙
if(bitval==1) DQ =1; // 如果写1,DQ 返回高电平
Delay(5); // 在时间隙内保持电平值,
DQ = 1; // Delay函数每次循环延时16μs,因此delay(5) = 104μs
}
void writeByte(unsigned char dat)
{
unsigned int i;
unsigned char j;
bit b;
for(j = 0; j < 8; j++)
{
b = dat & 0x01;
dat >>= 1;
if(b)
{
DQ = 0; i++; i++;
DQ = 1;
i = 8; while(i>0) i--;
}
else
{
DQ = 0;
i = 8; while(i>0) i--;
DQ = 1;
i++; i++;
}
}
}
void sendChangeCmd()
{
dsInit();
dsWait();
delayMs(1);
writeByte(0xcc);
writeByte(0x44);
}
void sendReadCmd()
{
dsInit();
dsWait();
delayMs(1);
writeByte(0xcc);
writeByte(0xbe);
}
int getTmpValue()
{
unsigned int tmpvalue;
int value;
float t;
unsigned char low, high;
sendReadCmd();
low = readByte();
high = readByte();
tmpvalue = high;
tmpvalue <<= 8;
tmpvalue |= low;
value = tmpvalue;
\
t = value * 0.0625;
\
value = t * 100 + (value > 0 ? 0.5 : -0.5); //大于0加0.5, 小于0减0.5
return value;
}
void dis(int v)
{
unsigned char count;
unsigned char datas[] = {0, 0, 0, 0, 0};
unsigned int tmp = abs(v);
datas[0] = tmp / 10000;
datas[1] = tmp % 10000 / 1000;
datas[2] = tmp % 1000 / 100;
datas[3] = tmp % 100 / 10;
datas[4] = tmp % 10;
writeComm(0xc0+3);
if(v < 0)
{
writeString("- ", 2);
}
else
{
writeString("+ ", 2);
}
if(datas[0] != 0)
{
writeData('0'+datas[0]);
}
for(count = 1; count != 5; count++)
{
writeData('0'+datas[count]);
if(count == 2)
{
writeData('.');
}
}
}
/**//*****************************XULEIMA*******************************/
void beep()
{
unsigned char y;
for (y=0;y<100;y++)
{
Delay(60);
BEEP=!BEEP; //BEEP取反
}
BEEP=1; //关闭蜂鸣器
Delay(40000);
}
/*******************************************************************/
/* */
/* 读取64位序列码 */
/* */
/*******************************************************************/
Read_RomCord(void)
{
unsigned char j;
Init_DS18B20();
writeByte(0x33); // 读序列码的操作
for (j = 0; j < 8; j++)
{
RomCode[j] = readByte() ;
}
}
/*******************************************************************/
/* */
/*DS18B20的CRC8校验程序 */
/* */
/*******************************************************************/
uchar CRC8()
{
uchar i,x; uchar crcbuff;
crc=0;
for(x = 0; x <8; x++)
{
crcbuff=RomCode[x];
for(i = 0; i < 8; i++)
{
if(((crc ^ crcbuff)&0x01)==0)
crc >>= 1;
else {
crc ^= 0x18; //CRC=X8+X5+X4+1
crc >>= 1;
crc |= 0x80;
}
crcbuff >>= 1;
}
}
return crc;
}
/*******************************************************************/
/* */
/* 数据转换与显示 */
/* */
/*******************************************************************/
Disp_RomCode()
{
uchar j;
uchar H_num=0x40; //LCD第二行初始位置
for(j=0;j<8;j++)
{
Temp = RomCode[j];
display[0]=((Temp&0xf0)>>4);
if(display[0]>9)
{ display[0]=display[0]+0x37;}
else{display[0]=display[0]+0x30;}
lcd_pos(H_num);
writeData(display[0]); //高位数显示
H_num++;
display[1]=(Temp&0x0f);
if(display[1]>9)
{display[1]=display[1]+0x37;}
else {display[1]=display[1]+0x30;}
lcd_pos(H_num);
writeData(display[1]); //低位数显示
H_num++;
}
}
/*******************************************************************/
/* */
/* DS18B20 OK 显示菜单 */
/* */
/*******************************************************************/
void Ok_Menu ()
{
uchar m;
lcd_init(); //初始化LCD
lcd_pos(0); //设置显示位置为第一行的第1个字符
m = 0;
while(cdis1[m] != '\0')
{ //显示字符
writeData(cdis1[m]);
m++;
}
lcd_pos(0x40); //设置显示位置为第二行第1个字符
m = 0;
while(cdis2[m] != '\0')
{
writeData(cdis2[m]); //显示字符
m++;
}
}
/*******************************************************************/
/* */
/* DS18B20 ERROR 显示菜单 */
/* */
/*******************************************************************/
void Error_Menu ()
{
uchar m;
lcd_init(); //初始化LCD
lcd_pos(0); //设置显示位置为第一行的第1个字符
m = 0;
while(cdis3[m] != '\0')
{ //显示字符
writeData(cdis3[m]);
m++;
}
lcd_pos(0x40); //设置显示位置为第二行第1个字符
m = 0;
while(cdis4[m] != '\0')
{
writeData(cdis4[m]); //显示字符
m++;
}
}
/**//*****************************DS18B20*******************************/
void display64()
{
P0 = 0xff;
P2 = 0xff;
//while(1)
//{
Ok_Menu ();
Read_RomCord(); //读取64位序列码
CRC8(); //CRC效验
if(crc==0) //CRC效验正确
{
Disp_RomCode(); //显示64位序列码
}
//}
}
void main()
{
int max;
while(1)
{
if(K4==0)
{
delayMs(10);
if(K4==0)
{
writeComm(0x01);
display64();
}
}
if(K1==0)
{
delayMs(10);
if(K1==0)
{
writeComm(0x01);
while(K4!=0)
{
init();
writeString(cdis5, 16);
delayMs(1000); //温度转换时间需要750ms以上
writeComm(0xc0);
dis(getTmpValue());
if(max>2800)
{
……………………
…………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
实验.rar
(112.22 KB, 下载次数: 7)
2017-10-24 14:21 上传
点击文件名下载附件
下载积分: 黑币 -5
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1