打印

ARM7上外接实时时钟

[复制链接]
2091|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
riberey|  楼主 | 2008-4-28 16:05 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

请教各位大侠:
小弟正在做一个实时时钟,用的是周工板LPC2114和DS1302,具体的程序如下:但是最后得到的数据全是0xFF?
还有就是我量了下我的硬件,晶振的一脚为0,另一脚为2.664V,是不是晶振那里有问题?其他硬件基本都没有问题,但也不排除。
求助中 ,五一之前就要搞定,要不然就.........,
我也知道,看程序是一个痛苦的过程,在此道歉。
程序如下:
/****************************************************************************
* 文件名:RTC.C
* 功能:  
* 说明:
*      
*      
****************************************************************************/
#include  "config.h"
#define   T_RST       (1<<14)        /* P0.14  实时时钟复位线引脚 */ 
#define   T_IO        (1<<15)        /* P0.15  实时时钟数据线引脚 */ 
#define   T_CLK       (1<<16)          /* P0.16  实时时钟时钟线引脚 */ 
#define   T_INCON     0x00014000        /* 定义写端口设置字          */ 
#define   T_OUTCON    0x0001c000       /* 定义读端口设置字          */ 
uint8 Read[7];                         /*定义数据存储器*/
void Hold(uint32  dly)                 /*延时*/
{   
   for(; dly>0; dly--); 


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

* 名称: v_RTInputByte 
* 说明:  
* 功能: 往DS1302写入1Byte数据 
* 调用: 
* 输入: ucDa 写入的数据  
* 返回值: 无 
***********************************************************************/ 
void v_RTInputByte(uint8 ucDa)  
{  
uint8 i;
IO0DIR = T_OUTCON; 
for(i=8; i>0; i--) 

if((ucDa&0x01) != 0) 
   IO0SET = T_IO; 
else 
   IO0CLR = T_IO; 
Hold(10); 
IO0SET = T_CLK; 
Hold(20); 
IO0CLR = T_CLK; 
Hold(10); 
ucDa >>= 1;      /*相当于汇编中的 RRC*/
}  
}
/********************************************************************  

* 名称: uchar uc_RTOutputByte 
* 说明:  
* 功能: 从DS1302读取1Byte数据 
* 调用:  
* 输入:  
* 返回值: ucDa 
***********************************************************************/ 
uint8 uc_RTOutputByte(void)  
{  
uint8 i; 
uint8 ucDa=0; 
IO0DIR = T_INCON; 
for(i=8; i>0; i--) 

Hold(10); 
ucDa>>= 1;           /*相当于汇编中的 RRC */ 
if((IO0PIN&T_IO) !=0 )
    ucDa += 0x80; 
IO0SET = T_CLK; 
Hold(20); 
IO0CLR = T_CLK; 
Hold(10); 
}  
return(ucDa);  

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

* 名称: v_W1302 
* 说明: 先写地址,后写命令/数据 
* 功能: 往DS1302写入数据 
* 调用: v_RTInputByte()  
* 输入: ucAddr: DS1302地址, ucDa: 要写的数据 
* 返回值: 无 
***********************************************************************/ 
void v_W1302(uint8 ucAddr, uint8 ucDa) 

IO0CLR = T_CLK;     /*T_CLK = 0;*/
IO0CLR = T_RST;      /*T_RST = 0;*/ 

Hold(40); 
IO0SET = T_RST;           /*T_RST = 1;*/ 
v_RTInputByte(ucAddr);     /* 地址,命令 */ 
v_RTInputByte(ucDa);       /* 写1Byte数据*/ 
IO0SET = T_CLK;          /*T_CLK = 1;*/ 
IO0CLR = T_RST;         /*T_RST = 0;*/ 
Hold(40); 
}  
/********************************************************************  

* 名称: uc_R1302 
* 说明: 先写地址,后读命令/数据 
* 功能: 读取DS1302某地址的数据 
* 调用: v_RTInputByte() , uc_RTOutputByte() 
* 输入: ucAddr: DS1302地址 
* 返回值: ucDa :读取的数据 
***********************************************************************/ 
uint8 uc_R1302(uint8 ucAddr) 

