淘宝店
Google
      
发新话题
打印

旋转LED时钟

旋转LED时钟


视屏效果在作者的博客上http://hi.baidu.com/52%5Fdiy/blog/item/9b1b8009a8a610256b60fba8.html
/**************************************************************************
作品名:旋转LED时钟
作者:李景良
所用芯片:AT89C2051+DS1302
程序长度325行(加注释加空行)
请珍惜作者的劳动成果,此程序未经作者许可,禁止传播或作为商业用途。
**************************************************************************/
#include <REG2051.H>     //定义头文件
#define uchar unsigned char //定义缩写字符
#define uint unsigned int
//以下定义DS1302时钟接口
sbit clock_clk=P3^4;
sbit clock_IO=P3^5;
sbit clock_Rst=P3^7;
//-----------------------------独立键盘定义
sbit Set1_Key= P3^0;//设定键
sbit Set2_Key= P3^1;//设定键进行调整
//-----------------------------定义累加器A中的各位
sbit a0=ACC^0;
sbit a1=ACC^1;
sbit a2=ACC^2;
sbit a3=ACC^3;
sbit a4=ACC^4;
sbit a5=ACC^5;
sbit a6=ACC^6;
sbit a7=ACC^7;
//以下定义全局变量
uchar sec,min,hour,k;
uint o;
//以下函数声明
uchar DSInputByte(void);                     //DS1302写入字节(底层协议)
void DSOutputByte(uchar dd);                 //DS1302读出字节(底层协议)
void write_clock(uchar ord,uchar dd);        //向DS1302写入数据
uchar read_clock(uchar ord);                 //从DS1302读出数据
void read_clockS(void);                      //常用时钟读取
void Reset_DS1302(void);                     //初始日期时间
void Set_time(uchar sel);                    //设置时间日期
void delay(uchar a);                         //延时
void display_s(uchar z);                     //执行扫描
void display_sm(uchar m);                    //位扫描
void key(void);                              //检测按键调时
//以下定义扫描数字字符的二维数组
uchar dispLed[11][5]=
{
      {0x82,0x7C,0x7C,0x7C,0x82},      //0
      {0xFF,0xBC,0x00,0xFC,0xFF},      //1
      {0xBC,0x78,0x74,0x6C,0x9C},      //2
      {0x7A,0x7C,0x5C,0x2C,0x72},      //3
      {0xE6,0xD6,0xB6,0x00,0xF6},      //4
      {0x1A,0x5C,0x5C,0x5C,0x62},      //5
      {0xC2,0xAC,0x6C,0x6C,0xF3},      //6
      {0x3F,0x7F,0x71,0x6F,0x1F},      //7
      {0x83,0x6D,0x6D,0x6D,0x83},      //8
      {0x9B,0x6D,0x6D,0x6D,0x83},      //9
      {0xFF,0xFF,0x92,0xFF,0xFF},      //显示小时、分、秒之间的:字符
};
uchar dispLed2[28]={0xFF,0x7D,0x00,0x7D,0xFF,0xC7,0x83,0xC1,0x83,0xC7,0xFF,0x03,0xFD,0xFD,0xFD,0x03,
                       0xFF,
                       0x00,0x6F,0x6F,0x6F,0x7F,     //F
           0xFF,
           0x00,0xFD,0xFD,0xFD,0xF9,     //L
           };
           //I心U图案
//===============================================主函数
void main(void)      //主函数
{
write_clock(0x8e,0x00); //允许写操作
      write_clock(0x90,0xa5); //打开充电二极管串联一个2K电阻
write_clock(0x8e,0x80); //禁止写操作
      o=0;
k=0;
TCON|=0x01; //外部中断0下降沿触发
IE=0x81; //开中断
while(1)     //死循环,此循环完成两项功能,1是等待中断,2是在没有中断时循环按键函数进行调时
{
key();     //调用调时函数
}
}
//************************************************以下对DS1320进行操作
void Reset_DS1302(void)     //将恢复初始日期时间函数,调整初始日期为2006年05月01日12时00分00秒星期一
{
     write_clock(0x8e,0x00); //允许写操作
     write_clock(0x8c,0x06); //年
     write_clock(0x8a,0x01); //星期
     write_clock(0x88,0x05); //月
     write_clock(0x86,0x01); //日
     write_clock(0x84,0x12); //小时
     write_clock(0x82,0x00); //分钟
     write_clock(0x80,0x00); //秒
     write_clock(0x8e,0x80); //禁止写操作
}
void DSOutputByte(uchar dd)      //DS1302读出字节(底层协议)
{
ACC=dd;
clock_IO=a0; clock_clk=1; clock_clk=0;
clock_IO=a1; clock_clk=1; clock_clk=0;
clock_IO=a2; clock_clk=1; clock_clk=0;
clock_IO=a3; clock_clk=1; clock_clk=0;
clock_IO=a4; clock_clk=1; clock_clk=0;
clock_IO=a5; clock_clk=1; clock_clk=0;
clock_IO=a6; clock_clk=1; clock_clk=0;
clock_IO=a7; clock_clk=1; clock_clk=0;
}
uchar DSInputByte(void) //DS1302写入字节(底层协议)
{
clock_IO=1;
a0=clock_IO;
clock_clk=1; clock_clk=0; a1=clock_IO;
clock_clk=1; clock_clk=0; a2=clock_IO;
clock_clk=1; clock_clk=0; a3=clock_IO;
clock_clk=1; clock_clk=0; a4=clock_IO;
clock_clk=1; clock_clk=0; a5=clock_IO;
clock_clk=1; clock_clk=0; a6=clock_IO;
clock_clk=1; clock_clk=0; a7=clock_IO;
return(ACC);
}
uchar read_clock(uchar ord) //DS1302读数据(底层协议)
{
uchar dd=0;
clock_clk=0;
clock_Rst=0;
clock_Rst=1;
DSOutputByte(ord);
dd=DSInputByte();
clock_Rst=0;
clock_clk=1;
return(dd);
}
void write_clock(uchar ord, uchar dd)     //DS1302写数据(底层协议)
{
clock_clk=0;
clock_Rst=0;
clock_Rst=1;
DSOutputByte(ord);
DSOutputByte(dd);
clock_Rst=0;
clock_clk=1;
}
void read_clockS(void)     //常用时钟数据读取
{
      sec=((read_clock(0x81))/16)*10 + (read_clock(0x81))%16;      //秒
min=((read_clock(0x83))/16)*10 + (read_clock(0x83))%16;       //分钟
hour=((read_clock(0x85))/16)*10+(read_clock(0x85))%16;      //小时
}
//调时用加1程序
void Set_time(uchar sel) //根据选择调整的相应项目加1并写入DS1302
{
     signed char add,item;
     signed char max,mini;
     if(sel==3)     {add=0x80; max=0;mini=0;}        //秒7
     if(sel==2)     {add=0x82; max=59;mini=0;}       //分钟6
     if(sel==1)     {add=0x84; max=23;mini=0;}       //小时5
     //读取1302某地址上的数值转换成10进制赋给item
     item=((read_clock(add+1))/16)*10 + (read_clock(add+1))%16;
      item++;//数值加1  
     if(item>max) item=mini;//查看数值有效范围   
     if(item<mini) item=max;           
     write_clock(0x8e,0x00);//允许写操作
     write_clock(add,(item/10)*16+item%10);//转换成16进制写入1302
     write_clock(0x8e,0x80);//写保护,禁止写操作  
}

