PIC16F877A万年历程序
2012-12-05
Wujieflash
标签: 万年历 PIC

为了把KS0108系列的液晶吃透,特别制作了这款万年历,感觉效果还是不错的.希望大家分享我的喜悦,毕竟有了更多志同道合的朋友支持,我才能更进一步提高.

一,原理介绍

说明:

1.单片机还是采用PIC中最经典的PIC16F877A,端口多,功能全,特别是他有8K的ROM,这是我选择的主要原因,因为储存液晶的字库需要很大的空间.

2.液晶显示还是用的KS0108系列,主要是他性价比高,指令简单,特别是公司也在用.

3.时钟/日历芯片用的DALLOS的DS1302芯片,他可以储存从2000-2099年的日历,及实时时钟,可以方便的读写.

4.温度测量还是用的DS18B20,这在我上一实例中已经用过,有兴趣可以查阅.

5.本万年历可以显示实时时钟,精确到秒,年,月,日,星期,阴历,温度,生肖等,显示的信息量大.

6,可以通过按键自由设定时钟及日历,按"设置"键可以在秒,分,时,日,月,星期,年之间来回切换,要设置的单元以闪烁提醒.通过"+"."-"按键可以把要设置的单元设定到预想状态.

二,程序说明

:

本程序有许多小的模块,现分列如下:

1.主程序

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

* 标题:万年历*

* 作者:Wujieflash*

* 日期:2008年1月13日*

* 说明:包含文件

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

#include

#include "ziku.h"

#include "lcd_init.h"

#include "ds1302.h"

#include "ds18b20.h"

#include "keyscan.h"

#include "yinli.h"

//子程序

//LCD显示空白边框子程序

void LCDShowTable()

