找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 606|回复: 1
打印 上一主题 下一主题
收起左侧

基于DS1302时钟液晶12864显示2路闹钟仿真及源程序

[复制链接]
跳转到指定楼层
楼主
一、系统方案
1、本设计采用51单片机作为主控器。
2、DS1302采集年月日时分秒送到液晶12864显示。
3、按键年月日时分秒,两路闹钟。


二、硬件设计
原理图如下:
三、单片机软件设计
1、首先是系统初始化
   uchar clock_time[6] = {0X00,0X59,0X23,0X09,0X04,0X11};        //定义时间变量 秒  分 时 日 月 年
        uchar alarm_time[2] =  { 10, 6}; //闹钟设置  alarm_time[0]: 分钟  alarm_time[1] :小时
        uchar alarm_time2[2] = { 15, 7};
    Lcd_Initial();     //LCD初始化
Clock_Fresh( clock_time ); //我把时间刷新放在这里,proteus会调用当前系统时间,
        Clock_Initial( clock_time ); //时钟初试化

        /***********************中断初始化***************************/
    EA = 1; //开总中断
    ET0 = 1;  //Timer0 开中断
    TMOD = 0x01; //Timer0 工作方式 1
    TH0 = 0x3c;
    TL0 = 0XB0;   //延时 50 ms
2、液晶显示程序

void showXY(uchar row,uchar col,uchar x,uchar y,uchar *tab){
        uchar i,j;
        bit right;
        if(col<64){right=0;}
        else {col-=64;right=1;}        
        for(i=0;i<y;i++){
                if(right)cs1=1,cs2=0;
                else  cs1=0,cs2=1;
                Lcd_Write_Command(addX0+row+i);
                Lcd_Write_Command(addY0+col);   
                for(j=0;j<x;j++){
                        if(col+j<64)Lcd_Write_Byte(tab[i*x+j]);
                        else if(right==0)
                                {                 
                                 cs1=1,cs2=0;                 
                                Lcd_Write_Command(addX0+row+i);         
                                 Lcd_Write_Command(addY0+(col+j-64));
                                Lcd_Write_Byte(tab[i*x+j]);
                         }                                                
                }
        }
}
/* 返回一个8*16字符索引位置 */                                       
uchar enN(uchar *s){
        uchar i;
        for(i=0;zm8x16_index[ i]!=0;i++)
[ i]                if(zm8x16_index[ i]==s[0])break;
        return i;        
}
/* 返回一个16*16字符索引位置 */
uchar cnN(uchar *s){
        uchar i;
        for(i=0;zm16x16_index[ i]!=0;i+=2)
                if(zm16x16_index[ i]==*s&&zm16x16_index[i+1]==*(s+1))break ;
        return i/2;
}
/* 显示中英文字符串 */
void showStr(uchar row,uchar col,uchar *s)
{
         uchar i;
         for(i=0;s[ i]!=0;i++){
                 if(s[ i]<0x80){
                        showXY(row,col,8,2,zm8x16_Table[enN(&s[ i])]);
                        col+=8;
                }else{                        
                        showXY(row,col,16,2,zm16x16_Table[cnN(&s[ i])]);     
                        col+=16;i+=1;               
                }
                if(col>120)
                {         
                        col=0;
                        row+=2;
                }
         }
}
3、按键程序
/********************************************************************************************
* 函数名称:Key_Idle()
* 功    能:键盘松开
* 入口参数:无
* 出口参数:无
*********************************************************************************************/
void Key_Idle()
{
   while( ( P1 & 0x0f ) != 0x0f );
}