//****************************************************以下扫描输出
void display(void) interrupt 0 //显示(中断处理)
{
      uchar c;
k=0; //退出调时状态
o++;
      if (o<80) //显示I心U
{
       delay(15);     //移位,使图案显示在中央位置
        for (c=0;c<28;c++)
         {
          P1=dispLed2[c];
          delay(2);
         }
       P1=0xFF;
}
else     //显示时间
{
        read_clockS();     //读出时间值
        display_sm(hour); //将小时值作为入口参数进行小时显示
        display_s(10);     //显示小时与分之间的冒号符号
        display_sm(min);     //将分钟值作为入口参数进行分钟显示
        display_s(10);     //显示分钟与秒之间的冒号符号
        display_sm(sec);     //将秒值作为入口参数进行秒显示
     }
if (o==500)     //当o等于500时,将o清零,再次显示I心U图案
        {
       o=0;
      }
}
void display_sm(uchar m) //位扫描
{
       display_s(m/10); //十位显示
     delay(2);
        switch (m%10)     //个位
         {
           case 0: //0
             display_s(0);
             break;
           case 1: //1
             display_s(1);
             break;
           case 2: //2
             display_s(2);
             break;
           case 3: //3
             display_s(3);
             break;
           case 4: //4
             display_s(4);
             break;
           case 5: //5
             display_s(5);
             break;
           case 6: //6
             display_s(6);
             break;
           case 7: //7
             display_s(7);
             break;
           case 8: //8
             display_s(8);
             break;
           case 9: //9
             display_s(9);
             break;
           }
}
void display_s(uchar z) //执行扫描
{
     uchar i;
     for (i=0;i<5;i++)
        {
        P1=dispLed[z];
        delay(2);
        }
      P1=0xFF;
}
//************************************************其它函数
void key(void) //检测按键并调时
{
     if(Set1_Key==0)     //正常显示时同时按下Set1_Key、Set2_Key二个键则初始化时间
         {
             delay(2);     //延时去抖动
             if(Set1_Key==0&&Set2_Key==0)
             {   
                Reset_DS1302(); //调用时间初始化函数
             }
         }
     if(Set1_Key==0)     //调时切换键按下切换调时的内容
          {
       delay(2);     //去抖
       if(Set1_Key==0)
                 {         
        k++;//切换累加变量     
          if(k>3)     //切换值超出后清0
                      {
            k=0;
          }
       while(Set1_Key==0)//等待键放开
           {  
           }
             }
      }
     if(Set2_Key==0)     //位加1键(使小时、分、秒加1)
          {
         delay(2);     //去抖
       if(Set2_Key == 0)
                 {
        switch(k)     //根据Set1_Key的按键次数进行数据调整
                    {
         case 1:
                       {
          Set_time(1);//秒调整
                       }
           break;
         case 2:
           {
          Set_time(2);//小时调整
           }
                       break;
         case 3:
                       {
          Set_time(3);//分钟调整
                       }
                       break;
                    }
            while(Set2_Key==0 )//等待按键释放
               {  
           }
              }
            }
}
void delay(uchar a) //延时函数
{
      uchar i;
while(--a!=0)
{
for (i=0;i<80;i++);
      }
}


[ 本帖最后由 电火花 于 2008-1-8 21:25 编辑 ]
附件: 您所在的用户组无法下载或查看附件

TOP

谢谢共享,没有看到视屏效果 。
淘宝店:http://shop33170822.taobao.com/

TOP

TOP

这个链接是视屏?没有啊~~

TOP

发新话题