uint8 ucDa; 
IO0CLR = T_RST;          /*T_RST = 0;*/ 
IO0CLR = T_CLK;         /*T_CLK = 0;*/ 
Hold(40); 
IO0SET = T_RST;              /*T_RST = 1;*/ 
v_RTInputByte(ucAddr);       /* 地址,命令 */ 
ucDa = uc_RTOutputByte();      /* 读1Byte数据 */ 
IO0SET = T_CLK;                 /*T_CLK = 1;*/ 
IO0CLR = T_RST;             /*T_RST = 0;*/ 
Hold(40); 
return(ucDa); 

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

* 名称: v_Set1302 
* 说明:  
* 功能: 初始化时钟并设置初始时间 
* 调用: v_W1302()  
* 输入: 初始时间地址。初始时间格式为: 秒 分 时 日 月 星期 年  
* 7Byte (BCD码) 1B 1B 1B 1B 1B 1B 1B 
* 返回值: 无 
***********************************************************************/ 
void v_Set1302()  

  IO0CLR=T_CLK;
   IO0SET=T_RST;

v_W1302(0x8e,0x00);              /* 控制命令,WP=0,写操作?*/ 
v_W1302(0x80,0x00);             /*写秒并启动振荡*/
v_W1302(0x82,0x00);            /*写分*/
v_W1302(0x84,0x12);               /*写时*/
v_W1302(0x86,0x01);               /*写日*/
v_W1302(0x88,0x05);               /*写月*/
v_W1302(0x8a,0x01);             /*写秒星期*/
v_W1302(0x8c,0x08);           /*写年*/
v_W1302(0x8e,0x80);           /* 控制命令,WP=1,写保护?*/ 

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

* 名称: v_Get1302 
* 说明:  
* 功能: 读取DS1302当前时间 
* 调用: uc_R1302()  
* 输入: 保存当前时间地址。当前时间格式为: 秒 分 时 日 月 星期 年  
* 7Byte (BCD码) 1B 1B 1B 1B 1B 1B 1B 
* 返回值: 无 
************************************************************************/

void v_Get1302()  
{
   IO0CLR=T_CLK;
   IO0SET=T_RST;


Read[0] = uc_R1302(0x81);      /*读秒*/
Read[1] = uc_R1302(0x83);     /*读分*/
Read[2] = uc_R1302(0x85);/*读时*/
Read[3] = uc_R1302(0x87);/*读日*/
Read[4] = uc_R1302(0x89);/*读月*/
Read[5] = uc_R1302(0x8b);/*读星期*/
Read[6] = uc_R1302(0x8d);/*读年*/


}   
/****************************************************************************
* 名称:DelayNS()
* 功能:长软件延时
* 入口参数:dly  延时参数,值越大,延时越久
* 出口参数:无
****************************************************************************/
void  DelayNS(uint32  dly)
{  uint32  i;
   for(; dly>0; dly--) 
      for(i=0; i<50000; i++);
}

/****************************************************************************
* 名称:main()
* 功能:发送时钟数据字符串
****************************************************************************/
int  main()
{  
   
   PINSEL0 = 0x00000000;      // 设置I/O连接到UART0
   PINSEL1 = 0x00000000;            
   
   
  
   
   v_Set1302();         //设置时钟初值
   DelayNS(10);
   
   
   
   v_Get1302();         //读时钟值
   
   
   
   
  
   DelayNS(10);
     
  
   return(0);
}

相关帖子

沙发
l0p0c| | 2008-4-28 16:31 | 只看该作者

这玩意儿内部不是自带RTC吗?

使用特权

评论回复
板凳
riberey|  楼主 | 2008-4-28 16:37 | 只看该作者

时钟

虽然是带了内部时钟,但是掉电会丢失,所以就不能达到理想的效果

使用特权

评论回复
地板
wangkj| | 2008-4-28 16:38 | 只看该作者

是不是数据线需要上拉或者下拉电阻?

使用特权

评论回复
5
riberey|  楼主 | 2008-4-28 16:49 | 只看该作者

时钟

按照手册上说,要接上拉电阻,但是,我接了上拉电阻。

使用特权

评论回复
6
后学| | 2008-4-29 08:30 | 只看该作者

re

重点检查SDA和SCLK管脚的波形。。。

使用特权

评论回复
7
riberey|  楼主 | 2008-4-30 17:31 | 只看该作者

回后学