{

uch i;

SlectScreen(1);//写左半屏

SetLine(0);//起使页

SetColumn(0);//起使列

for(i=0;i

//显示固定字符子程序

void LCDShowGudingWord()

{

Show8X16_2(0,24,s0);

Show8X16_2(0,32,s0);

Show8X16(2,1,s0);

Show8X16(2,9,s0);

Show16X16_3(6,40,ri);

Show16X32(2,24,ss0);

Show16X32(2,40,ss0);

Show8X16_2(0,64,s0);

Show8X16_2(0,72,s0);

Show8X16_2(0,80,maohao);

Show8X16_2(0,88,s0);

Show8X16_2(0,96,s0);

Show8X16_2(0,104,maohao);

Show8X16_2(0,112,s0);

Show8X16_2(0,119,s0);

Show8X16(2,80,s0);

Show8X16(2,88,s0);

Show16X16_2(4,64,shiyi);

Show16X16_2(4,80,yue);

Show16X16_2(4,95,chu);

Show16X16_2(4,111,yi);

Show16X16_3(6,72,sheng);

Show16X16_3(6,88,xiao);

Show16X16_3(6,104,shu);

Show16X16_2(0,40,nian);

Show16X16(4,2,yue);

Show16X16_3(6,8,xing);

Show16X16_3(6,24,qi);

Show16X16(2,96,danwei1);

Show8X16_2(0,8,s2);

Show8X16_2(0,16,s0);

}

/*----------------------------------------------------------*/

//TRM1初始化子程序

void TMR1init()

{

//TRM1 INITIAL

T1CON=0X30;//8分频

TMR1IF=0;//清中断标志

TMR1IE=1;//使能定时器1中断

TMR1L=0XDB;//初始值(定时0.5S)

TMR1H=0X0B;

TMR1ON=1;//开定时器1

}

//冒号闪烁子程序

void FlashMaohao()

{

static uch timecount=0;

if(TMR1IF==1)

{

TMR1ON=0;

TMR1IF=0;

TMR1L=0XDB;//重新付初值

TMR1H=0X0B;

flag++;

flag=flag%2;//闪烁标志在0-1间翻转

TMR1ON=1;

timecount++;

if(timecount==120)//1分钟采样一次温度

{

timecount=0;

get_temp();//温度转换子程序

}

}

if(flag==0)

{

Show8X16_2(0,80,maohao);

Show8X16_2(0,104,maohao);

}

if(flag==1)

{

Show8X16_2(0,80,noshu);//清除

Show8X16_2(0,104,noshu);

}

}

//主程序

void main()

{

TMR1init();//定时器1初始化

keyinit();//键盘初始化

LCDinit();//LCD操作初始化

LCDShowTable();//显示空白表格

LCDShowGudingWord();//显示固定字符

//Set1302(DisCash);//设置初始时间(默认写入我写程序的时间)

get_temp();//读取温度

while(1)

{

v_Get1302(clock);//读取时间、日历

display();

YangToYin(clock[6]/16*10+clock[6]&0x0f,clock[4]/16*10+clock[4]&0x0f,clock[3]/16*10+clock[3]&0x0f);

FlashMaohao();//冒号闪烁

KeyScan();//键盘扫描

}

}

2.测温程序:

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

* 标题:DS18B20测温*

* 作者:Wujieflash*

* 日期:2008年1月13日*

* 说明:使用DS18B20芯片测温*

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

# define DQ RC3//定义18B20数据端口

# define DQ_DIR TRISC3//定义18B20D口方向寄存器

# define DQ_HIGH() DQ_DIR =1//设置数据口为输入

# define DQ_LOW() DQ = 0; DQ_DIR = 0//设置数据口为输出

unsigned charTLV=0 ;//采集到的温度高8位

unsigned charTHV=0;//采集到的温度低8位

unsigned char TZ=0;//转换后的温度值整数部分

//------------------------------------------------

//延时函数

//系统初始化函数

void init()

{

ADCON1=0X07;//设置A口为普通数字口

TRISA=0X00;//设置A口方向为输出

//TRISC3=0;//设置D口方向为输出

}

//-----------------------------------------------

//复位DS18B20函数

reset(void)

{

char presence=1;

while(presence)

{

DQ_LOW() ;//主机拉至低电平

delay(2,90);//延时503us

DQ_HIGH();//释放总线等电阻拉高总线,并保持15~60us

delay(2,8);//延时70us

if(DQ==1) presence=1;//没有接收到应答信号,继续复位

else presence=0;//接收到应答信号

delay(2,70);//延时430us

}

}

//-----------------------------------------------

//写18b20写字节函数

void write_byte(uch val)

{

uch i;

uch temp;

for(i=8;i>0;i--)

{

temp=val&0x01;//最低位移出

DQ_LOW();

NOP();

NOP();

NOP();

NOP();

NOP();//从高拉至低电平,产生写时间隙

if(temp==1)DQ_HIGH();//如果写1,拉高电平

delay(2,7);//延时63us

DQ_HIGH();

NOP();

NOP();

val=val>>1;//右移一位

}

}

//------------------------------------------------

//18b20读字节函数

uch read_byte(void)

{

uch i;

uch value=0;//读出温度

static bit j;

for(i=8;i>0;i--)

{

value>>=1;

DQ_LOW();

NOP();

NOP();

NOP();

NOP();//6us

DQ_HIGH();//拉至高电平

NOP();

NOP();

NOP();//4us

j=DQ;

if(j) value|=0x80;

delay(2,7);//63us

}

return(value);

}

//-------------------------------------------------

//启动温度转换函数

void get_temp()

{

int i;

DQ_HIGH();

reset();//复位等待从机应答

write_byte(0XCC);//忽略ROM匹配

write_byte(0X44);//发送温度转化命令

for(i=10;i>0;i--)

{

delay(201,132);//调用多次延迟函数,确保温度转换完成所需要的时间

}

reset();//再次复位,等待从机应答

write_byte(0XCC);//忽略ROM匹配

write_byte(0XBE);//发送读温度命令

TLV=read_byte();//读出温度低8

THV=read_byte();//读出温度高8位

DQ_HIGH();//释放总线

TZ=(TLV>>4)|(THV<<4);

}

3.日历显示程序

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

* 标题:DS1302读写*

* 作者:Wujieflash*

* 日期:2008年1月14日*

* 说明:日历显示范围:2000年--2099年*

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

#defineRSTRC0

#defineSCLK RC1

#defineIORC2

uch flag=0;

uch second=1,minute=1,hour=1,year=1,month=1,date=1,day=1;

uch clock[]={0};

uch DisCash[]={0x00,0x30,0x09,0x16,0x01,0x03,0x09};

/////往1302写入1Byte数据////////////////////////

void RTInputByte(uch d)

{

uch i;

TRISC=0x00;

for(i=8; i>0; i--)

{

IO = d&0x01;//取最低位

SCLK = 1;//上升沿发送

SCLK = 0;//恢复

d = d >> 1;

}

}

///////从1302读取1Byte数据////////////////////////

uch RTOutputByte(void)

{

uch i,val=0;

TRISC2=1;//设置为输入

for(i=8; i>0; i--)

{

val = val >>1;

if(IO)val=val|0x80;// 从最低位开始接收

SCLK = 1;//下降沿接收

SCLK = 0;

}

return(val);

}

///////先写地址,后写命令/数据//////////////////////////

void W1302(uch ucAddr, uch ucDa)

{

RST = 0;

SCLK = 0;

RST = 1;//打开DS1302

RTInputByte(ucAddr);// /* 地址,命令 */

RTInputByte(ucDa);// /* 写1Byte数据*/

SCLK = 1;

RST = 0;//关闭DS1302

}

///////先写地址,后读命令/数据////////////////////////

uch R1302(uch ucAddr)

{

uch ucData;

RST = 0;

SCLK = 0;

RST = 1;

RTInputByte(ucAddr);// /* 地址,命令 */

ucData = RTOutputByte();// /* 读1Byte数据 */

SCLK = 1;

RST = 0;

return(ucData);

}

/////////向1302写入 秒 分 时 日 月 星期 年 */////////////

void Set1302(uch *pClock)

{

uch i;

uch ucAddr = 0x80;//起使地址

W1302(0x8e,0x00);///* 控制命令,WP=0,允许写操作*/

for(i =7; i>0; i--)

{

W1302(ucAddr,*pClock);///* 秒 分 时 日 月 星期 年 */

pClock++;

ucAddr +=2;//写地址加2

}

W1302(0x8e,0x80);// /* 控制命令,WP=1,写保护*/

}

////////从1302读出 秒 分 时 日 月 星期 年 *//////////////////

void v_Get1302(unsigned charucCurtime[])

{

unsigned char i;

unsigned char ucAddr = 0x81;

for(i=0;i

/////////与LCD的显示接口//////////////////////

void display()

{

uch i;

for(i=0;i

4.按键扫描与服务程序

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

* 标题:按键扫描和服务*

* 作者:Wujieflash*

* 日期:2008年1月17日*

* 说明:当按键按下,选中的单元就会闪烁 *

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

uch k=0;

//键盘初始化子程序

void keyinit()

{

TRISD0=1;

TRISD0=1;

TRISD0=1;

}

/*----------------------------------------------------------*/

//键盘扫描子程序

void KeyScan()

{

int d;

if(RD0==0)//设置键按下

{

k++;//选定入口值

k=k%8;

}

while(1)

{

if(RD0==1)break;//等待按键松开

}

switch(k)//键盘服务入口

{

case 1://设置秒

{

d=R1302(0x81);//读取秒

d=d/16*10+d%16;//转换为16进制

second=flag;//设置秒的闪烁标志

minute=1;//其余变量不闪烁

hour=1;

year=1;

month=1;

date=1;

day=1;

if(second==0)//闪烁

{

Show8X16_2(0,111,noshu);

Show8X16_2(0,119,noshu);

}

if(RD1==0)//秒数值加1

{

d++;

if(d>0x3b)d=0;//大于59就为0

d=d/10*16+d%10;

W1302(0x80,d);//写入DS1302

while(1)

{

if(RD1==1)break;//等待键松开

}

}

if(RD2==0)//数值减1

{

d--;

if(d0x3b)d=0;

d=d/10*16+d%10;

W1302(0x82,d);

while(1)

{

if(RD1==1)break;

}

}

if(RD2==0)

{

d--;

if(d0x17)d=0;

d=d/10*16+d%10;

W1302(0x84,d);

while(1)

{

if(RD1==1)break;

}

}

if(RD2==0)

{

d--;

if(d0x1f)d=1;

d=d/10*16+d%10;

W1302(0x86,d);

while(1)

{

if(RD1==1)break;

}

}

if(RD2==0)

{

d--;

if(d0x0c)d=1;

d=d/10*16+d%10;

W1302(0x88,d);

while(1)

{

if(RD1==1)break;

}

}

if(RD2==0)

{

d--;

if(d0x07)d=1;

d=d/10*16+d%10;

W1302(0x8a,d);

while(1)

{

if(RD1==1)break;

}

}

if(RD2==0)

{

d--;

if(d0x63)d=0;

d=d/10*16+d%10;

W1302(0x8c,d);

while(1)

{

if(RD1==1)break;

}

}

if(RD2==0)

{

……

共 2 页   12下一页
可能会用到的工具/仪表
本站简介 | 意见建议 | 免责声明 | 版权声明 | 联系我们
CopyRight@2024-2039 嵌入式资源网
蜀ICP备2021025729号