⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 5.c

📁 由单片机、DS18B20、DS1302、1602等组成时间温度显示系统。有Proteus图和C语言程序
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <reg51.h>
#include <intrins.h>
#define HIGH 1
#define LOW 0
#define  uchar unsigned char
#define  uint  unsigned int

//***************LCD1602********************************
#define DATA_MODE 0x28 //LCD模式设置,0x28位四位数据线模式
#define OPEN_SCREEN 0x0C //打开LCD显示
#define DISPLAY_ADDRESS 0x80 //写地址指令
#define CLEARSCREEN LCD_en_com(0x01) //清屏
#define LCDIO P0 //LCD1602的高四位接在P0口的高四位
sbit LCD1602_RS=P0^1; //RS为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器。
sbit LCD1602_EN=P0^0; //E端为使能端,当E端由高电平跳变成低电平时,液晶模块执行命令。
void LCD_en_com(uchar command); //写命令指令
void LCD_en_dat(uchar temp); //写数据指令
void LCD_set_xy(uchar x, unsigned char y); //设置显示地址:X为横轴(0-15),Y为纵轴(0-1).
void LCD_write_char(uchar x,uchar y,uchar dat); //写一个字符
void LCD_write_string(uchar x,uchar y,uchar *s);//写一个字符串
void LCD_write_int(uchar x,uchar y,uint intdat); //写无字符型整形数
void LCD_init(void); //lcd初始化
void cover(void);

//************************DS1302*******************************************//
sbit RST =P3^4; //ds1302的接线
sbit IO  =P3^3;
sbit SCLK=P3^2;
sbit ACC0=ACC^0;  //累加器
sbit ACC7=ACC^7;
uchar times[7]={50,59,23,30,11,7,8}; //存放时间

uchar led[13];
void change_time(unsigned char i);
//*************************DS18B20*******************************************//
sbit DQ=P1^0;
uint   h;             //定义循环变量
uchar data  temp_data[2]={0x00,0x00};               // 读出温度暂放
uchar data  display[5]={0x00,0x00,0x00,0x00,0x00};//显示单元数据,共4个数据,一个运算暂存用
uchar code ditab[16]={0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09};
//************************其他******************************************//
sbit alarm_speaker=P3^7; //蜂鸣器的接线
void delay(uchar i); //延时程序
unsigned char key=16; //存放健值
//***************************************************************************************
void LCD_en_write(void) //EN端产生一个高电平脉冲,写LCD
{
LCD1602_EN=HIGH;
_nop_();
LCD1602_EN=LOW;
}
//****************************************************************************************
void LCD_en_com(uchar command)
{
delay(9);
LCD1602_RS=LOW; //RS=0 写命令
LCDIO&=0x0f;	//清高四位
LCDIO|=command&0xf0; //先发送高四位数据
LCD_en_write();
command=command<<4;
LCDIO&=0x0f;
LCDIO|=command&0xf0; //发送低四位数据
LCD_en_write();
}
//*****************************************************************************************
void LCD_en_dat(uchar dat)
{
delay(9);
LCD1602_RS=HIGH; //RS=1 写数据
LCDIO&=0x0f;	 //清高四位
LCDIO|=dat&0xf0; //写高四位
LCD_en_write();
dat=dat<<4;		 //低四位移到高四位
LCDIO&=0x0f;	 // 清高四位
LCDIO|=dat&0xf0; //写低四位
LCD_en_write();
}
//**************设置显示地址:X为横轴(0-15),Y为纵轴(0-1)**************************************
void LCD_set_xy(uchar x,uchar y)
{
uchar address;
x&=0x0f;
if(!y)
address=0x80+x;
else
address=0xc0+x;
LCD_en_com(address);
}
//***************写一个字符:X为横轴(0-15),Y为纵轴(0-1)**********
void LCD_write_char(uchar x,uchar y,uchar dat)
{
LCD_set_xy(x,y);
LCD_en_dat(dat);
}
//***************写一个字符串**********
void LCD_write_string(uchar x,uchar y,const uchar *s)
{
LCD_set_xy(x,y);
while(*s)
{
LCD_en_dat(*s);
s++;
}
}
//****************写一个无字符整数***************************************
void LCD_write_int(uchar x,uchar y,uint intdat)
{
uchar i=0,temp[5];
LCD_set_xy(x,y);
if(intdat==0)
{
LCD_en_dat(0x30);
return;
}
while(intdat/10 || intdat%10)
{
temp[i]=intdat%10;
intdat/=10;
i++;
}
while(i)
{
i--;
LCD_en_dat(temp[i]+0x30);
}
}
//*****//LCD的初始化函数(刚上电的时候一定要调用一次)//*********************
void LCD_init(void)
{
LCD_en_com(DATA_MODE); //设计四位数据线模式
LCD_en_write();
delay(9);
LCD_en_com(DATA_MODE);
LCD_en_com(OPEN_SCREEN); //打开LCD显示
LCD_en_com(DISPLAY_ADDRESS);//设计首地址
CLEARSCREEN; //清屏
delay(9);
}
//***********************18b20************
//*********************11微秒延时函数*********************//
void delay1(uint t)
{
for(;t>0;t--);
}
//*********************18B20复位函数*********************//
reset(void)
{
char presence=1;
while(presence)
{
while(presence)
  {
	DQ=1;_nop_();_nop_();//总线上拉
	DQ=0;                //下拉         
	delay1(50);           //维持550us,最短维持480us
	DQ=1;                //总线上拉
	delay1(6);            //检测总线上升沿,66us
	presence=DQ;         //DS18B20发存在低电平信号(60-240us);presence=0继续下一步
   }
delay1(30);              //延时300us,总线恢复高电平,DQ=1;
presence = ~DQ;         //取反,跳出循环
}
DQ=1;
} 
//*********************18B20写命令函数*********************//
void write_byte1(uchar val)
{
uchar i;
for (i=8; i>0; i--) //定义 8 bit,写 8 bit
{
DQ=1;_nop_();_nop_(); 
DQ = 0;_nop_();_nop_();_nop_();_nop_();_nop_();//5us
DQ = val&0x01;      //最低位移出,并写入总线
delay1(6);           //66us
val=val/2;          //右移一位,倒数第二位变为最低位
}
DQ = 1;
delay(1);           //高电平维持11us,写结束 
}
//*********************18B20读1个字节函数*********************//
uchar read_byte1(void)
{
uchar i;
uchar value = 0;
for (i=8;i>0;i--)
{
DQ=1;_nop_();_nop_();
value>>=1;           //右移一位
DQ = 0;            
_nop_();_nop_();_nop_();_nop_();          //4us
DQ = 1;_nop_();_nop_();_nop_();_nop_();   //4us ,读时隙
if(DQ)value|=0x80;   //DQ=1,则写入为 10000000
delay1(6);            //66us
}
DQ=1;
return(value);
}
//*********************读出温度函数*********************//
read_temp()
{
	reset();       //总线复位
	write_byte1(0xCC); // 发Skip ROM命令
	write_byte1(0xBE); //  发读命令
	temp_data[0]=read_byte1();  //温度低8位
	temp_data[1]=read_byte1();  //温度高8位
	reset();
	write_byte1(0xCC); // Skip ROM
	write_byte1(0x44); // 发转换命令
}
//*********************温度数据处理函数*********************//
work_temp()
{
uchar n=0;       //存储符号
if(temp_data[1]>112)
 {temp_data[1]=(0xFF-temp_data[1]);temp_data[0]=(0xFF-temp_data[0]);n=1;} //负温度求补码

display[4]=temp_data[0]&0x0f;display[0]=ditab[display[4]];  //处理小数位
display[4]=((temp_data[0]&0xf0)>>4)|((temp_data[1]&0x0f)<<4);//低八位屏蔽小数位后右移四位与高八位屏蔽符号位后左移四位合并//
if(n){display[4]+=1;display[0]-=9;}
display[3]=display[4]/100;  //百位
display[1]=display[4]%100;  
display[2]=display[1]/10;   //十位
display[1]=display[1]%10;   //个位
LCD_write_int(11,1,display[1]); //显示温度的个位
LCD_en_dat('.');
LCD_write_int(13,1,display[0]); //显示温度的小数位
LCD_en_dat(0x27); //显示'号
LCD_en_dat('C'); //显示C
if(!display[3])
{
	LCD_write_string(9,1," ");
	if(!display[2])
	{
		LCD_write_string(10,1," ");
	}
	else
		LCD_write_int(10,1,display[2]);
} 
else
{
	LCD_write_int(9,1,display[3]);
	LCD_write_int(10,1,display[2]);
}
if(n)
{
	if(!display[2])
	LCD_write_string(10,1,"-");
	else
	LCD_write_string(9,1,"-");
}  //负温度时最高位显示"-"
}
/*=================================================================*/