我用万用表测量了1302的I/O和RST 以及CLK,都不变化,说明DS1302没有工作振荡?如果是这样的话,就没有道理啊,因为我已经在程序里加上了控制振荡的控制字了啊,所以只有一种情况就是我的CPU(LPC2114)根本没有把初始化的数据传送到DS1302,以至于DS1302根本就没工作。

使用特权

评论回复
8
后学| | 2008-4-30 22:45 | 只看该作者

re

用示波器。。。万用表差远了。。。

使用特权

评论回复
9
laijie_991| | 2008-5-3 14:13 | 只看该作者

看来遇到了类似的问题.

我去年使用DS1307郁闷了几天.
基于I2C总线,时钟没有工作.结果是软件配置问题.

下面为一参考程序.百分百可以跑.

//*******************************************************************
//***此程序为调试通过的源程序
//***文件名:SY1126.C***//
//***是51系例单片机的最小系统
//***有AT89S8252/AT89S51/52的在线下载功能
//***IIC总线芯片为24C02,记存密码
//*******************************************************************
#include"at89x52.h"
#include<intrins.h>
#define  uchar unsigned char     
#define  uint  unsigned int
#define  nop  _nop_()       /* 定义空操作指令 */
#define VAR    P1
sbit clk=P2^0;                /*DTLED-6显示芯片/时钟芯片DS1302时钟输入端*/
sbit dout=P2^1;                /*DTLED-6显示芯片数据读入端*/
sbit en =P2^2;                /*DTLED-6显示芯片使能端*/    
sbit RST=P2^3;                /*DS1302芯片复位起始端*/
sbit DINOUT=P2^4;            /*DS1302时钟芯片数据输入输出端*/    
sbit enable=P2^5;            /*LCD模块用*/
sbit rw=P2^6;                /*LCD模块用*/
sbit rs=P2^7;                /*LCD模块用*/

sbit SCL=P3^4;                /*24C01 CSL接脚=89C51 T0 P3.4*/
sbit SDA=P3^5;                /*24C01 SDA接脚=89C51 T1 P3.5*/

bit FLAG0=0;                /*位标号FLAG0=1键盘扫描回应*/
bit FLAG1=1;                /*位标号20H.1比较密码回应旗号*/
bit FLAG2=1;                /*位标号FLAG2=0时,进入键盘操作*/
bit FLAG3=1;                /*位标号FLAG3=0时,键盘操作*/
bit FLAG4=0;                /*位标号FLAG4=0时,键盘操作*/
bit FLAG5=0;                /*位标号FLAG5=1时,存储*键按下*/
bit FLAG6=0;                /*位标号FLAG6=1时,有串行信号输入*/
bit TSendAddress(uchar slaaddress,uchar subaddress,uchar * s,uchar no); /* 向有子地址器件写入6字节数据函数 */
bit TRcvAddress(uchar slaaddress,uchar subaddress,uchar * s,uchar no);  /* 向有子地址器件读取6字节数据函数 */
bit acknow;                     /* 应答标志位 acknow=1 表示正常响应 acknow=0 表示未响应 */
static const char tab[16]={0x01,0x02,0x03,0x0c,    /*键盘码00,01,02,03,*/
                           0x04,0x05,0x06,0x0d,    /*键盘码04,05,06,07,*/
                           0x07,0x08,0x09,0x0e,    /*键盘码08,09,0a,0b,*/
                           0x0a,0x00,0x0b,0x0f};/*键盘码0c,0d,0e,0f*/
//static const char tab1[6]={0x01,0x01,0x01,0x01,0x01,0x01};/*内定密码"888888"*/
uchar char1[]="Syber Nanjing.Co";
uchar char2[]="Password:";
uchar dispbuf[9];                /*显示值存放阵列*/
uchar clocktmp[3];                /*显示值存放阵列*/
uchar bufdata[9];    
uchar bufuart[6];            /*串口接收值存放阵列*/
uchar a1=0,clockbak,b1=100,stand=0,m=0,busy,count=10;        
char ww=0,ptr=0,ptr1=0;        /*PTR键盘扫描指标,ptr1显示器扫描指标*/
void delay (unsigned int value)        /*延时副程式*/
 {
      while (value!=0) value--;        /*10US延时*/
 }
void Enable(uchar c);
void Write1(char *c1);                     
void Write2(char c2);                     
void Write3(void);                     /* 显示密码字符串 */
void Initial();                            /*LCD模块初始化*/
void tsled(void);            /*串行发送到DTLED-6副程式*/    
void BCD(void);                /*BCD码转换副程式*/
void scan(void);            /*键盘扫描副程式*/
void clear(void);            /*清除按键存放/显示器阵列dispbuf[]副副程式*/
void open(void);            /*开门比较密码副程式*/    
void read24c02();              /*读24c02的存储值*/
void write24c02();            /*写24c02的存储值*/
void IICSAVE(void);            /*设定密码并存入buft[]阵列副程式*/
void disp(void);            /*显示存放在dispbuf[]阵列的密码副程式*/    
void tserial(void);            /*串口serial发送副程式*/    
void rserial(void);            /*串口serial接收副程式*/    
void temp(void);
void Rd1302st(void);                /*读时钟芯片DS1302*/
void Rd1302(void);                    /*读时钟芯片DS1302*/
void Wr1302(void);                    /*写时钟芯片DS1302*/
void Start();                           /* 起动总线函数 */
void Stop();                            /* 结束总线函数 */
void SendByte(uchar c);                 /* 8951发数据或地址给8583 字节数据发送函数 */
uchar RcvByte();                        /* 8951从24C01读数据字节数据接收函数 */
void Ack(bit a);                        /* 主机8951应答子函数 */
void xch(void);                /*宣告按键存放/显示器阵列dispbuf[]右键滚入副程式*/    
void wxb1(void);        /*0~9计数,秒*/    
void wxb2(void);        /*0~9计数,分*/    
void wxb3(void);        /*0~9计数,时*/    
void save_clocks(void);                /*按显示时间更改时钟*/
void speekclose(void);
void LCD_disple(void);                /*液晶显示*/
/***********************************************************************/
main()                    /*主程式*/
{
     TMOD=0x11;            /*TIMER0工作在案MODE1,16位定时器*/
                        /*TIMER1工作在MODE2,自动重新装载模式*/
                           /*方式寄存器TMOD___________________________*/
                           /*|    定时器1        |     定时器1       |*/
                           /*| GATE|C/T| M1 | M0 | GATE|C/T| M1 | M0 |*/
                           /*|___________________|___________________|*/
    TH1=256-(28800/9600);    /*设定传输波特率9600,晶体振荡器=11.059Mhz*/
                        /*|波特率9600时|SMOD=0|C/T=0|模式=2|自动载入TH1=FD|*/        
                        /*|波特率4800时|SMOD=0|C/T=0|模式=2|自动载入TH1=FA|*/
                        /*|波特率2400时|SMOD=0|C/T=0|模式=2|自动载入TH1=F4|*/
                        /*|波特率1200时|SMOD=0|C/T=0|模式=2|自动载入TH1=E8|*/
    TR1=1;                /*启动TEMER0*/
//    T2MOD=0x02;            /*定时器2工作在输出模式*/
    T2CON=0x38;            /*定时器2工作控制寄存器T2CON_________________*/
                           /*| TF2|EXF2|RCLK|TCLK|EXEN2|TR2|C/T2|CP/RL2|*/
                           /*|___________________|_____________________|*/
    TL2=0xfd;            /*设定传输波特率9600,晶体振荡器=11.059Mhz*/
    TH2=0xff;            /*设定传输波特率9600,晶体振荡器=11.059Mhz*/
    RCAP2L=0xdc;        /*设定传输波特率9600,晶体振荡器=11.059Mhz*/
    RCAP2H=0xff;        /*设定传输波特率9600,晶体振荡器=11.059Mhz*/
    TH2=256-(28800/9600);    /*设定传输波特率9600,晶体振荡器=11.059Mhz*/
                        /*|波特率9600时|SMOD=0|C/T=0|模式=2|自动载入TH1=FD|*/        
                        /*|波特率4800时|SMOD=0|C/T=0|模式=2|自动载入TH1=FA|*/
                        /*|波特率2400时|SMOD=0|C/T=0|模式=2|自动载入TH1=F4|*/
                        /*|波特率1200时|SMOD=0|C/T=0|模式=2|自动载入TH1=E8|*/
    TR2=1;                /*启动TEMER2*/
    SCON=0x50;            /*设定UART工作在MODE3模式,可传送和接收数据 REN=1*/
                        /*串列控制寄存器SCON_______________________*/
                           /*|  7    6    5    4 |  3    2    1    0 |*/
                           /*| SM0| SM1| SM2| REN| TB8| RB8| TI | RI |*/
                           /*|___________________|___________________|*/
    IE=0x98;            /*8是允许中断,a是TIMER0,TIMER1中断致能位*/
                        /*|  7    6    5    4 |  3    2    1    0 |*/
                           /*| EA |    | ET2| ES | ET1| EX1| ET0| EX0|*/
                           /*|___________________|___________________|*/
    IP=0x18;            /*中断优先级寄存器IP_______________________*/
                           /*|    |    | PT2| PS | PT1| PX1| PT0| PX0|*/
                           /*|___________________|___________________|*/
    read24c02();        /*呼叫读取密码存放在DATE1[]副程式*/
    dispbuf[0]=0x03;    /*小数点位*/
    dispbuf[7]=0x01;    /*ID号码*/
    dispbuf[8]=0x01;    /*蜂鸣器设定开/二次分频*/
    Rd1302st();            /*读时钟芯片DS1302*/
    LCD_disple();        /*液晶显示*/
    P0=0xff;
while(1)
    {
    scan();                 /*呼叫键盘扫描副程式有按FLAG0会为1*/
    if(FLAG0==1) 
        {
        temp();            /*判断有按键输入否?*/
        }
    else
        {FLAG4=FLAG5=0;
        if(FLAG2==1)
            {
            Rd1302();                /*读时钟芯片DS1302*/
            if(dispbuf[1]!=clockbak)    /*秒加一*/    
                {
                clockbak=dispbuf[1];
                tsled();        /*串行发送到DTLED-6副程式*/    
                tserial();        /*宣告串口serial发送副程式*/    
                }
            }
        }
    }
}
//*********************************************************************/
//串行发送DTLED-6显示
//dispbuf0-dispbuf1-dispbuf2-dispbuf3-dispbuf4-dispbuf5-dispbuf6-dispbuf7-dispbuf8
// 小数点 - 数码管1- 数码管2- 数码管3- 数码管4- 数码管5- 数码管6-ID识别码-BZ识别码
//00000xxx-0000xxxx-0000xxxx-0000xxxx-0000xxxx-0000xxxx-0000xxxx-0000xxxx-0000xxxx
//小数点=1~6,其它为不显示                                                    
//数码管1-6=0~15,
//ID识别码=0~15   
//BZ识别码=BZ.3为蜂鸣输出控制位,0=关闭,1=打开
//     BZ0~2为蜂鸣频率输出设定为,000=不分频,  最高频率输出=4800Hz;
//                                     001=一次分频,频率输出=4800/ 2 =2400Hz;
//                                     010=二次分频,频率输出=4800/ 4 =1200Hz;
//                                  011=三次分频,频率输出=4800/ 8 =600Hz;
//                                     100=四次分频,频率输出=4800/ 16=300Hz;
//                                     101=五次分频,频率输出=4800/ 32=150Hz;
//                                     110=六次分频,频率输出=4800/ 64=75Hz;                
//                                     111=七次分频,频率输出=4800/128=38Hz;      
//======================================================================
void tsled(void)            /*串行发送DTLED-6显示副程式*/    
{   char ts0,i,j;
    clk=0;
    en=0;
    delay(10);
    for(j=0;j<9;j++)
      {    ts0=dispbuf[j];
        for(i=0;i<4;i++)        /*发小数点码8,4,2,1*/
        {
         clk=1;
        ts0=ts0<<1;    
        if(AC==1) 
        dout=1;
        else      dout=0;
        clk=0;
        nop;
        delay(3);
        }
   }     
    en=1;
}        /*返回主程式*/
/***********************************************************************/
//  设定 字符型LCD模块, 使用DB0--DB7,显示两行,
//  使用5*7字型  显示器要显示 光标要显示但不闪烁 */
//======================================================================
void LCD_disple()                    /*液晶显示*/
{   delay(1000);
    Initial();
    Enable(0x80);                   /* 从第1行第1列开始显示 */
    Write1(char1);                     /* 显示第1行字符串 */
    Enable(0xc0);                    /* 从第2行第1列开始显示 */
    Write1(char2);                     /* 显示第2行字符串 */
    Enable(0xc9);                    /* 从第2行第1列开始显示 */
    Write3();                     /* 显示第2行字符串 */
}
//======================================================================
void Initial()            /*LCD模块初始化*/
{
    Enable(0x01);        /*清除显示*/    
    delay(300);            /*清除需大于1.64ms*/
    Enable(0x38);        /*LCD功能设定,8位元数据传送,2行显示*/
    Enable(0x0f);        /*屏幕设定,游标ON,游标闪烁*/    
    Enable(0x06);        /*加一状态,游标向右移*/
}      
//======================================================================
void Write1(char *c1)                     
{while(*c1!=0)
     {Write2(*c1);
     c1++;
     }
}
//======================================================================
void Write3(void)                     
{uchar i=6;                     
while(i>0)
 {     P0=bufdata|0x30;
    rs=1;rw=0;
    enable=1;
    delay(2);
    enable=0;
     i--;
 }
}
//======================================================================
void Write2(char c2)                     
{P0=c2;
rs=1;rw=0;enable=1;
delay(2);
enable=0;
}
//======================================================================
void Enable(uchar c)
{
P0=c;
rs=0;
rw=0;
enable=1;
delay(2);
enable=0;        
}

/***********************************************************************/
void temp(void)
{    FLAG2=0;
  if(tab[ptr]==0x0e) 
    {disp();        /*如果是按“C”则呼叫显示密码DISP*/
       while(m==P1);            /*按钮放开否?*/
      dispbuf[0]=0x03;    /*小数点位*/
    }
  else                        /*否则往下执行*/
    {
    switch(tab[ptr])            /*是则测试ptr键盘扫描计数器指标至TAB[]取到的键盘码*/
        {
          case 0x0a: 
                  write24c02();    /*是否按“*”是则呼叫设定密码SET*/
                  clear();        /*是否按“#”是则呼叫清除显示器CLEAR*/
               while(m==P1);            /*按钮放开否?*/
                     break;        /*跳出此循环*/
          case 0x0b: 
                  clear();        /*是否按“#”是则呼叫清除显示器CLEAR*/
               while(m==P1);            /*按钮放开否?*/
                      break;        /*跳出此循环*/
          case 0x0c:            /*是否按“A”,未规划键待用户自己定义*/
                  FLAG2=1; P3_2=1;    
                dispbuf[0]=0x03;        /*小数点位*/
                       break;        /*跳出此循环*/
          case 0x0d:            /*是否按“B”,未规划键待用户自己定义*/    
                     break;        /*跳出此循环*/
          case 0x0e:            /*是否按“C”,已侦测过*/    
                   read24c02();    /*呼叫读取密码存放在DATE1[]副程式*/
                     break;        /*跳出此循环*/                    
          case 0x0f: 
                 while(m==P1);            /*按钮放开否?*/
                  open();            /*是否按“D”,是则呼比较密码开门副程式*/
                 dispbuf[0]=0x03;    /*小数点位*/
                goto openend;
                     break;        /*跳出此循环*/
          default:   
                  xch();            /*以上均不是则为数字键呼叫XCH作右键滚入*/
                     break;        /*跳出此循环*/
             }                    /*跳出SWITCH*/
        delay(100);                /*按钮抗机械反弹跳*/
        while(m==P1);            /*按钮放开否?*/
        tsled();                /*串行发送到DTLED-6副程式*/
openend:    nop;
   }                
}        /*返回上一层程式*/
/****************************************************/
void temp_setclock(void)        /*判断有按键输入否?*/
{
switch(dispbuf[0])            /*是则测试ptr键盘扫描计数器指标至TAB[]取到的键盘码*/
 {
  case 0x01: 
            wxb1();        /*0~9计数*/    
           break;        /*跳出此循环*/
  case 0x03: 
            wxb1();        /*0~9计数*/    
           break;        /*跳出此循环*/
  case 0x05: 
            wxb2();        /*0~2,0~4计数*/    
           break;        /*跳出此循环*/
  default:              /*以上均不是*/
           break;        /*跳出此循环*/
 }        
   delay(100);                /*按钮抗机械反弹跳*/
   while(m==P1);            /*按钮放开否?*/
   tsled();                /*串行发送到DTLED-6副程式*/
}        /*返回上一层程式*/
/****************************************************/
void wxb1(void)
{
   switch(tab[ptr])            /*是则测试ptr键盘扫描计数器指标至TAB[]取到的键盘码*/
        {
          case 0x02: 
                  dispbuf[dispbuf[0]]++;    /*是按“上”,是则呼叫设定密码SET*/
                  if(dispbuf[dispbuf[0]]>9)
                      {dispbuf[dispbuf[0]+1]++;    
                       dispbuf[dispbuf[0]]=0;
                      }  
                  if(dispbuf[dispbuf[0]+1]==6)
                      {dispbuf[dispbuf[0]+1]=dispbuf[dispbuf[0]]=0;
                      }  
                     break;        /*跳出此循环*/
          case 0x08: 
                  if(dispbuf[dispbuf[0]]==0)    /*是按“下”,是则呼叫清除显示器CLEAR*/
                      {if(dispbuf[dispbuf[0]+1]==0)  
                          dispbuf[dispbuf[0]+1]=6;
                          dispbuf[dispbuf[0]]=10; 
                          dispbuf[dispbuf[0]+1]--;
                      }    
                  dispbuf[dispbuf[0]]--;        
                     break;        /*跳出此循环*/
          case 0x04:            /*是按“左”,未规划键待用户自己定义*/
                  dispbuf[0]=dispbuf[0]+2;    /*小数点左移一位*/
                if(dispbuf[0]>6)
                    dispbuf[0]=1;
                       break;        /*跳出此循环*/
          case 0x06:            /*是按“右”,未规划键待用户自己定义*/    
                if(dispbuf[0]<3)
                    dispbuf[0]=7;
                  dispbuf[0]=dispbuf[0]-2;    /*小数点右移一位*/
                     break;        /*跳出此循环*/
          case 0x0a:            /*是按“*”,已侦测过*/    
                       FLAG5=1;
                        break;        /*跳出此循环*/ 
          case 0x0c:            /*是否按“A”,未规划键待用户自己定义*/
                  FLAG4=FLAG5=P3_2=1;    
                dispbuf[0]=0x03;        /*小数点位*/
                       break;        /*跳出此循环*/
          default:              /*以上均不是*/
                     break;        /*跳出此循环*/
        }            
}        /*返回上一层程式*/
/****************************************************/
void wxb2(void)
{switch(tab[ptr])            /*是则测试ptr键盘扫描计数器指标至TAB[]取到的键盘码*/
        {case 0x02: 
                  dispbuf[dispbuf[0]]++;    /*是按“上”,是则呼叫设定密码SET*/
                  if(dispbuf[dispbuf[0]+1]==2)
                      {if(dispbuf[dispbuf[0]]>4)
                          {dispbuf[dispbuf[0]+1]=dispbuf[dispbuf[0]]=0;}  
                    }
                  else
                      {if(dispbuf[dispbuf[0]]>9)
                          {dispbuf[dispbuf[0]+1]++;    dispbuf[dispbuf[0]]=0;}  
                      if(dispbuf[dispbuf[0]+1]>2)
                          {dispbuf[dispbuf[0]+1]=dispbuf[dispbuf[0]]=0;}  
                    }
                     break;        /*跳出此循环*/
          case 0x08: 
                  if(dispbuf[dispbuf[0]]==0)    /*是按“下”,是则呼叫清除显示器CLEAR*/
                      {if(dispbuf[dispbuf[0]+1]==0) 
                          {dispbuf[dispbuf[0]+1]=2;
                           dispbuf[dispbuf[0]]=5; 
                          }    
                      else 
                          {dispbuf[dispbuf[0]]=10; dispbuf[dispbuf[0]+1]--;
                          }     
                      }
                      dispbuf[dispbuf[0]]--;        
                     break;        /*跳出此循环*/
          case 0x04:            /*是按“左”,未规划键待用户自己定义*/
                  dispbuf[0]=dispbuf[0]+2;    /*小数点左移一位*/
                if(dispbuf[0]>6)
                    dispbuf[0]=1;
                       break;        /*跳出此循环*/
          case 0x06:            /*是按“右”,未规划键待用户自己定义*/    
                if(dispbuf[0]<3)
                    dispbuf[0]=7;
                  dispbuf[0]=dispbuf[0]-2;    /*小数点右移一位*/
                     break;        /*跳出此循环*/
          case 0x0a:            /*是按“*”,已侦测过*/    
                       FLAG5=1;
                        break;        /*跳出此循环*/                    
          case 0x0c:            /*是否按“A”,未规划键待用户自己定义*/
                  FLAG4=FLAG5=P3_2=1;    
                dispbuf[0]=0x03;        /*小数点位*/
                       break;        /*跳出此循环*/
          default:              /*以上均不是*/
                     break;        /*跳出此循环*/
        }            
}        /*返回上一层程式*/
/****************************************************/
void save_clocks(void)                /*按显示时间更改时钟*/
{clocktmp[0]=dispbuf[1]|(dispbuf[2]<<4);
 clocktmp[1]=dispbuf[3]|(dispbuf[4]<<4);
 clocktmp[2]=dispbuf[5]|(dispbuf[6]<<4);
 Wr1302();
 FLAG2=1;                
 nop;
}
/****************************************************/
void xch(void)                    /*显示向右移动副程式*/
{char c;                    /*宣告变数*/
     for(c=6;c>0;c--)
     {dispbuf[c]=dispbuf[c-1];/*将显示器dispbuf[]移位交换,dispbuf[3]->dispbuf[4]->dispbuf[5]...*/
     }
     dispbuf[0]=0;                /*有安键时,小数点不亮*/
     dispbuf[1]=tab[ptr];        /*新的按键值存入dispbuf[1],最低位*/
}        /*返回上一层程式*/
/****************************************************/
void open(void)                    /*开门比较密码副程式*/
{char c;                        /*宣告变数*/
   FLAG1=1;                        /*设开门标号为1*/
for(c=1;c<6;c++)                /*比较六个密码*/
 {if(dispbuf[c]!=bufdata[c])    /*显示值(按键值disbuf[])与密码TAB[]比较是否相等*/
           FLAG1=0;
        if(FLAG1==0)            /*FLAG1=0 表示不相等*/
               break;            /*跳出此循环*/
 }
 if(FLAG1==1)                /*如FLAG1=1 表示密码相等,令电锁P2.0置0动作*/
  {                            /*密码正确*/
    dispbuf[8]=0x09;                /*蜂鸣器设定开/二次分频*/
    dispbuf[0]=0x01;            /*小数点到最高位位*/
       P3_2=0;                        /*P3.2置0,使绿色下载指示灯亮(喇叭响)*/    
//    TMOD=0x11;
     TR1=1;                        /**/
    TF1=0;
    IE=0x9f;                    /*8是允许中断,a是TIMER0,TIMER1中断致能位*/
       tsled();                    /*串行发送到DTLED-6副程式*/    
    while(FLAG5==0)                /*等待设置死循环*/
        {
         scan();                 /*呼叫键盘扫描副程式有按FLAG0会为1*/
            if(FLAG0==1) 
          {
           temp_setclock();        /*判断有按键输入否?*/
          }
            if(FLAG6==1) 
            {tsled();        /*串行发送到DTLED-6副程式*/    
             FLAG6=0;
            }
        }
    if(FLAG4==0)
    save_clocks();                /*按显示时间更改时钟*/
  }    
    else P3_2=1;                /*密码错,P3.2置1,关闭绿色下载指示灯灭(喇叭不响)*/    
}        /*返回上一层程式*/
/******************************************************/
void clear(void)                /*清除显示器dispbuf[]为00副程式*/
{char c;                    /*宣告变数*/
     for(c=1;c<7;c++)            /*将00存入显示阵列dispbuf[]*/
     {dispbuf[c]=0x00;
     }                    
}        /*返回上一层程式*/
/******************************************************/
void Wr1302(void)                    /*写时钟芯片DS1302*/
{char i,j,ts0,conb,conbyt;
    conb=0x80;
    ts0=conb;
//
for(j=0;j<3;j++)            /*写秒,分,时三次循环*/
    {clk=RST=0;                    /*DS1302系统初始化*/
        nop;nop;
        RST=1;
    for(i=0;i<8;i++)            /*写控制字到DS1302*/
      {clk=0;                    /*清时钟*/
        if(conb&0x01) 
                DINOUT=1;
        else    DINOUT=0;
         clk=1;                    /*时钟上升沿,发送数据有效*/
        conb=conb>>1;    
        nop;
      }
         clk=0;                    /*清时钟*/
        conb=ts0+2+j*2;
    conbyt=clocktmp[j]&0x7f;
    for(i=0;i<8;i++)            /*写设定值到DS1302*/
      {clk=0;                    /*清时钟*/
       if(conbyt&0x01) 
                DINOUT=1;
        else    DINOUT=0;
   &n

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

6

帖子

0

粉丝