/*---------------------------------------------------------------------------
这个是main函数屏蔽的都可以用
电子智能时钟程序
单 片 机:STC89C52RC
晶 振:12MHz
时钟芯片:DS12887
液 晶 屏:LCM-12864-ST7920
时 间:2010年3月28日
LCM12864使用并口连接方式,PSB、RST接高电平
头文件----------------------------------------------------------------------*/
#include <reg52.h>
#include <intrins.h>
#include "LCD12864.h"
#include "DS12CR887.h"
#include "DS18B20.h"
#include "nongli.h"
#include "displaytime.h"
#define uint unsigned int
#define uchar unsigned char
/*--------------------定义按键-----------------------------------------------*/
//sbit K1 = P2^7; //K1-设置
//sbit K2 = P2^6; //K2-确认、返回
//sbit K3 = P2^5; //K3-加
//sbit K4 = P2^4; //K4-减
//
//void DelayM(uint);
//
///*定义变量-------------------------------------------------------------------*/
//bit q=0, w=0; //调时标志位
//
///*延时函数 1MS/次------------------------------------------------------------*/
//void DelayM(uint a)
//{
// uchar i;
// while( --a != 0) { for(i = 0; i < 125; i++); }
//}
///*日期、时间设置函数---------------------------------------------------------*/
//void Set_time(uchar sel)
//{
// signed char address,item;
// signed char max,min;
// unsigned char yy,mo,moontemp1,moontemp2;
// ds_write(0x0a,0x00); //进入调时,关闭时钟振荡器
// write_com(0x30); write_com(0x06);
// write_com(0x98); lcm_w_word("设置");
// if(sel==5) {lcm_w_word("秒钟");address=0; max=59;min=0;} //秒钟0
// if(sel==4) {lcm_w_word("分钟");address=2; max=59;min=0;} //分钟2
// if(sel==3) {lcm_w_word("小时");address=4; max=23;min=0;} //小时4
// if(sel==2) {lcm_w_word("日期"); //日期修改为按月份实际天数调整
// address=7; //日期7
// mo = ds_read(0x08);//读月
// moontemp1=mo/16;
// moontemp2=mo%16;
// mo=moontemp1*10+moontemp2;//转换成10进制月份数据
//
// yy = ds_read(0x09);//读年
// moontemp1=yy/16;
// moontemp2=yy%16;
// yy=moontemp1*10+moontemp2;//转换成10进制年份数据
//
// if(mo==2&&yy%4!=0){max=28;min=1;}//平年2月28天
// if(mo==2&&yy%4==0){max=29;min=1;}//闰年2月29天
// if(mo==1||mo==3||mo==5||mo==7||mo==8||mo==10||mo==12){max=31;min=1;}//每月31天的月份
// if(mo==4||mo==6||mo==9||mo==11){max=30;min=1;} //每月30天的月份
// }
// if(sel==1) {lcm_w_word("月份");address=8; max=12;min=1;} //月份8
// if(sel==0) {lcm_w_word("年份");address=9; max=99;min=0;} //年份9
// item=ds_read(address); //读取DS12CR887某地址上的数值赋给item
// if(K3 == 0) {item++;} //K3-加数:1
// if(K4 == 0) {item--;} //K4-减数:1
// if(item>max) item=min; //限制数值最大有效范围
// if(item<min) item=max; //限制数值最小有效范围
// ds_write(address,item); //将调整好的item值写入DS12CR887
// displaydate(); //显示日期
// displaytime(); //显示时间
// displaynl(); //显示农历
// displayxq(); //显示星期
//}
/*主函数---------------------------------------------------------------------*/
void main()
{
// uchar e=0;
// K1=1;K2=1;K3=1;K4=1;
// ds_int(); //时钟芯片初始化
lcm_init(); //液晶初始化
//调用欢迎信息
// DelayM(2000); //延时
// lcm_clr(); //清屏
// Clean_12864_GDRAM(); //清屏
// ds_write(0,30); //miao
// ds_write(2,59); //fen
// ds_write(4,12); //shi
while(1)
{
welcome();
// if (w == 0) //正常走时
// {
// displaydate(); //显示日期
// displaynl(); //显示农历
// displaytime(); //显示时间
// displayxq();
// }
// else {} //否则启动调时
//
///*----------------------------设置时间--------------------------------------*/
// if (K1 == 0)
// {
// DelayM(20); //按键消抖
// if(K1 == 0 && w == 1) //当是调时状态 本键用于调整下一项
// {
// e++; //选择调节的对象
// if (e >= 7 ) {e = 0;}
// while(! K1 ); //等待键松开
// Set_time(e); //调整
// }
// if(K1 == 0 && w == 0) //当是正常状态时就进入调时状态
// {
// lcm_clr();
// Clean_12864_GDRAM(); //清屏
// w=1; //进入调时
// Set_time(e);
// }
// while(K1 == 0); //等待键松开
// }
///*--------------------------------------------------------------------------*/
// if (K2 == 0) // 当在调时状态时就退出调时
// {
// DelayM(20);
// if(K2 == 0 && w == 1)
// {
// w = 0; //退出调时
// e = 0; //"下一项"计数器清0
// }
// if(K2 == 0 && w == 0)
// {
// lcm_clr(); Clean_12864_GDRAM();
// write_com(0x30); write_com(0x06);
// welcome();
// while(K2 == 0);
// }
// lcm_clr(); Clean_12864_GDRAM();
// ds_write(0x0a,0x20); //调时完毕,开启时钟振荡器
// displaydate();
// displaynl();
// displaytime();
// ds1820disp();
// while(K2 == 0);
// }
///*加调整--------------------------------------------------------------------*/
// if (K3 == 0 && w == 1)
// {
// DelayM(20);
// if(K3 == 0 && w == 1) { Set_time(e); }
// while(! K3 );
// }
///*减调整--------------------------------------------------------------------*/
// if (K4 == 0 && w == 1)
// {
// DelayM(20);
// if(K4 == 0 && w == 1) { Set_time(e); }
// while(! K4 );
// }
}
}
/*结束---------------------------------------------------
#ifndef __LCD12864_H__
#define __LCD12864_H__
#define uchar unsigned char
#define uint unsigned int
/*定义12864液晶屏数据线--------------------------------------------------------------*/
sbit LCM_RS = P2^7; //模式位,为0输入指令,为1输入数据
sbit LCM_RW = P2^6; //读写位,为0读,为1写
sbit LCM_EN = P2^5; //使能位,高脉冲
sbit LCM_PSB = P2^4;
#define Lcd_Bus P0 //LCM12864数据总线,P0.0--P0.7对应连接DB0--DB7
/*液晶数字符号图片,宽度x高度=16x32---------------------------------------------------*/
//PCtoLCD2002取模:顺向,逐行式
uchar code num1632[11][64]={
{//图片数字0
0x00,0x00,0x0F,0xF0,0x1F,0xF8,0x3F,0xFC,0x7F,0xFE,0x7C,0x3E,0x78,0x1E,0x78,0x1E,
0x78,0x1E,0x78,0x1E,0x78,0x3E,0x78,0x3E,0x78,0x5E,0x78,0x5E,0x78,0x9E,0x78,0x9E,
0x79,0x1E,0x79,0x1E,0x7A,0x1E,0x7A,0x1E,0x7C,0x1E,0x7C,0x1E,0x78,0x1E,0x78,0x1E,
0x78,0x1E,0x78,0x1E,0x7C,0x3E,0x7F,0xFE,0x3F,0xFC,0x1F,0xF8,0x0F,0xF0,0x00,0x00,},
{//图片数字1
0x00,0x00,0x00,0x38,0x00,0x78,0x00,0xF8,0x01,0xF8,0x01,0xF8,0x00,0x78,0x00,0x78,
0x00,0x78,0x00,0x78,0x00,0x78,0x00,0x78,0x00,0x78,0x00,0x78,0x00,0x78,0x00,0x78,
0x00,0x78,0x00,0x78,0x00,0x78,0x00,0x78,0x00,0x78,0x00,0x78,0x00,0x78,0x00,0x78,
0x00,0x78,0x00,0x78,0x00,0x78,0x00,0x78,0x00,0x78,0x00,0x78,0x00,0x78,0x00,0x00},
{//图片数字2
0x00,0x00,0x0F,0xF0,0x1F,0xF8,0x3F,0xFC,0x7F,0xFE,0x7C,0x3E,0x78,0x1E,0x78,0x1E,
0x78,0x1E,0x78,0x1E,0x78,0x1E,0x78,0x1E,0x78,0x3E,0x00,0x7E,0x00,0xFC,0x01,0xF8,
0x03,0xF0,0x07,0xE0,0x0F,0xC0,0x1F,0x80,0x3F,0x00,0x7E,0x00,0x7C,0x00,0x78,0x00,
0x78,0x00,0x78,0x00,0x78,0x1E,0x7F,0xFE,0x7F,0xFE,0x7F,0xFE,0x7F,0xFE,0x00,0x00},
{//图片数字3
0x00,0x00,0x0F,0xF0,0x1F,0xF8,0x3F,0xFC,0x7F,0xFE,0x7C,0x3E,0x78,0x1E,0x78,0x1E,
0x78,0x1E,0x78,0x1E,0x78,0x1E,0x00,0x1E,0x00,0x1E,0x00,0x3E,0x0F,0xFC,0x0F,0xF8,
0x0F,0xF8,0x0F,0xFC,0x00,0x3E,0x00,0x1E,0x00,0x1E,0x78,0x1E,0x78,0x1E,0x78,0x1E,
0x78,0x1E,0x78,0x1E,0x7C,0x3E,0x7F,0xFE,0x3F,0xFC,0x1F,0xF8,0x0F,0xF0,0x00,0x00},
{//图片数字4
0x00,0x00,0x00,0x1C,0x00,0x3C,0x00,0x7C,0x00,0x7C,0x00,0xFC,0x01,0xFC,0x01,0xFC,
0x03,0xFC,0x07,0xBC,0x07,0xBC,0x0F,0x3C,0x0F,0x3C,0x1E,0x3C,0x1E,0x3C,0x3C,0x3C,
0x3C,0x3C,0x78,0x3C,0x78,0x3C,0x78,0x3C,0x7F,0xFE,0x7F,0xFE,0x7F,0xFE,0x7F,0xFE,
0x00,0x3C,0x00,0x3C,0x00,0x3C,0x00,0x3C,0x00,0x3C,0x00,0x3C,0x00,0x3C,0x00,0x00},
//图片数字5
0x00,0x00,0x7F,0xFE,0x7F,0xFE,0x7F,0xFE,0x7F,0xFE,0x78,0x00,0x78,0x00,0x78,0x00,
0x78,0x00,0x78,0x00,0x7B,0xF0,0x7F,0xF8,0x7F,0xFC,0x7F,0xFE,0x7E,0x3E,0x7C,0x1E,
0x7C,0x1E,0x00,0x1E,0x00,0x1E,0x00,0x1E,0x78,0x1E,0x78,0x1E,0x78,0x1E,0x78,0x1E,
0x78,0x1E,0x78,0x1E,0x7C,0x3E,0x7F,0xFE,0x3F,0xFC,0x1F,0xF8,0x0F,0xF0,0x00,0x00,
{//图片数字6
0x00,0x00,0x0F,0xF0,0x1F,0xF8,0x3F,0xFC,0x7F,0xFE,0x7C,0x3E,0x78,0x1E,0x78,0x1E,
0x78,0x1E,0x78,0x00,0x78,0x00,0x78,0x00,0x7B,0xF0,0x7F,0xF8,0x7F,0xFC,0x7F,0xFE,
0x7C,0x3E,0x78,0x1E,0x78,0x1E,0x78,0x1E,0x78,0x1E,0x78,0x1E,0x78,0x1E,0x78,0x1E,
0x78,0x1E,0x78,0x1E,0x7C,0x3E,0x7F,0xFE,0x3F,0xFC,0x1F,0xF8,0x0F,0xF0,0x00,0x00},
{//图片数字7
0x00,0x00,0x7F,0xFE,0x7F,0xFE,0x7F,0xFE,0x7F,0xFE,0x78,0x1E,0x00,0x1E,0x00,0x3C,
0x00,0x3C,0x00,0x78,0x00,0x78,0x00,0xF0,0x00,0xF0,0x01,0xE0,0x01,0xE0,0x03,0xC0,
0x03,0xC0,0x07,0x80,0x07,0x80,0x07,0x80,0x07,0x80,0x07,0x80,0x07,0x80,0x07,0x80,
0x07,0x80,0x07,0x80,0x07,0x80,0x07,0x80,0x07,0x80,0x07,0x80,0x07,0x80,0x00,0x00},
{//图片数字8
0x00,0x00,0x0F,0xF0,0x1F,0xF8,0x3F,0xFC,0x7F,0xFE,0x7C,0x3E,0x78,0x1E,0x78,0x1E,
0x78,0x1E,0x78,0x1E,0x78,0x1E,0x78,0x1E,0x7C,0x3E,0x3F,0xFC,0x1F,0xF8,0x1F,0xF8,
0x3F,0xFC,0x7C,0x3E,0x78,0x1E,0x78,0x1E,0x78,0x1E,0x78,0x1E,0x78,0x1E,0x78,0x1E,
0x78,0x1E,0x78,0x1E,0x7C,0x3E,0x7F,0xFE,0x3F,0xFC,0x1F,0xF8,0x0F,0xF0,0x00,0x00},
{//图片数字9
0x00,0x00,0x0F,0xF0,0x1F,0xF8,0x3F,0xFC,0x7F,0xFE,0x7C,0x3E,0x78,0x1E,0x78,0x1E,
0x78,0x1E,0x78,0x1E,0x78,0x1E,0x78,0x1E,0x78,0x1E,0x78,0x1E,0x78,0x1E,0x7C,0x3E,
0x7F,0xFE,0x3F,0xFE,0x1F,0xFE,0x0F,0xDE,0x00,0x1E,0x00,0x1E,0x00,0x1E,0x78,0x1E,
0x78,0x1E,0x78,0x1E,0x7C,0x3E,0x7F,0xFE,0x3F,0xFC,0x1F,0xF8,0x0F,0xF0,0x00,0x00},
{// 图片":" 10
//6X6方点
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xE0,0x07,0xE0,
0x07,0xE0,0x07,0xE0,0x07,0xE0,0x07,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xE0,0x07,0xE0,0x07,0xE0,0x07,0xE0,
0x07,0xE0,0x07,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
};
uchar code bmp1616[4][32]={
{0x00,0x00,0x00,0x00,0x3C,0x3C,0x2F,0xF4,0x3D,0x3C,0x39,0x1C,0x11,0x48,0x11,0x88,
0x11,0x08,0x10,0x08,0x18,0x18,0x0C,0x30,0x1F,0xF8,0x18,0x18,0x00,0x00,0x00,0x00,},
{0x01,0x00,0x01,0x00,0x01,0x00,0x7F,0xFC,0x42,0x04,0x82,0x08,0x05,0x00,0x05,0x08,
0x08,0x90,0x18,0xA0,0x28,0x40,0x48,0x20,0x88,0x10,0x0A,0x08,0x0C,0x06,0x08,0x00},
{0x00,0x00,0x3F,0xFE,0x20,0x00,0x20,0x80,0x20,0x80,0x20,0x80,0x2F,0xFC,0x20,0x84,
0x20,0x84,0x21,0x04,0x21,0x04,0x22,0x04,0x22,0x04,0x44,0x04,0x48,0x28,0x90,0x10},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x00,0x00},
};
/*12864液晶显示屏并口驱动程序--------------------------------------------------------*/
//检查忙位
void chk_busy()
{
LCM_RS=0; LCM_RW=1; LCM_EN=1;
Lcd_Bus=0xff;
while((Lcd_Bus&0x80)==0x80);
LCM_EN=0;
}
/*写指令到LCD------------------------------------------------------------------------*/
void write_com(uchar cmdcode)
{
chk_busy();
LCM_RS=0; LCM_RW=0; LCM_EN=1;
Lcd_Bus=cmdcode;
LCM_EN=0;
}
/*写数据到LCD------------------------------------------------------------------------*/
void write_data(uchar Dispdata)
{
chk_busy();
LCM_RS=1; LCM_RW=0; LCM_EN=1;
Lcd_Bus=Dispdata;
LCM_EN=0;
}
/*向LCM发送一个字符串,长度64字符之内-------------------------------------------------*/
void lcm_w_word(uchar *s)
{
while(*s>0) { write_data(*s); s++; } //应用:lcm_w_word("您好!");
}
/******************************************************************************/
void lcm_w_test(bit i,unsigned char word) //写指令或数据(被调用层)
{
if(i == 0) //写指令(0,指令)
{
write_com(word);
}
else //写数据(1,数据)
{
write_data(word);
}
}
/*清屏函数--------------------------------------------------------------------------*/
void lcm_clr(void)
{
lcm_w_test(0,0x01); //写命令
}
/******************************************************************************/
void lcm_clr2(void) //清屏上面3行(用空格填满要清显示的地方,因为液晶屏是静态显示的,所以这办法常用)
{
lcm_w_test(0,0x80);//第一行
lcm_w_word(" ");
//标尺("1234567812345678"应该能够显示满一行)
lcm_w_test(0,0x90);//第二行
lcm_w_word(" ");
//标尺("1234567812345678"应该能够显示满一行)
lcm_w_test(0,0x88);//第一行
lcm_w_word(" ");
//标尺("1234567812345678"应该能够显示满一行)
}
/*初始化LCD屏------------------------------------------------------------------------*/
void lcm_init()
{
LCM_PSB=1;
write_com(0x30); //选择8bit数据流
write_com(0x0c); //开显示(无游标、不反白)
lcm_clr(); //清除显示,并且设定地址DDRAM指针为00H
// write_com(0x01); //清除显示,并且设定地址指针为00H
lcm_clr2();
}
/*使用绘图的方法让一个16*16的汉字符反白----------------------------------------------*/
//形式参数:uchar x,uchar y,uchar wide,uchar bkcor
//行参说明:坐标水平位置,坐标垂直位置,反白行数,要反白还是清除(1:反白,0:清除)
void write1616GDRAM(uchar x,uchar y,uchar sign,uchar *bmp)
{
uchar i,j,basex;
write_com(0x36); //扩展指令,绘图模式命令,开显示也可以绘.(关图片显示0x34)
if(y==1||y==2) //第一第二行
{
basex=0x80; //上半屏
y=(y-1)*16; //垂直位址从0X80开始.
}
if(y==3||y==4) //第三第四行
{
basex=0x88; //下半屏
y=(y-3)*16; //垂直位址都是从0X80开始的,不管上下半屏。
}
for(i=0;i<16;i++) //
{
write_com(0x80+y+i); //写入垂直位址。
write_com(basex+x-1); //再写入水平位址(上半屏第一字为0X80,……第七字为0X87)
//下半屏第一字为0X88,……第七字为0X8F;
for(j=0;j<2;j++) //再写入两个8位元的数据,AC会自动增一,接着写数据
{
if(sign==1)
write_data(~(*bmp++));
else
write_data(*bmp++);
}
}
write_com(0x36); //写完数据,开图片显示
}
/**************************************************************************************
//函数功能:显示16X16图形,适用于st7920型液晶
//形式参数:uchar x,uchar y,uchar *bmp
//行参说明:横坐标X列,纵坐标Y行,sign=1反白、=0不反,tt是要显示的图形bmp1616中的第几个
//************************************************************************************/
void set1616pic(uchar x,uchar y,uchar sign,uchar tt)
{
uchar (*pp)[32]; //定义指针
pp=bmp1616; //二维数组首地址给指针,故指针指向下一个数组地址应为加64
write1616GDRAM(x,y,sign,pp[tt]); //写入小时的十位
}
/**************************************************************************************
//函数功能:显示16X32图形,适用于st7920型液晶
//形式参数:uchar x,uchar y,uchar *bmp
//行参说明:横坐标X列,纵坐标Y行,要显示的图形BMP
//************************************************************************************/
void write1632GDRAM(uchar x,uchar y,uchar *bmp)
{
uchar i,j,basex,basey;
switch(y) //由y纵坐标定是上半屏还是下半屏
{
case 1: basex=0x80; break; //上半屏
case 2: basex=0x80; break; //先上半屏,下面再下半屏。
case 3: basex=0x88; break; //下半屏
default: return; //别的则返回
}
basey=basex+x-1;
write_com(0x36);
if(y==1||y==3) //如为第一第三行,则直接是在同一半屏,直接绘完32行点陈数据。
{
for(i=0;i<32;i++) //写入32行点阵
{
write_com(0x80+i); //先写入垂直位址,选上下32行的哪一行,不管上下半屏,首行都为0X80
write_com(basey); //再写入水平位址(选上下半屏)
for(j=0;j<2;j++) //2个8位元的数据,即16BIT宽度
write_data(*bmp++);
}
}
if(y==2) //从第二行开始则画图将上下半屏都有,所以先画完上半屏16行,再画下半屏16行。
{
for(i=0;i<16;i++) //写入上半屏16行点阵
{
write_com(0x90+i); //先写入垂直位址,选上下32行的哪一行,不管上下半屏,首行都为0X80,第二行为0X90。
write_com(basey); //(选上半屏)再写入水平位址
for(j=0;j<2;j++) //2个8位元的数据,即16BIT宽度
write_data(*bmp++);
}
for(i=0;i<16;i++) //写入下半屏16行点阵
{
write_com(0x80+i); //先写入垂直位址,选上下32行的哪一行,不管上下半屏,首行都为0X80
write_com(basey+8); //(选下半屏)再写入水平位址
for(j=0;j<2;j++) //2个8位元的数据,即16BIT宽度
write_data(*bmp++);
}
}
write_com(0x36); //写完数据,开图片显示
}
/**************************************************************************************
** 函数名称: init_12864_GDRAM()
** 功能描述: 在程写GDRAM时序初始化12864
**************************************************************************************/
void init_12864_GDRAM()
{
write_com(0x30); //基本指令操作
write_com(0x0C); //整体显示开,游标关,游标位置关
write_com(0x06); //光标右移,DDRAM位址计数器(AC)加1,不整屏移动
lcm_clr(); //清屏 (清DDRAM)
}
/**************************************************************************************
//函数名称:Clean_12864_GDRAM(void)
//函数功能:清屏函数
//使用说明:GDRAM填满0
//************************************************************************************/
void Clean_12864_GDRAM(void)
{
uchar x,y;
write_com(0x36);
init_12864_GDRAM(); //设置扩展指令集,按手册说明,仅设置了绘图位,
write_com(0x36); //需要两次,本次设置扩展指令集。
for (y=0;y<32;y++)
{
write_com(0x80+y); //设置y=1000+00xx,y+1则往下一行
write_com(0x80); //设置x=1000 0000
for (x=0;x<16;x++)
{
write_data(0x00); //高字节数据
write_data(0x00); //低字节数据
}
}
}
/*-----------------------------------------------------------------------------------*/
#endif
我们用的是带字库的12864
|