PICFA万历程序.docx

上传人:b****7 文档编号:9451763 上传时间:2023-02-04 格式:DOCX 页数:29 大小:21.26KB
下载 相关 举报
PICFA万历程序.docx_第1页
第1页 / 共29页
PICFA万历程序.docx_第2页
第2页 / 共29页
PICFA万历程序.docx_第3页
第3页 / 共29页
PICFA万历程序.docx_第4页
第4页 / 共29页
PICFA万历程序.docx_第5页
第5页 / 共29页
点击查看更多>>
下载资源
资源描述

PICFA万历程序.docx

《PICFA万历程序.docx》由会员分享,可在线阅读,更多相关《PICFA万历程序.docx(29页珍藏版)》请在冰豆网上搜索。

PICFA万历程序.docx

PICFA万历程序

PIC16F877A万年历程序

时间:

2009-03-05 来源:

 作者:

Wujieflash 点击:

1581 字体大小:

【大中小】

   为了把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显示空白边框子程序

voidLCDShowTable()

{

 uchi。

 SlectScreen

(1)。

    //写左半屏

 SetLine(0)。

        //起使页

 SetColumn(0)。

      //起使列

 for(i=0。

i

//显示固定字符子程序

voidLCDShowGudingWord()

{

 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初始化子程序

voidTMR1init()

{

 //TRM1INITIAL

  T1CON=0X30。

      //8分频

  TMR1IF=0。

        //清中断标志

  TMR1IE=1。

        //使能定时器1中断

  TMR1L=0XDB。

      //初始值(定时0.5S)

  TMR1H=0X0B。

  TMR1ON=1。

        //开定时器1

}

//冒号闪烁子程序

voidFlashMaohao()

{

 staticuchtimecount=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)。

 }

}

//主程序

voidmain()

{

 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芯片测温               *

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

#defineDQRC3                               //定义18B20数据端口

#defineDQ_DIRTRISC3                        //定义18B20D口方向寄存器

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

#defineDQ_LOW()DQ=0。

DQ_DIR=0          //设置数据口为输出

 unsignedchar TLV=0。

                       //采集到的温度高8位

 unsignedchar THV=0。

                        //采集到的温度低8位

 unsignedcharTZ=0。

                          //转换后的温度值整数部分

 

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

//延时函数

//系统初始化函数

voidinit()

{

 ADCON1=0X07。

                               //设置A口为普通数字口

 TRISA=0X00。

                                //设置A口方向为输出

 //TRISC3=0。

                                //设置D口方向为输出

}

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

//复位DS18B20函数

reset(void)

{

 charpresence=1。

 while(presence)

 {

   DQ_LOW()。

                               //主机拉至低电平

   delay(2,90)。

                             //延时503us

   DQ_HIGH()。

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

   delay(2,8)。

                              //延时70us

   if(DQ==1)presence=1。

                    //没有接收到应答信号,继续复位

   elsepresence=0。

                         //接收到应答信号

   delay(2,70)。

                             //延时430us

  }

 }

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

//写18b20写字节函数

voidwrite_byte(uchval)

{

 uchi。

 uchtemp。

 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读字节函数

uchread_byte(void)

{

 uchi。

 uchvalue=0。

                               //读出温度

 staticbitj。

 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)。

}

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

//启动温度转换函数

voidget_temp()

{

inti。

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年 *

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

#define RST RC0

#define SCLKRC1

#define IO  RC2

uchflag=0。

uchsecond=1,minute=1,hour=1,year=1,month=1,date=1,day=1。

uchclock[]={0}。

uchDisCash[]={0x00,0x30,0x09,0x16,0x01,0x03,0x09}。

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

voidRTInputByte(uchd)

{

   uchi。

   TRISC=0x00。

   for(i=8。

i>0。

i--)

   {

     IO=d&0x01。

     //取最低位

     SCLK=1。

        //上升沿发送

     SCLK=0。

        //恢复

     d=d>>1。

      

   }

}

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

uchRTOutputByte(void)

{

   uchi,val=0。

   TRISC2=1。

           //设置为输入

   for(i=8。

i>0。

i--)

   {

     val=val>>1。

        

     if(IO)val=val|0x80。

//从最低位开始接收

     SCLK=1。

         //下降沿接收

     SCLK=0。

   }

    return(val)。

}

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

voidW1302(uchucAddr,uchucDa)

{

   RST=0。

   SCLK=0。

   RST=1。

                 //打开DS1302

   RTInputByte(ucAddr)。

     ///*地址,命令*/

   RTInputByte(ucDa)。

       ///*写1Byte数据*/

   SCLK=1。

   RST=0。

                 //关闭DS1302

}

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

uchR1302(uchucAddr)

{

   uchucData。

   RST=0。

   SCLK=0。

   RST=1。

   RTInputByte(ucAddr)。

           ///*地址,命令*/

   ucData=RTOutputByte()。

       ///*读1Byte数据*/

   SCLK=1。

   RST=0。

   return(ucData)。

}

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

voidSet1302(uch*pClock)

{

   uchi。

   uchucAddr=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读出秒分时日月星期年*//////////////////

voidv_Get1302(unsignedchar ucCurtime[])

{

unsignedchari。

unsignedcharucAddr=0x81。

for(i=0。

i

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

voiddisplay()

{

 uchi。

 for(i=0。

i

4.按键扫描与服务程序

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

*标题:

按键扫描和服务                            *

*作者:

Wujieflash                                    *        

*日期:

2008年1月17日                            *

*说明:

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

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

uchk=0。

//键盘初始化子程序

voidkeyinit()

{

 TRISD0=1。

 TRISD0=1。

 TRISD0=1。

}

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

//键盘扫描子程序

voidKeyScan()

{

 intd。

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

 {

 k++。

   //选定入口值

 k=k%8。

 }

 while

(1)

 {

 if(RD0==1)break。

//等待按键松开

 }

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

 {

 case1:

//设置秒

 {

  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)//

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 表格模板 > 合同协议

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1