/* 从1302的当前地址处读出1字节数据 */
/*=================================================================*/
void write_1302_byte(unsigned char d)
{
	unsigned char i;
	ACC=d; //将8位数据写入ACC
	for(i=8;i>0;i--) //循环8次将ACC8位数据从低位到高位写入1302
	{
		IO=ACC0; //将ACC的最低位转送到IO口
		SCLK=1; //上升沿写入1位数据
		SCLK=0;
		ACC=ACC>>1; //将ACC次低位变为最低位
	}
}
/*=================================================================*/
/* 从1302的当前地址处读出1字节数据 */
/*=================================================================*/
unsigned char read_1302_byte(void)
{
	unsigned char i;
	for(i=8;i>0;i--)
	{
		ACC=ACC>>1;
		ACC7=IO;
		SCLK=1; //时钟下降沿读1位数据
		SCLK=0;
	}
	return (ACC);
}
/*=================================================================*/
/* 将数据Data写入1302寄存器add处 */
/*================================================================*/
void write_1302_reg(unsigned char add,unsigned char d)
{
	RST= 0;
	SCLK=0;
	RST= 1;
	write_1302_byte(add); //将1302的指针移到add处
	write_1302_byte(d); //往add处写入数据
	SCLK=1;
	RST=0; //停止写数据
}
/*=================================================================*/

/* 读寄存器add处的值 */
/*==================================================================*/
unsigned char read_1302_reg(unsigned char add)
{
	unsigned char d;
	RST=0;
	SCLK=0;
	RST=1;
	write_1302_byte(add);
	d=read_1302_byte();
	SCLK=1;
	RST=0;
	return (d);
}
/*=================================================================*/

/* 设置时间,time[0]-time[6]数据存放顺序为:秒,分,时,日,月,星期,年 */
/*===================================================================*/
void write_1302_time(unsigned char *time)
{
	unsigned char add=0x80; //地址add初值(秒),偶数地址为只写
	unsigned char i;
	unsigned char timeBCD[7]; //用以存放time数据的BCD码值
	bdata unsigned char l,h; //单位变量,分别存放时间数据(8421BCD码)的低4位和高4位
	for(i=0;i<7;i++) //将时间数据转为BCD码放入timeBCD中
	{
		l=time[i]%10;
		h=time[i]/10;
		timeBCD[i]=h*16+l;
	}
	write_1302_reg(0x8e,0x00); //禁止写
	for(i=0;i<7;i++)
	{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -