12864模拟时钟

#include
#include
#include
#include

#define uchar unsigned char
#define uint unsigned int
#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};
#define pi 3.1415926
/************* 12864LCD引脚定义 *************/
#define LCD_data P0 //数据口
sbit LCD_RS = P2^3; //寄存器选择输入
sbit LCD_RW = P2^2; //液晶读/写控制
sbit LCD_EN = P2^1; //液晶使能控制
sbit LCD_PSB = P2^4; //串/并方式控制
sbit LCD_RST = P2^5; //液晶复位端口
sbit k1=P3^5; //按键
sbit k2=P3^2;
sbit k3=P3^3;
sbit k4=P3^4;

sbit DQ = P2^0; //数据口define interface
uchar a,b,c,count,num;
uint temp;
uchar tabbjsj[]="北京时间";
uchar tabsswd[]="实时温度";
uchar tab[]="01:00:00";
uchar code table[]={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x0F,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0xF8,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x0E,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x87,0x13,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x03,0xF7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x30,0x0E,0x30,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x78,0x1C,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x3C,0xFC,0x38,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x79,0xDE,0x71,0xDE,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x79,0x9E,0x79,0x9E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x3C,0x3C,0x3C,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x3B,0x9E,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x0F,0xF7,0x0F,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xEF,0x37,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x03,0xDE,0x7B,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xBC,

0xFD,0x80,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x79,0xDE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x79,0x8E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x1E,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xF0,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,
0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x20,
0x00,0x01,0x9C,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0xC0,0x00,0x99,0x00,0x00,0x30,0x00,0x03,0x9A,0x00,0x0C,0x23,0x00,0x00,0x00,0x02,0xC6,
0x00,0x99,0x80,0x06,0xB4,0x00,0x02,0x21,0x00,0x06,0x33,0x00,0x10,0x80,0x07,0x26,0x00,0x98,0x00,0x12,0x88,0x00,0x02,0x24,0x80,0x06,0x3F,
0x00,0x1F,0xC0,0x05,0x26,0x00,0x15,0x00,0x1C,0x00,0x00,0x03,0x66,0x70,0x17,0x67,0x00,0x0F,0x00,0x01,0xBE,0x00,0x02,0x00,0x0E,0x70,0x00,
0x03,0x7E,0x00,0x17,0xE2,0x00,0x07,0x00,0x07,0x00,0x01,0xA0,0x40,0x18,0x00,0x00,0x06,0xCE,0x00,0x0E,0x62,0x00,0x07,0x00,0x03,0xA6,0x00,
0x9C,0x80,0x12,0x38,0x00,0x06,0x0F,0x80,0x06,0x62,0x00,0x06,0x00,0x03,0x08,0x00,0x84,0x00,0x10,0xF0,0x00,0x0C,0xFC,0x00,0x06,0x22,0x00,
0x1E,0x00,0x05,0x1C,0x00,0x1E,0x00,0x10,0x40,0x00,0x12,0x24,0x80,0x3E,0x42,0x00,0x1E,0x00,0x01,0x1C,0x00,0x04,0x00,0x10,0x80,0x00,0x02,
0x44,0xC0,0x3C,0x43,0x00,0x7F,0xF0,0x01,0x0E,0x00,0x04,0x00,0x11,0x10,0x80,0x02,0x64,0x80,0x00,0x03,0x00,0x20,0x00,0x00,0xFA,0x80,0x08,
0x00,0x13,0x08,0x80,0x02,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x18,0x00,0x00,0x07,0x00,0x02,0x0C,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0

x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00};
/*******************************************************************/
/* */
/* 延时函数 */
/* */
/*******************************************************************/
void delay(int ms)
{
while(ms--)
{
uchar i;
for(i=0;i<150;i++)
{
_nop_();
_nop_();
_nop_();
_nop_();
}
}
}

/*******************************************************************/
/* */
/* 精确延时函数,延时1秒,软件算得 */
/* */
/*******************************************************************/
void Delay_S(void) //延时1s误差 0us
{
unsigned char a,b,c;
for(c=167;c>0;c--)
for(b=171;b>0;b--)
for(a=16;a>0;a--);
_nop_(); //if Keil,require use intrins.h
}
/*******************************************************************/
/* */
/*检查LCD忙状态 */
/*lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据。 */
/* */
/*******************************************************************/
bit lcd_busy()
{
bit result;
LCD_RS = 0;
LCD_RW = 1;
LCD_EN = 1;
delayNOP();
result = (bit)(P0&0x80);
LCD_EN = 0;
return(result);
}
/*******************************************************************/
/* */
/*写指令数据到LCD */
/*RS=L,RW=L,E=高脉冲,D0-D7=指令码。 */
/* */
/*******************************************************************/
void lcd_wcmd(uchar cmd)
{
while(lcd_busy());
LCD_RS = 0;
LCD_RW = 0;
LCD_EN = 0;
_nop_();
_nop_();
LCD_data = cmd;
delayNOP();
LCD_EN = 1;
delayNOP();
LCD_EN = 0;
}
/*******************************************************************/
/* */
/*写显示数据到LCD */
/*RS=H,RW=L,E=高脉冲,D0-D7=数据。 */
/* */
/*******************************************************************/
void lcd_wdat(uchar dat)
{


while(lcd_busy());
LCD_RS = 1;
LCD_RW = 0;
LCD_EN = 0;
LCD_data = dat;
delayNOP();
LCD_EN = 1;
delayNOP();
LCD_EN = 0;
}
/*******************************************************************/
/* */
/*从lcd读取数据到data */
/*RS=H,RW=L,E=高脉冲,D0-D7=数据。 */
/* */
/*******************************************************************/
uchar lcd_rdat()
{
uchar dat;
while(lcd_busy());
LCD_data = 0XFF;
LCD_RS = 1;
LCD_RW = 1;
LCD_EN = 0;
LCD_EN = 1;
dat = LCD_data;
LCD_EN = 0;
return(dat);
}

/*******************************************************************/
/* */
/* LCD初始化设定 */
/* */
/*******************************************************************/
void lcd_init()
{
LCD_PSB = 1; //并口方式

LCD_RST = 0; //液晶复位
delay(3);
LCD_RST = 1;
delay(3);

lcd_wcmd(0x34); //扩充指令操作
delay(5);
lcd_wcmd(0x30); //基本指令操作
delay(5);
lcd_wcmd(0x0C); //显示开,关光标
delay(5);
lcd_wcmd(0x01); //清除LCD的显示内容
delay(5);
}

/***********************************************************
函数名: DrawPoint
函数说明:画点
传入参数:打点位置(x0,y0);color=1,点亮;color=0,擦除
传出参数:无
返回值: 无
**********************************************************/
void DrawPoint(unsigned char x,unsigned char y,unsigned char color)
{
unsigned char row,collum,cbite;
unsigned char tempH,tempL;
lcd_wcmd(0x34);//打开扩充指令集
lcd_wcmd(0x36);//打开图形显示

collum=x>>4;
cbite=x&0x0f;

if(y<32)
row=y;
else
{
row=y-32;
collum+=8;
}

lcd_wcmd(0x80+row);//先写Y坐标
lcd_wcmd(0x80+collum);//再写X坐标
lcd_rdat();
tempH = lcd_rdat();//先读出高字节
tempL = lcd_rdat();//再读出低字节

lcd_wcmd(0x80+row);//先写Y坐标
lcd_wcmd(0x80+collum);//再写X坐标
if (color)
{
if(cbite<8)
{
tempH|=(1<<(7-cbite));

}
else
{

tempL|=(1<<(15-cbite));
}
}
else
{
if(cbite<8)
{
tempH&=~(1<<(7-cbite));

}
else
{

tempL&=~(1<<(15-cbite));
}
}
lcd_wdat(tempH);
lcd_wdat(tempL);

lcd_wcmd(0x30);
}
/***********************************************************
函数名: line
函数说明:画直线
传入参数:直线起始位置(x0,y0);终点(x1,y1)
传出

参数:无
返回值: 无
**********************************************************/
void line(unsigned char x0,unsigned char y0, unsigned char x1,unsigned char y1,unsigned char color)
{
int dx; /* 直线x轴差值变量*/
int dy; /* 直线y轴差值变量 */
char dx_sym; /* x轴增长方向,为-1时减值方向,为1时增值方向 */
char dy_sym; /* y轴增长方向,为-1时减值方向,为1时增值方向 */
int dx_x2; /* dx*2值变量,用于加快运算速度*/
int dy_x2; /* dy*2值变量,用于加快运算速度*/
int di; /* 决策变量 */

if (x0 == x1) /* 画垂直线 */
{
if (y0 > y1)
{
dx = y0;
y0 = y1;
y1 = dx;
}
for (dx = y0; dx < y1+1; dx++)
{
DrawPoint(x0, dx,color);
}
}

if (y0 == y1) /* 画水平线 */
{
if(x0 > x1)
{
dy = x0;
x0 = x1;
x1 = dy;
}
for (dy = x0; dy < x1+1; dy++)
{
DrawPoint(dy, y0,color);
}
}

/****************************画斜线******************************/
dx = x1-x0; /* 求取两点之间的差值 */
dy = y1-y0;
if (dx > 0) /* 判断x轴方向 */
{
dx_sym = 1; /* dx>0,设置dx_sym=1 */
}
else
{
if (dx < 0)
{
dx_sym = -1; /* dx<0,设置dx_sym=-1 */
}
}

if (dy > 0) /* 判断y轴方向 */
{
dy_sym = 1; /* dy>0,设置dy_sym=1 */
}
else
{
if (dy < 0)
{
dy_sym = -1; /* dy<0,设置dy_sym=-1 */
}
}


dx = dx_sym * dx; /* 将dx、dy取绝对值 */
dy = dy_sym * dy;
dx_x2 = dx*2; /* 计算2倍的dx及dy值 */
dy_x2 = dy*2;

/* 使用Bresenham法进行画直线 */
if (dx >= dy) /* 对于dx>=dy,则使用x轴为基准 */
{
di = dy_x2 - dx;
while(x0!=x1)
{
DrawPoint(x0, y0,color);
x0 += dx_sym;
if (di < 0)
{
di += dy_x2; /* 计算出下一步的决策值 */
}
else
{
di += dy_x2 - dx_x2;
y0 += dy_sym;

}
}
DrawPoint(x0, y0,color); /* 显示最后一点 */
}
else /* 对于dx{
di = dx_x2 - dy;
while(y0!=y1)
{
DrawPoint(x0, y0,color);
y0 += dy_sym;
if (di < 0)
{
di += dx_x2;
}
else
{
di += dx_x2 - dy_x2;
x0 += dx_sym;
}
}
DrawPoint(x0, y0,color); /* 显示最后一点 */
}
}


/***********************************************************
函数名: circle
函数说明:画圆
传入参数:圆心坐标(x1,y1),半径r
传出参数:无
返回值: 无
**********************************************************/
void circle(int x1, int y1, unsigned int r)
{
int x, y, d;
x = 0;
y = r;
d = 1-r; /* 计算初始值 */

while (x <= y)
{
/* 绘制点(x,y)及其在八分圆中的另外7个对称点 */
DrawPoint(x1+x, y1+y,1);
DrawPoint(x1+y, y1+x,1);
DrawPoint(x1-y, y1+x,1);
DrawPoint(x1-x, y1+y,1);
DrawPoint(x1-x, y1-y,1);
DrawPoint(x1-y, y1-x,1);
DrawPoint(x1+y, y1-x,1);
DrawPoint(x1+x, y1-y,1);

if (d < 0)
{
d += 2*x+3; /* 根据误差项d的判断,决定非最大位移方向上是走还是不走 */
}
else
{
d += 2*(x-y)+5;
y--;
}
x++;
}
}



/*******************************************
函数名称:void DrawHand(char x0,char y0,char a,char b,char c,char color)
功 能:画时钟指针
参 数:(x0,y0)表盘圆心坐标,
R指针长度
Time指针所指刻度(秒、分60进制,时12进制)
step指针步长(秒、分为6,时为30)
color指针颜色
返回值 :无
********************************************/
void DrawHand(char x0,char y0,char R,char Time,char step,char color)
{
char x,y;
x=R*cos(Time*step*pi/180-pi/2)+x0;
y=R*sin(Time*step*pi/180-pi/2)+y0;
line(x0,y0,x,y,color);
}

/*******************************************
函数名称:clr_screen(void)
功 能:清除液晶GDRAM内部的随机数据
参 数:无
返回值 :无
********************************************/
void clr_screen(void)
{

uchar i,j;
for(j=0;j<64;j++)
{
for(i=0;i<128;i++)
{
DrawPoint(i,j,0);
}
}
}






/*******************************************************************************
* 描述: *
* 12864标准字库液晶演示 数据p0,控制p2 *

********************************************************************************/


#define x0 31
#define y0 31 //表盘圆心坐标

/***********************************************************
函数名: DISP_BP
函数说明:画表盘
传出参数:无
返回值: 无
**********************************************************/
void DISP_BP(void)
{
circle(x0,y0,30);//画圆

line(31,1,31,3,1);//12点
line(30,1,30,3,1);
line(32,1,32,3,1);
line(31,61,31,59,1);//6点
line(30,61,30,59,1);
line(32,61,32,59,1);
line(61,31,59,31,1);//3点
line(61,30,59,30,1);
line(61,32,59,32,1);
line(1,31,3,31,1);//9点
line(1,30,3,30,1);
line(1,32,3,32,1);
line(109,51,111,51,1);//℃符号
line(109,50,111,50,1);
line(109,49,111,49,1);
line(110,50,110,50,0);
circle(8,8,8); //耳朵左
line(16,7,16,11,0);
line(7,16,12,16,0);
line(15,12,11,15,0);
line(15,11,12,17,0);
line(12,15,12,15,0);
circle(54,8,8); //耳朵右
line(46,7,46,11,0);
line(55,16,50,16,0);
line(47,12,51,16,0);
line(47,11,47,11,0);
// line(48,14,48,14,1);
line(51,15,51,15,0);
}


/*****************显示时分秒*****************/
void sfm(uchar add,uchar sfm)
{
uchar sfm1,sfm2;
sfm1=sfm/10;
sfm2=sfm%10;
lcd_wcmd(0x90+add);
lcd_wdat(0x30+sfm1);
lcd_wdat(0x30+sfm2);
}

void sfmfen()
{
uchar fen1,fen2;
fen1=b/10;
fen2=b%10;
lcd_wcmd(0x90+5);
lcd_wdat(0x3a);
lcd_wdat(0x30+fen1);
lcd_wdat(0x30+fen2);
}

//按键扫描函数
void keyscan()
{
// uchar i,j,k;
if(k1==0)
delay(5);
if(k1==0)
{
while(!k1);
DrawHand(x0,y0,25,a,6,0); // 消除秒针位置
DrawHand(x0,y0,20,b,6,1); //显示新的分针位置
DrawHand(x0,y0,15,c,6,1);//显示新的时针位置
a++;
if(a==60)
a=0;
sfm(7,a);
DrawHand(x0,y0,25,a,6,1); //显示秒针位置
}

if(k2==0)
delay(5);
if(k2==0)
{
while(!k2);
DrawHand(x0,y0,20,b,6,0); //消除原来分针位置
DrawHand(x0,y0,15,c,6,1);//显示新的时针位置
DrawHand(x0,y0,25,a,6,1); //显示秒针位置
b++;
if(b==60)
b=0;
sfmfen();
DrawHand(x0,y0,20,b,6,1); //显示新的分针位置
}

if(k3==0)
delay(5);
if(k3==0)
{
while(!k3);
DrawHand(x0,y0,15,c,6,0);//消除原来的时针位置
DrawHand(x0,y0,25,a,6,1); //显示秒针位置
DrawHand(x0,y0,20,b,6,1); //显示新的分针位置
c++;
if(c==60)
c=0;
sfm(4,c/5);
DrawHand(x0,y0,15,c,6,1);//显示新的时针位置

}
}




/*******************画开机画面********************/

void GUI_CLEAR(const uchar *pic)
{
uchar i,j,k;
lcd_wcmd(0X34);
lcd_wcmd(0X34);
for(i=0;i<2;i++)
{
for(j=0;j<32;j++)
{
lcd_wcmd(0X80+j);
delay(2);
if(i==0)
{
lcd_wcmd(0X80);
delay(2);

}
else
{
lcd_wcmd(0X88);
delay(2);
}
for(k=0;k<16;k++)
{
lcd_wdat(*(pic++));
//LCD_WRITE_DATA

(0X00);
delay(2);
}
}
}

lcd_wcmd(0X36);
lcd_wcmd(0X30);
}

/********************DS18B20***********************************/
void delay18b20(unsigned char i)
{
while(--i);
}

void Init_Ds18b20(void) //DS18B20初始化send reset and initialization command
{
DQ = 1; //DQ复位,不要也可行。
delay18b20(1); //稍做延时
DQ = 0; //单片机拉低总线
delay18b20(250); //精确延时,维持至少480us
DQ = 1; //释放总线,即拉高了总线
delay18b20(100); //此处延时有足够,确保能让DS18B20发出存在脉冲。
}

uchar Read_One_Byte() //读取一个字节的数据read a byte date
//读数据时,数据以字节的最低有效位先从总线移出
{
uchar i = 0;
uchar dat = 0;
for(i=8;i>0;i--)
{
DQ = 0; //将总线拉低,要在1us之后释放总线
//单片机要在此下降沿后的15us内读数据才会有效。
_nop_(); //至少维持了1us,表示读时序开始
dat >>= 1; //让从总线上读到的位数据,依次从高位移动到低位。
DQ = 1; //释放总线,此后DS18B20会控制总线,把数据传输到总线上
delay18b20(1); //延时7us,此处参照推荐的读时序图,尽量把控制器采样时间放到读时序后的15us内的最后部分
if(DQ) //控制器进行采样
{
dat |= 0x80; //若总线为1,即DQ为1,那就把dat的最高位置1;若为0,则不进行处理,保持为0
}
delay18b20(10); //此延时不能少,确保读时序的长度60us。
}
return (dat);
}

void Write_One_Byte(uchar dat)
{
uchar i = 0;
for(i=8;i>0;i--)
{
DQ = 0; //拉低总线
_nop_(); //至少维持了1us,表示写时序(包括写0时序或写1时序)开始
DQ = dat&0x01; //从字节的最低位开始传输
//指令dat的最低位赋予给总线,必须在拉低总线后的15us内,
//因为15us后DS18B20会对总线采样。
delay18b20(10); //必须让写时序持续至少60us
DQ = 1; //写完后,必须释放总线,
dat >>= 1;
delay18b20(1);
}
}


uint Get_Tmp() //获取温度get the temperature
{
float tt;
uchar a,b;
Init_Ds18b20(); //初始化
Write_One_Byte(0xcc); //忽略ROM指令
Write_One_Byte(0x44); //温度转换指令
Init_Ds18b20(); //初始化
Write_One_Byte(0xcc); //忽略ROM指令
Write_One_Byte(0xbe); //读暂存器指令
a = Read_One_Byte(); //读取到的第一个字节为温度LSB
b = Read_One_Byte(); //读

取到的第一个字节为温度MSB
temp = b; //先把高八位有效数据赋于temp
temp <<= 8; //把以上8位数据从temp低八位移到高八位
temp = temp|a; //两字节合成一个整型变量
tt = temp*0.0625; //得到真实十进制温度值
//因为DS18B20可以精确到0.0625度
//所以读回数据的最低位代表的是0.0625度
temp = tt*10+0.5; //放大十倍
//这样做的目的将小数点后第一位也转换为可显示数字
//同时进行一个四舍五入操作。
return temp;
}


/****************动态显示温度函数**************/

void Display(uint temp) //显示程序
{
uchar A1,A2,A3;
A1 = temp/100; //百位
A2 = temp%100/10; //十位
A3 = temp%10; //个位

lcd_wcmd(0x98+4);
lcd_wdat(' ');
lcd_wdat(0x30+A1);
lcd_wdat(0x30+A2);
lcd_wdat('.');
lcd_wdat(0x30+A3);

}


/*********************************************************
* *
* 主函数 *
* *
*********************************************************/

void main()
{
lcd_init();
GUI_CLEAR(table);
Delay_S(); Delay_S();Delay_S();
Delay_S(); Delay_S();Delay_S();
TMOD=0X01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;ET0=1;TR0=1;
a=0;b=0;c=45;
delay(100); //上电,等待稳定
lcd_init(); //初始化LCD
clr_screen(); //清屏
DISP_BP(); //画表盘
//DrawHand(x0,y0,25,a,6,1); //显示秒针
//DrawHand(x0,y0,20,b,6,1); //显示分针
//DrawHand(x0,y0,15,c,6,1); //显示时针

lcd_wcmd(0x90+4); //显示初始时间
for(num=0;num<8;num++)
{
lcd_wdat(tab[num]);
}
lcd_wcmd(0x98+7); //显示温度符号C
lcd_wdat('C');
lcd_wcmd(0x80+4); //显示”北京时间“
for(num=0;num<8;num++)
{
lcd_wdat(tabbjsj[num]);
}
lcd_wcmd(0x88+4); //显示"实时温度"
for(num=0;num<8;num++)
{
lcd_wdat(tabsswd[num]);
}
c=5;b=0;a=0;
DrawHand(x0,y0,25,a,6,1); //显示秒针
DrawHand(x0,y0,20,b,6,1); //显示分针
DrawHand(x0,y0,15,c,6,1); //显示时针
while(1)
{
keyscan();
Display(Get_Tmp());//显示温度
if(count==20)
{
count=0;
DrawHand(x0,y0,25,a,6,0); // 消除秒针位置
DrawHand(x0,y0,20,b,6,1); //显示新的分针位置
DrawHand(x0,y0,15,c,6,1);//显示新的时针位置
a++;
if(a==60)
{
a=0;
DrawHand(x0,y0,20,b,6,0); //消除原来分针位置
DrawHand(x0,y0,15,c,6,1);//显示新的时针位置
b++;
if(b==60 )
{
b=0;
DrawHand(x0,y0,15,c,6,0);//消除原来的时针位置
c++;

if(c==60)
{
c=0;
}
sfm(4,c/5); DrawHand(x0,y0,15,c,6,1);//显示新的时针位置
}
sfmfen(); DrawHand(x0,y0,20,b,6,1); //显示新的分针位置
}
sfm(7,a); DrawHand(x0,y0,25,a,6,1); //显示新的秒针位置
}
}
}






void ser0()interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
count++;
}







相关文档
最新文档