/********************************************************************************************
* 函数名称:Key_Scan()
* 功    能:键盘扫描
* 入口参数:无
* 出口参数:键值
*********************************************************************************************/
uchar Key_Scan()
{
   if( ( P1 & 0x0f ) != 0x0f )         //判断按键
   {
       Delay(10);                  //消除抖动
                  // Lcd_Initial();
       if( ( P1 & 0x0f ) != 0x0f )
           {        
          switch ( P1 & 0x0f )              //将按键码转换成键值
          {  
             case  0x0e: return  up_array;  
             case  0x0d: return  down_array;
             case  0x0b: return  clear_array;
             case  0x07: return  function_array;
             default :   return  null;
          }
           }         
   }
   return null;
}
4、核心算法程序
void main( void )
{         
    uchar clock_time[6] = {0X00,0X59,0X23,0X09,0X04,0X11};        //定义时间变量 秒  分 时 日 月 年
        uchar alarm_time[2] =  { 10, 6}; //闹钟设置  alarm_time[0]: 分钟  alarm_time[1] :小时
        uchar alarm_time2[2] = { 15, 7};
    Lcd_Initial();     //LCD初始化
Clock_Fresh( clock_time ); //我把时间刷新放在这里,proteus会调用当前系统时间,
        Clock_Initial( clock_time ); //时钟初试化

        /***********************中断初始化***************************/
    EA = 1; //开总中断
    ET0 = 1;  //Timer0 开中断
    TMOD = 0x01; //Timer0 工作方式 1
    TH0 = 0x3c;
    TL0 = 0XB0;   //延时 50 ms

    while( 1 )
        {

                 {
                      Clock_Fresh( clock_time ); //时间刷新
              Lcd_Clock( clock_time );   //时间显示            

              Calendar_Convert( 0 , clock_time );
                          Week_Convert( 0, clock_time );

              //闹钟1报警
              if( * alarm_time == HexNum_Convert(* ( clock_time + 1 ) )) //分钟相吻合
                             if( * ( alarm_time + 1 ) == HexNum_Convert(*( clock_time + 2 )) ) //小时相吻合
                                 {        
                                     if(HexNum_Convert(*( clock_time )) == 2)
                                                 TR0 = 1; //启动Timer0
                                 }
                          //闹钟2报警
                          if( * alarm_time2 == HexNum_Convert(* ( clock_time + 1 ) )) //分钟相吻合
                             if( * ( alarm_time2 + 1 ) == HexNum_Convert(*( clock_time + 2 )) ) //小时相吻合
                                 {
                                         if(HexNum_Convert(*( clock_time )) == 2)
                                                 TR0 = 1; //启动Timer0
                                 }
           }
                switch( Key_Scan() )
       {
          case up_array:  
          {
              //Lcd_Initial();
                                                Key_Idle();
          }
           break;     
          case down_array:   
          {
                      // Lcd_Initial();
                                                Key_Idle();
                  }
          break;                  
                  case clear_array:   
          {   
                       // Lcd_Initial();
                                                Key_Idle();
              }
                  break;
                  case function_array:
                  {
                //Lcd_Initial();
                                Key_Function( clock_time, alarm_time ,alarm_time2);
          }
                        break;
                  case null:      

                   break;
         }
        }
}
四、 proteus仿真设计
Proteus软件是一款应用比较广泛的工具,它可以在没有硬件平台的基础上通过自身的软件仿真出硬件平台的运行情况,这样就可以通过软件仿真来验证我们设计的方案有没有问题,如果有问题,可以重新选择器件,连接器件,直到达到我们设定的目的,避免我们搭建实物的时候,如果当初选择的方案有问题,我们器件都已经焊接好了,再去卸载下去,再去焊接新的方案的器件,测试,这样会浪费人力和物力,也给开发者带来一定困惑,Proteus仿真软件就很好的解决这个问题,我们在设计之初,就使用该软件进行模拟仿真,测试,选择满足我们设计的最优方案。最后根据测试没问题的仿真图纸,焊接实物,调试,最终完成本设计的作品。

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:688460 发表于 2023-11-12 18:35 | 只看该作者
程序不完整,群主应该不给予黑币奖励!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表