您的位置:首页版主原创PIC示例程序
内容搜索: 标题内容作者
     
阅读内容
背景:#EDF0F5 #FAFBE6 #FFF2E2 #FDE6E0 #F3FFE1 #DAFAF3 #EAEAEF 默认  

LED电子闹钟16F72(已调试OK)

[日期:2007-12-29 ] [来源:www.picavr.com 作者:本站原创] [字体: (投递新闻)
 
用PIC16F72做的带闹钟定时时钟
 
16F72带闹钟定时时钟

//*APPLICATION NOTE  E6000 ICEXPLORER ***************
//* Title:           FOR colk_time                  *
//* Version:         00                             *
//* Last Updated:                                   *
//* MCU:             PIC16F72                       *
//* FOR:             WWW.PICAVR.COM                 *
//***************************************************
//****ROM  PCLATH.D3=0  000H-7FFH                   ;
//  PCLATH.D3=1  800H-FFFH                     ;
//***************************************************
//** RAM    BANK0=20H---7FH STATUS RP0=0,RP1=0  *
//**        BANK1=A0H---FFH STATUS RP0=1,RP1=0  *
//***************************************************
//               __________________
//    MCLR/VPP/TH-| 1         28 |-RB7/PGD
//   RA0/AN0-| 2           27 |-RB6/PGC
//        RA1/AN1-| 3         26 |-RB5
// RA2/AN2/VRref--| 4           25 |-RB4
// RA3/AN3/VRref+-| 5           24 |-RB3/PGM
//      RA4/TOCKI-| 6           23 |-RB2
//     RA5/AN4/SS-| 7           22 |-RB1
//            VSS-| 8           21 |-RB0/INT
//     OSC1/CLKIN-| 9           20 |-VDD
//    OSC2/CLKOUT-| 10         19 |-VSS
// RC0/TISO/TICKI-| 11          18 |-RC7/RX/DT
// RC1/T1OSI/CCP2-| 12          17 |-RC6/TX/CK
//    RC2/CCP1-| 13          16 |-RC5/SDO
//    RC3/SCK/SCL-| 14          15 |-RC4/SDA
//                |________________|
//                       16F72
//***************************************************
#include <pic.h>                  //
#include <stdio.h>                //
#include <math.h>                 //
#define uchar unsigned char       //
#define uint unsigned int         //
//------------------------------------------
#define KEY_UP RA4                //
#define KEY_DOWN RA5              //
#define KEY_SET RA3               //
//------------------------------------------
void com_buf(void);               //
void display(void);               //
void buf_initial(void);           //
void ad_program(void);            //
void add_colk(void);              //
void keywork1(void);              //
void PORT_DATA(void);             //
void sub_colk(void);              //
void timr0int(void);              //
void colk_stt(void);              //
//------------------------------------------
static volatile unsigned char ADRES @ 0x1E;
static volatile unsigned char FLAG1 @ 0x20; //可位寻址的状态寄存器

static volatile bit SET   @ (unsigned) &FLAG1 * 8 + 2; //
static volatile bit UP   @ (unsigned) &FLAG1 * 8 + 1; //
static volatile bit DOWN  @ (unsigned) &FLAG1 * 8 + 0; //
//----------------------------------------------------
static bit B_JIAN0,B_JIAN1,B_JIAN2,B_JIAN3,B_ON,B_OFF,B_BUF,B_ADD;
static bit B_DP,B_COM,B_END;//
unsigned char buf[4];    //
unsigned char k,data,sreg,disppoint,msec,sec,ad_buf,SEL,spbuf;  //
unsigned char T_ON0,T_ON1,T_ON2,T_ON3,T_OFF0,T_OFF1,T_OFF2,T_OFF3; //
unsigned char colk0,colk1,colk2,colk3; //
unsigned int  i,kcon1,kcon2,PORT_BUF;  //
const char table[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xd8,0x80,0x90}; //
//*********************************
/*延时函数*/
//*********************************
void delay_10ms()                //
{ uint j;                        //
    for(j=0;j<300;j++)           //
    {;}                          //
}                                //
//*********************************
void delay_50us()                //
{ uchar j;                       //
    for(j=0;j<20;j++)            //
    {;}                          //
}                                //
//=================================
//延时最大255毫秒
//=================================
void delay_ms(uchar ms)    //
{
  uchar i,j;               //
  for(j=0;j<ms;j++)        //
    for(i=0;i<86;i++)     //
    {
      #asm                 //
      nop                  //
      nop                  //
      #endasm              //
    }
}
//==================================


//**********************************
void delay_1s()            //延时1S
{
 uint j;                   //
    for(j=0;j<200;j++);     //
     {
     display();             //
     keywork1();            //
     }
}
//********************************
void ds_sp()                //报警程序
{
 uchar i;                   //
 uint j;                    //
 for(i=0;i<100;i++)          //
   {
    for(j=0;j<20;j++);      //
      {
       display();           //
       keywork1();          //
      }
      RA2=!RA2;             //
    }
  RA2=0;                    //  
}
//*********************************
void sp()                   //
{
  uchar i;                  //
  for(i=0;i<20;i++)          //
   {
     if(B_END==1)
        {
         B_COM=1;           //
         return;            //
        }
     ds_sp();               //
     delay_1s();            //
   }
}
//*******************************
//显示清0程序
//*******************************
void buf_initial()     //
{
   buf[0]=0X00;        //
   buf[1]=0X00;        //
   buf[2]=0X00;        //
   buf[3]=0X00;        //
   T_ON0=0X00;T_ON1=0X07;T_ON2=0X00;T_ON3=0X00; //
   T_OFF0=0X00;T_OFF1=0X07;T_OFF2=0X00;T_OFF3=0X05;//
   sreg=0x00;          //
   msec=0x00;          //                     
}                      //
//**********************************

//**********************************
void put_num(char c)
{
  PORTB=table[c&0x0f]; //
  RB7=0;               //
  if(B_DP==0)          //
    {
      RB7=1;           //
     }
}
//*********************************

//**********************************
//显示子程序
//**********************************
void display()         //
{
  disppoint=0;         //
  put_num(buf[disppoint]); //
  RC4=0;               //
  delay_ms(1);         //
  RC4=1;               //

  disppoint++;         //
  put_num(buf[disppoint]); //
  RC5=0;               //    
  delay_ms(1);         //
  RC5=1;               //
  CLRWDT();            //
  disppoint++;         //
  put_num(buf[disppoint]); //
  RC6=0;               //
  delay_ms(1);         //
  RC6=1;               //

  disppoint++;         //
  put_num(buf[disppoint]); //
  RC7=0;               //
  delay_ms(1);         //
  RC7=1;               //
}
//*********************************

//*********************************
//AD转换初始化子程序   //
//*********************************
void ad_program()      //
{
   TRISA=0XFF;         //
   ADCON1=0B00000010;  //AN0-AN4=A VREF=VDD
   PIE1=0;             //

   ADCON0=0B01001001;  //fosc/8 RA1/AN1 ADON=1
   INTCON=0;           //
   ADIF=0;             //
   ADRES=0;            //
   delay_50us();       //
   ADGO=1;             // GODONE=1
   while(ADIF==0);     //
    {
     ;
     }                 //
   ad_buf=ADRES;       //
   ADCON1=0B00000111;  //  RA0-RA5=D
   TRISA=0X38;         //  RA3-RA5=IN
   ADCON0=0B00000000;  //fosc/2 RA0/AN0 ADON=0
}
//*********************************


//*********************************
//tmr0初始化子程序
//*********************************
void timr0int()
{
  T0CS=0;        //tmr0工作于定时器方式
  PSA=1;         //tmr0不用分频
  T0IF=0;        //清除tmr0的中断标志
  T0IE=1;        //tmr0中断允许
}
//**********************************


//**********************************
//按键等待程序
//**********************************
void keywait()                   //
{
   while((PORTC & 0x06)!=0x06)   //
     {
      display();                 //
     }                           //
}                                //
//**********************************
void keywait1()                  //
{
   while((PORTA & 0x08)!=0x08)   //
     {
      display();                 //
     }                           //
}                                //
//************************************

//*****************************************
//当前时间与开机,关机时间比较
//*****************************************
void com_buf()
{                                        //
  if((T_ON0==buf[0])&&(T_ON1==buf[1])&&(T_ON2==buf[2])&&(T_ON3==buf[3]))                      //
               {                         //
                RC3=1;return;            //
                }                        //

     else if((T_OFF0==buf[0])&&(T_OFF1==buf[1])&&(T_OFF2==buf[2])&&(T_OFF3==buf[3]))
               {
                RC3=0;                   //
                B_COM=1;                  //
                sp();                    //
                return;                  //
                }                        //
}                                        //
//******************************************


//******************************************
//时钟显示程序
//******************************************
void add_colk()
{
   CLRWDT();     //
   buf[3]++;     //
   B_COM=0;      //
   B_END=0;      //
   if(buf[3]>9) //
     {
       buf[3]=0;  //
       buf[2]++;   //
       if(buf[2]>5) //
 {
          buf[2]=0;  //
          buf[1]++;  //
//----------------------------------
   if(buf[1]==4) //
             {
               if(buf[0]==2)
                  {
                    buf[0]=0; //
                    buf[1]=0; //
                    return;   //
                   }
                return;       //
              }
//----------------------------------
           else if(buf[1]>9)
               {
                 buf[1]=0;   //
                 buf[0]++;   //
                }
           }
       }
}
//**********************************

//**********************************
void sub_colk()
{
   CLRWDT();     //
   if(buf[3]!=0)     //
       {
         buf[3]--;   //
         return;     //
       }
       buf[3]=9;
       if(buf[2]!=0) //
         {
           buf[2]--; //
           return;   //
          }
        buf[2]=5;
        if(buf[1]!=0) //
           {
             buf[1]--;  //
             return;    //
           }
         buf[1]=9;
         if(buf[0]!=0)  //
             {
               buf[0]--; //
               return;   //
             }
           buf[1]=3;     //
           buf[0]=2;     //
}
//***************************************************
void colk_to_time_on()
{
  T_ON0=buf[0];T_ON1=buf[1];T_ON2=buf[2];T_ON3=buf[3];   //
}
//---------------------------------------------------
void colk_to_time_off()
{
  T_OFF0=buf[0];T_OFF1=buf[1];T_OFF2=buf[2];T_OFF3=buf[3];//
}
//---------------------------------------------------
void colk_to_disp_buf()
{
  colk0=buf[0];colk1=buf[1];colk2=buf[2];colk3=buf[3];   //
}
//***************************************************
void colk_stt()
{
  CLRWDT();     //
  if(KEY_UP==0)    //
        {
         B_ADD=1;   //
        }
   if(KEY_DOWN==0)
         {
           B_ADD=0; //
          }
//-----------------------------------
    if(B_ON==1)
         {
           if(B_ADD==0)  //
              {
               add_colk();    //
               colk_to_time_on(); //
               return;
              }
             sub_colk();   //
             colk_to_time_on();  //
             return;
         }
//------------------------------------
     if(B_OFF==1)
         {
            if(B_ADD==0)  //
                {
                 add_colk();   //
                 colk_to_time_off();//
                 return;
                }
              sub_colk();
              colk_to_time_off(); //
              return;
          }
//------------------------------------------
      if(B_BUF==1)
             {
              if(B_ADD==0)    //
                {
                 add_colk();  //
                 colk_to_disp_buf(); //
                 return;
                }
               sub_colk();    //
               colk_to_disp_buf();    //
               return;
            }
}
//*********************************************
void PORT_DATA()
{
   TRISC=0X01;       //RC7--RC1清0为输出,RC0置1为输入
   RA0=1;            //开LED显示
   PORTC=PORT_BUF;   //按键扫描完成后恢复I/O口状态
}  
//*********************************************
//按键处理子程序       //
//*********************************************
void keywork1()
{
  if(B_JIAN1==1)   //连加标志位   B_JIAN1=1
        {
//-------------------------------------------------------
JIAN_add:  if(B_JIAN0==0)    //按键按下时间为3S后置B_JIAN0=1 ,B_JIAN1=0为点动按键
            {
               if(B_JIAN1==0)   //B_JIAN1=1时, 计算第一次按下的时间,B_JIAN1=0为点动按键
                  {
                    delay_10ms();
                    if((KEY_UP==0)||(KEY_DOWN==0))
                       {
                         B_JIAN1=1;  //KEY_UP 按下,B_JIAN1=1
                         CLRWDT();   //
//______________________________________________________
JIAN_add1:             if((KEY_UP==0)||(KEY_DOWN==0)) //
                           {
                             if(KEY_UP==0)     //
                                 {
                                   B_ADD=1; //时间减标志位
                                  }
                               if(KEY_DOWN==0)   //
                                    {
                                     B_ADD=0; //时间加标志位
                                    }
                                 if((--kcon1)==0)  //
                                    {
                                     kcon1=500;    //设置第一次按键的计数值
                                     B_JIAN0=1;    //
                                     colk_stt();   //时间加
                                     return; //子程序返回
                                    }
                                  else
                                     {
                                       return;//子程序返回
                                     }
                               }
                         B_JIAN0=0;B_JIAN1=0;B_JIAN2=0;B_JIAN3=0; //清除按键标志位
                         colk_stt();   // 时间+1
                         return;//子程序返回
                       }
                    else
                       {
                          return; //子程序返回
                       }
                  }
               goto JIAN_add1; // B_JIAN1=1时,转JIAN_add1计算RB7按下的时间
//_________________________________________________________________________
          }
          if((KEY_UP==0)||(KEY_DOWN==0)) //
             {
//_________________________________________
              if((--kcon1)==0)    //
                    {
                      kcon1=20;     //设置按键连加时的速度计数值
                      colk_stt();   //
                      return;//子程序返回
                    }
                else
                   {
                     return;       //子程序返回
                   }
             }
          B_JIAN0=0;B_JIAN1=0;B_JIAN2=0;B_JIAN3=0;
          return;
      }
//---------------------------------------------
  else if((KEY_UP==0)||(KEY_DOWN==0))       //比较KEY_UP键按下否
       {
        goto JIAN_add;   //RB7=0, KEY_UP按下,转到连加处JIAN_ADD
       }
//----------------------------------------------
    else if((PORTA&0x08)!=0x08)   //重读P1.2-P1.4位,若还是不全为1,定有键按下
       {
         delay_10ms();
         if((PORTA&0x108)!=0x08)
            {
              di();      //
              B_DP=0;B_COM=1;B_END=1;//
              SEL++;     //
              if(SEL==0X01)    //
                  {
                     keywait1();      //
                     RC1=0;RC2=1;     //
                    
                     buf[0]=T_ON0; buf[1]=T_ON1; buf[2]=T_ON2; buf[3]=T_ON3; //
                     B_ON=1;B_OFF=0,B_BUF=0; //
                     return;
                  }
                if(SEL==0X02)
                    {
                      keywait1();      //
                      RC1=1;RC2=0;     //
                     
                      buf[0]=T_OFF0; buf[1]=T_OFF1; buf[2]=T_OFF2; buf[3]=T_OFF3; //
                      B_ON=0;B_OFF=1,B_BUF=0; //
                      return;
                    }
                  if(SEL==0X03)
                     {
                      keywait1();
                      RC1=1;RC2=1;     //
                     
                      buf[0]=colk0; buf[1]=colk1; buf[2]=colk2; buf[3]=colk3; //
                      SEL=0x00;sreg=0x00; msec=0x00;sec=0x00; B_ON=0; B_OFF=0,B_BUF=1;  //
                      ei();   //开总中断
                      TMR0=0X14;      //TMR0置初值
                      return;
                     }

               }
        }
//----------------------------------------------------------
  B_JIAN0=0;B_JIAN1=0;B_JIAN2=0;B_JIAN3=0; //清除按键标志位
  kcon1=20;                                //
  CLRWDT();     //
}
//***********************************************************

//***********************************************************
//按键处理子程序       //
//***********************************************************
void keywork()               //
{
  if((PORTC&0x06)!=0x06)     //如果P1.2--P1.4不为全1,可能有键按下
   {
     delay_10ms();           //延时去抖动
     if((PORTC&0x06)!=0x06)  //重读P1.2-P1.4位,若还是不全为1,定有键按下
         {
//----------------------------------
            if (KEY_SET==0)       //按下SET键,如在SET状态就退出,否则进入
                {
                   keywait();
                   ei();          //
                   TMR0=0X08;     //
                   return;        //
                 }
             else if (KEY_UP==0)   //按下UP键
                    {
                      keywait();   //
                      buf_initial(); //
                      di();        //
                      return;
                    }
           }
     }
   else if((PORTA&0x10)!=0x10)     //如果P1.2--P1.4不为全1,可能有键按下
       {
        delay_10ms();           //延时去抖动
        if((PORTA&0x10)!=0x10)  //重读P1.2-P1.4位,若还是不全为1,定有键按下
             {
                di();           //
                keywait1();     //
                add_colk();     //
                return;
              }
       }
}
//*******************************


//*******************************
//****** Tmr0中断程序 ***********
//*******************************
void interrupt clkint(void)
{
  TMR0=0x14;        //
  T0IF=0;           //
  CLRWDT();         //       
  sreg=sreg+1;      //
  if(sreg==40)      //
   {
    sreg=0;         //
    msec=msec+1;    //
    if(msec>99)     //
      {
        msec=0;     //
        B_DP=!B_DP; //
        sec=sec+1;  //
       if(sec>59)    //
          {
           sec=0;      //
           add_colk(); //
          }
       }
   }  
}
//*******************************
//主函数
//*******************************
void main(void)    //
{
  OPTION=0;        //
  ADCON1=0x07;     //  RA0-RA5=D
  ADCON0=0B01001001;//


  TRISA=0x38;      //00111000= RA3,RA4,RA5
  TRISB=0X00;      //
  TRISC=0X01;      //

  PORTB=0x00;      //
  PORTC=0X07;      //
  PORTA=0x38;      //

  B_DP=0;          //
  B_COM=0;         //
  B_END=0;         //
  B_ON=0; B_OFF=0,B_BUF=1;//
  timr0int();      //
  buf_initial();   //
  di();            //
  while(1)         //
   {
     CLRWDT();     //
     display();    //
     keywork1();   //
    
       if(B_COM==0)  //
       {
        com_buf();  //
       }
   }
}

PCB图:


PIC16F72做的带闹钟定时时钟(PCB图)

 

阅读:
录入:admin

推荐 】 【 打印
上一篇:PIC16F877A实验板(图)
下一篇:
本文评论
      全部评论
发表评论


点评: 字数
姓名:
赞助商广告