EDN首页   博客首页 用户登陆  |  注册
aaa
发表于 2010/2/6 22:28:49

0

关于投票

单片机自学_4(4×4键盘扫描程序)

说明:本程序为4×4键盘扫描程序,是经过验证显示正确的。

功能:4×4键盘,总共16个键,分别依次编号,当按到相应的按键的时候,数码管显示相应的编号。

编号依次为:1,2,3,4,5,6,7,8,9,A,B,C,D,E,  F

#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit dula="P2"^6;
sbit wela="P2"^7;
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};

uint temp,num;
void display();
void delay(uint z);
void main()
{
 while(1)
 {
  display();
 } 
}
void display()
{
 P3=0xfe;
 temp=P3;
 temp=temp&0xf0;
 while(temp!=0xf0)
 {
  delay(5);
  temp=P3;
  temp=temp&0xf0;

  wela=1;
  P0=0xfe;
  wela=0;

  while(temp!=0xf0)
  {
   temp=P3;
   switch(temp)
   {
    case 0xee:num=0;
     break;
    case 0xde:num=1;
     break;
    case 0xbe:num=2;
     break;
    case 0x7e:num=3;
     break;
   }
   dula=1;
   P0=table[num];
   dula=0;
  while(temp!=0xf0)
   {
    temp=P3;
    temp=temp&0xf0;
   }
  } 
 } //显示0,1,2,3

 P3=0xfd;
 temp=P3;
 temp=temp&0xf0;
 while(temp!=0xf0)
 {
  delay(5);
  temp=P3;
  temp=temp&0xf0;

  wela=1;
  P0=0xfe;
  wela=0;

  while(temp!=0xf0)
  {
   temp=P3;
   switch(temp)
   {
    case 0xed:num=4;
     break;
    case 0xdd:num=5;
     break;
    case 0xbd:num=6;
     break;
    case 0x7d:num=7;
     break;

   }
   dula=1;
   P0=table[num];
   dula=0;
  while(temp!=0xf0)
   {
    temp=P3;
    temp=temp&0xf0;//
   }
  } 
 } //显示4,5,6,7

 P3=0xfb;
 temp=P3;
 temp=temp&0xf0;
 while(temp!=0xf0)
 {
  delay(5);
  temp=P3;
  temp=temp&0xf0;

  wela=1;
  P0=0xfe;
  wela=0;

  while(temp!=0xf0)
  {
   temp=P3;
   switch(temp)
   {
    case 0xeb:num=8;
     break;
    case 0xdb:num=9;
     break;
    case 0xbb:num=10;
     break;
    case 0x7b:num=11;
     break;

   }
   dula=1;
   P0=table[num];
   dula=0;
  while(temp!=0xf0)
   {
    temp=P3;
    temp=temp&0xf0;
   }
  } 
 } //显示8,9,A,B
 P3=0xf7;
 temp=P3;
 temp=temp&0xf0;
 while(temp!=0xf0)
 {
  delay(5);
  temp=P3;
  temp=temp&0xf0;

  wela=1;
  P0=0xfe;
  wela=0;

  while(temp!=0xf0)
  {
   temp=P3;
   switch(temp)
   {
    case 0xe7:num=12;
     break;
    case 0xd7:num=13;
     break;
    case 0xb7:num=14;
     break;
    case 0x77:num=15;
     break;

   }
   dula=1;
   P0=table[num];
   dula=0;
  while(temp!=0xf0)
   {
    temp=P3;
    temp=temp&0xf0;
   }
  } 
 } //显示C、D、E、F
}

void delay(uint z)
{
 uint x,y;
 for(x=z;x>0;x--)
  for(y=110;y>0;y--);
}

系统分类: 单片机  |  用户分类: 单片机  |  标签: 4×4键盘扫描程序  |  来源: 原创  | 

点击查看原文

发表评论 阅读全文(408) | 回复(0)

发表于 2010/2/5 12:18:11

0

关于投票

自学单片机_3(数码管按流水灯计数)

说明:每一个程序都是通过手头上的现有的片子,通过ISP下载可以实现的,有什么问题,欢迎大家指点,纠正。

实现目的:流水灯每左移一次,蜂鸣器响;当8个流水灯分别显示完后,数码管个位开始计数;当数码管个位计数为9时,个位清零,数码管十位开始计数;当十位计数为9时,清零。

 

#include<reg52.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit bee="P2"^3;
sbit dula="P2"^6;
sbit wela="P2"^7;
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};

void delay(uint z);
main()
{
 uint num,temp,num1,num2;;
 temp=0xfe;
 P1=temp;

 wela=1;
 P0=0xff;
 wela=0;

 while(1)
 {
  bee=0;
  num++;
  
  if(num==8)
   {
    num=0;
    num1++;
    if(num1==10)
     {
      num1=0;
      num2++;
      if(num2==10)
       num2==0;
      dula=1;
      P0=table[num2];
                  dula="0";
  
                  wela="1";
      P0=0xfe;
      wela=0;  
      delay(100); //十位数码管显示
     }
    dula=1;
    P0=table[num1];
                dula="0";

                wela="1";
    P0=0xfd;
    wela=0;    //个位数码管显示

   }
    
  delay(20);
  P1=0xff;
  bee=1;
  delay(20);
  temp=_crol_(temp,1);  //移位
  P1=temp;
 
 }
  
   
}

void delay(uint z)
{
 uint x,y;
 for(x=z;x>0;x--)
  for(y=110;y>0;y--);
}

系统分类: 单片机  |  用户分类: 单片机  |  标签: 自学单片机_3(数码管按流水灯计数)  |  来源: 原创  | 

点击查看原文

发表评论 阅读全文(202) | 回复(0)

发表于 2010/1/30 22:02:32

0

关于投票

自学单片机_2(键盘按键显示)

#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit bee="P2"^3;
sbit dula="P2"^6;
sbit s5=P3^7;
sbit wela="P2"^7;

uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};

void delay(uint z);
void main()
{
 uint num;
 P3=0xff;
 wela=1;
 P0=0xfe;
 wela=0;
 while(1)
 {
  if(s5==0)
  {
   delay(10);
   if(s5==0)
   {
    bee=0;
    P1=0xfe;
    num++;
    if(num==10)
    num=0;
    
   }     
   while(!s5);
   delay(10);
   while(!s5);
   
  }
  else
  {
   bee=1;
   P1=0x7f;
  }
  dula=1;
  P0=table[num];
  dula=0;
  
 
  
 }


}

void delay(uint z)
{
 uint x,y;
 for(x=z;x>0;x--)
  for(y=110;y>0;y--);
}

 

实现功能:选择键盘按键之一,按下该键,发光二极管最后一个灯亮;松开按键,发光二极管第一个灯亮;在整个过程中,数码管进行计数,当数码管数值为9时,清零。

需要注意:按键在按键过程和松开过程中,需要消抖(很重要),否则很容易出错!

系统分类: 单片机  |  用户分类: 单片机  |  标签: 自学单片机_2(键盘按键显示)  |  来源: 原创  | 

点击查看原文

发表评论 阅读全文(199) | 回复(0)

发表于 2008/5/21 16:08:06

5

关于投票

应用Protues仿真单片机字体是反相的,求助怎么修改正确!

这个是我的仿真效果,不知道怎么回事?

希望懂Protues高手们,帮帮忙!

给点建议!

系统分类: 单片机  |  用户分类: 单片机  |  标签: Protues  |  来源: 原创  | 

点击查看原文

发表评论 阅读全文(2215) | 回复(2)

发表于 2008/4/30 22:11:14

9

关于投票

单片机硬件设计原则

偶然之间看到了这个链接,感觉相当的不错,现在收藏了,以便日后学习!同时与大家分享!

 

单片机硬件设计原则
  
一个单片机应用系统的硬件电路设计包含两部分内容:一是系统扩展,即单片机内部的功能单元,如ROMRAMI/O、定时器/计数器、中断系统等不能满足应用系统的要求时,必须在片外进行扩展,选择适当的芯片,设计相应的电路。二是系统的配置,即按照系统功能要求配置外围设备,如键盘、显示器、打印机、A/DD/A转换器等,要设计合适的接口电路。
系统的扩展和配置应遵循以下原则:

1
、尽可能选择典型电路,并符合单片机常规用法。为硬件系统的标准化、模块化打下良好的基础。
2
、系统扩展与外围设备的配置水平应充分满足应用系统的功能要求,并留有适当余地,以便进行二次开发。
3
、硬件结构应结合应用软件方案一并考虑。硬件结构与软件方案会产生相互影响,考虑的原则是:软件能实现的功能尽可能由软件实殃,以简化硬件结构。但必须注意,由软件实现的硬件功能,一般响应时间比硬件实现长,且占用CPU时间。
4
、系统中的相关器件要尽可能做到性能匹配。如选用CMOS芯片单片机构成低功耗系统时,系统中所有芯片都应尽可能选择低功耗产品。
5
、可靠性及抗干扰设计是硬件设计必不可少的一部分,它包括芯片、器件选择、去耦滤波、印刷电路板布线、通道隔离等。
6
、单片机外围电路较多时,必须考虑其驱动能力。驱动能力不足时,系统工作不可靠,可通过增设线驱动器增强驱动能力或减少芯片功耗来降低总线负载。
7
、尽量朝单片方向设计硬件系统。系统器件越多,器件之间相互干扰也越强,功耗也增大,也不可避免地降低了系统的稳定性。随着单片机片内集成的功能越来越强,真正的片上系统SoC已经可以实现,如ST公司新近推出的μPSD32××系列产品在一块芯片上集成了80C32核、大容量FLASH存储器、SRAMA/DI/O、两个串口、看门狗、上电复位电路等等。

单片机系统硬件抗干扰常用方法实践

影响单片机系统可靠安全运行的主要因素主要来自系统内部和外部的各种电气干扰,并受系统结构设计、元器件选择、安装、制造工艺影响。这些都构成单片机系统的干扰因素,常会导致单片机系统运行失常,轻则影响产品质量和产量,重则会导致事故,造成重大经济损失。

      
形成干扰的基本要素有三个: 1)干扰源。指产生干扰的元件、设备或信号,用数学语言描述如下:du/dt di/dt大的地方就是干扰源。如:雷电、继电器、可控硅、电机、高频时钟等都可 能成为干扰源。(2)传播路径。指干扰从干扰源传播到敏感器件的通路或媒介。典型的干扰传 播路径是通过导线的传导和空间的辐射。(3)敏感器件。指容易被干扰的对象。如:A/DD/A变换器,单片机,数字IC 弱信号放大器等。 干扰的分类 1干扰的分类干扰的分类有好多种,通常可以按照噪声产生的原因、传导方式、波形特性等等进行不同的分类。按产生的原因分:可分为放电噪声音、高频振荡噪声、浪涌噪声。按传导方式分:可分为共模噪声和串模噪声。按波形分:可分为持续正弦波、脉冲电压、脉冲序列等等。 2 干扰的耦合方式干扰源产生的干扰信号是通过一定的耦合通道才对测控系统产生作用的。因此,我有有必要看看干扰源和被干扰对象之间的传递方式。干扰的耦合方式,无非是通过导线、空间、公共线等等,细分下来,主要有以下几种: 1)直接耦合:这是最直接的方式,也是系统中存在最普遍的一种方式。比如干扰信号通过电源线侵入系统。对于这中问剑钣行У姆椒ň褪羌尤肴ヱ畹缏贰4佣芎玫囊种啤?/P> 2)公共阻抗耦合:这也是常见的耦合方式,这种形式常常发生在两个电路电流有共同通路的情况。为了防止这种耦合,通常在电路设计上就要考虑。使干扰源和被干扰对象间没有公共阻抗。 3)电容耦合:又称电场耦合或静电耦合 。是由于分布电容的存在而产生的耦合。 4)电磁感应耦合:又称磁场耦合。是由于分布电磁感应而产生的耦合。 5)漏电耦合:这种耦合是纯电阻性的,在绝缘不好时就会发生。

      
常用硬件抗干扰技术 针对形成干扰的三要素,采取的抗干扰主要有以下手段。 1 抑制干扰源抑制干扰源就是尽可能的减小干扰源的du/dtdi/dt。这是抗干扰设计中最优先考虑和最重要的原则,常常会起到事半功倍的效果。 减小干扰源的du/dt主要是通过在干扰源两端并联电容来实现。减小干扰源的di/dt则是在干扰源回路串联电感或电阻以及增加续流二极管来实现。 抑制干扰源的常用措施如下: 1)继电器线圈增加续流二极管,消除断开线圈时产生的反电动势干扰。仅加 续流二极管会使继电器的断开时间滞后,增加稳压二极管后继电器在单位时间内可 动作更多的次数。 2)在继电器接点两端并接火花抑制电路(一般是RC串联电路,电阻一般选几K 到几十K,电容选0.01uF),减小电火花影响。 3)给电机加滤波电路,注意电容、电感引线要尽量短。 4)电路板上每个IC要并接一个0.01μF0.1μF高频电容,以减小IC对电源的 影响。注意高频电容的布线,连线应靠近电源端并尽量粗短,否则,等于增大了电 容的等效串联电阻,会影响滤波效果。 5)布线时避免90度折线,减少高频噪声发射。 6)可控硅两端并接RC抑制电路,减小可控硅产生的噪声(这个噪声严重时可能会把可控硅击穿的)。 2 切断干扰传播路径 按干扰的传播路径可分为传导干扰和辐射干扰两类。 所谓传导干扰是指通过导线传播到敏感器件的干扰。高频干扰噪声和有用信号的频带不同,可以通过在导线上增加滤波器的方法切断高频干扰噪声的传播,有时也可加隔离光耦来解决。电源噪声的危害最大,要特别注意处理。 所谓辐射干扰是指通过空间辐射传播到敏感器件的干扰。一般的解决方法是增加干扰源与敏感器件的距离,用地线把它们隔离和在敏感器件上加 蔽罩。 切断干扰传播路径的常用措施如下: 1)充分考虑电源对单片机的影响。电源做得好,整个电路的抗干扰就 解决了一大半。许多单片机对电源噪声很敏感,要给单片机电源加滤波电路或稳压器,以减小电源噪声对单片机的干扰。比如,可以利用磁珠和电容组成π形滤波电路,当然条件要求不高时也可用 100Ω电阻代替磁珠。 2)如果单片机的I/O口用来控制电机等噪声器件,在I/O口与噪声源之间应加隔离(增加π形滤波电路)。 3)注意晶振布线。晶振与单片机引脚尽量靠近,用地线把时钟区隔离起来,晶振外壳接地并固定。 4)电路板合理分区,如强、弱信号,数字、模拟信号。尽可能把干扰源(如电机、继电器)与敏感元件(如单片机)远离。 5)用地线把数字区与模拟区隔离。数字地与模拟地要分离,最后在一点接于电源地。A/DD/A芯片布线也以此为原则。 6)单片机和大功率器件的地线要单独接地,以减小相互干扰。 大功率器件尽可能放在电路板边缘。 7)在单片机I/O口、电源线、电路板连接线等关键地方使用抗干扰元件如磁珠、磁环、电源滤波器、屏蔽罩,可显著提高电路的抗干扰性能。 3 提高敏感器件的抗干扰性能 提高敏感器件的抗干扰性能是指从敏感器件这边考虑尽量减少对干扰噪声 的拾取,以及从不正常状态尽快恢复的方法。 提高敏感器件抗干扰性能的常用措施如下: 1)布线时尽量减少回路环的面积,以降低感应噪声。 2)布线时,电源线和地线要尽量粗。除减小压降外,更重要的是降低耦 合噪声。 3)对于单片机闲置的I/O口,不要悬空,要接地或接电源。其它IC的闲置端在不改变系统逻辑的情况下接地或接电源。 4)对单片机使用电源监控及看门狗电路,如:IMP809IMP706IMP813 X5043X5045等,可大幅度提高整个电路的抗干扰性能。 5)在速度能满足要求的前提下,尽量降低单片机的晶振和选用低速数字电路。 6IC器件尽量直接焊在电路板上,少用IC座。 4 其它常用抗干扰措施 交流端用电感电容滤波:去掉高频低频干扰脉冲。变压器双隔离措施:变压器初级输入端串接电容,初、次级线圈间屏蔽层与初级间电容中心接点接大地,次级外屏蔽层接印制板地,这是硬件抗干扰的关键手段。次级加低通滤波器:吸收变压器产生的浪涌电压。采用集成式直流稳压电源:因为有过流、过压、过热等保护。I/O口采用光电、磁电、继电器隔离,同时去掉公共地。通讯线用双绞线:排除平行互感。防雷电用光纤隔离最为有效。A/D转换用隔离放大器或采用现场转换:减少误差。外壳接大地:解决人身安全及防外界电磁场干扰。加复位电压检测电路。防止复位不充份,CPU就工作,尤其有EEPROM的器件,复位不充份会改变EEPROM的内容。印制板工艺抗干扰: 电源线加粗,合理走线、接地,三总线分开以减少互感振荡。 CPURAMROM等主芯片,VCCGND之间接电解电容及瓷片电容,去掉高、低频干扰信号。 独立系统结构,减少接插件与连线,提高可靠性,减少故障率。 集成块与插座接触可靠,用双簧插座,最好集成块直接焊在印制板上,防止器件接触不良故障。 有条件采用四层以上印制板,中间两层为电源及地

 

 

系统分类: 单片机  |  用户分类: 单片机  |  标签: 单片机硬件设计  |  来源: 转贴  | 

点击查看原文

发表评论 阅读全文(1163) | 回复(1)

发表于 2008/4/30 22:05:22

5

关于投票

单片机应用编程技巧100问.pdf

点击下载单片机应用编程技巧100问

另外补充:

功能强大的时钟中断
  在单片机CPU发挥两个CPU的功效,大大方便和简化
  下面以6MHz时钟的AT89C51系统为例,说明时钟中断的
  定时器初值与中断周期 时钟中断无需过于频繁,一般取20mS(50Hz)即可。如需要百分之一秒的时基10mS(100Hz)。这里取20mS,用定时器T0工作于16位定时器方式(方式1)T0的工作方式为:每过一个机器周期自动加1,当计满0FFFFh,要溢出时,便会产生中断,并由硬件设置相应的标志位供N+1个机器周期。所以,我们只要在T0中预先存入一个比满值0FFFFhN的数,然后启动定时器,便会在N个机器周期后产生中断。这个值便是所谓的初值。下面计算我们需要的初值:时钟为6MHz12个时钟周期为一个机器周期,20mS中有10000个机器周期。(10000)10=(2710)16,则0FFFFh-2710h+1=0D8F0h。由于响应中断、保护现场及重装初值还需要7~8个机器周期,把这个值再加上7,即T0应装入的初值是0D8F7h。每次中断进入后,先把APSW的值压入堆栈,然后即把0D8F7h装入T0
  设置一个单元,每次中断加1 我们可以取内部RAM中一个单元,取名为INCPI(Increase Per Interrupt),在中断中,装完T0初值后,用INC INCPI指令将其加一。从这个单元中,无论中断程序还是主程序,都可以从中获得20mS1~256之间任意整数倍的信号。例如:有一段向数码管送显的程序,需要每0.5秒执行一次以便刷新显示器,便可以设一单元(称为等待单元)W_DISP,用/MOV A,INCPI/ADD A,#25/MOV W_DISP,A/语句让其比当前的INCPI值大25,然后在每次中断中检查是否于INCPI值相等。若相等,说明已过了25个中断周期,便执行送显程序,并且让W_DISP再加上25,等待下个0.5秒。我们可以设置多个等待单元,以便取出多个不同的时基信号。让中断程序在每次中断时依次查询各个等待单元是否与INCPI相等,若相等,则执行相应的处理,并重新设置该等待单元的值,否则跳过。例如:用0.5秒信号刷新或闪烁显示器,用1秒信号产生实时时钟,或输出一定频率的方波,以一定间隔查询输入设备等。
  在中断中读键 通常,我们在主程序中读键盘,步骤为:扫描键盘,若有键按下,则延时几十毫秒去抖动,再次确认此键确实按下,然后处理该键对应的工作,完成后再次重上述步骤。但这有两点不足:1.处理相应工作时无法锁存按键的输入,即可能漏键。2.延时去抖时CPU无法做其它事情,效率不高。如果把读键放入时钟中断中,则可避免上述不足。方法为:如果两次相邻的中断中都读到同一个键按下,则这个键是有效的(达到了去抖目的),并将其锁存到先入先出(队列)的键盘缓冲区,等主程序来处理。这样,主程序处理按键的同时,仍可响应键盘的输入。缓冲区深度通常可设为8级,若锁存的键数多于8个,则忽略新的按键,并报警提示用户新的按键将无效。若键盘缓冲队列停滞的时间大大长于主程序处理按键所需要的最大时间,说明主程序已出错或跑飞,可以在中断用指令将系统复位,起到了看门狗的目的。
  主程序中的延时 由于有常开的时钟中断,所以当主程序中有需要时间较短、精度较高的延时时,应暂时把时钟中断关闭。而程序中需要时间较长、精度不高的延时时,便可仿照下需的写法,避免多层嵌套的循环延时。
  例:在P1.1输出1秒的高电平脉冲
    MOV    A,INCPI
    INC    A
    CJNE    A,INCPI$   
;等待一次中断处理完成
    SETB    P1.1        
;设P1.1H,脉冲开始
    ADD    A,#50        
5020mS1
    CJNE    A,INCPI,$   
;等中断将INCPI加一50
    CLR    P1.1        
;设P1.1L,脉冲结束
  结束语:从上看出,要灵活地应用时钟中断,将任务合理分配给中断和主程序,并且二者要分工明确,接口简单。这其中的技巧还需要大家在实践中多多摸索与体会。另外要注意:应尽量缩短中断处理程序的执行时间,更不要长于20mS

 

感觉不错,跟大家分享一下,呵呵

 

系统分类: 单片机  |  用户分类: 单片机  |  标签: 单片机编程  |  来源: 无分类  | 

点击查看原文

发表评论 阅读全文(1860) | 回复(1)

发表于 2008/4/30 22:02:15

3

关于投票

10小时学会C语言(简单易学)

点击下载

10小时学会C语言(简单易学),绝对适用于新手!

系统分类: 单片机  |  用户分类: 单片机  |  标签: C语言  |  来源: 无分类  | 

点击查看原文

发表评论 阅读全文(2712) | 回复(2)

发表于 2008/4/30 21:54:17

5

关于投票

有关单片机串口的几个小招数但愿你能用得上

1.可用函数发生器当串口发送器用
如果你要调试串口,只有一块扳,计算机又不在手边,你可以用函数发升器当串口发送器来用,如你的波特率是9600,那你把函数发生器频率调到9600/2=4800HZ上输出TTL电平直接到RXD上就行了,如果是RS232接口,你频率不变就选函数发生器双极性(交流输出)就是了,注意电平有峰峰值12VPP就够了,此时你的单片机收到数据必须是55H,你可以用MOV P1,SBUF,P1上去测电压,这样没显示也可测试串口了.
理论依旧:55H 01010101 串口启始位是0,先发55H最低位,于是一帧就是0(启始)101010101(停止)................0(启始)101010101(停止)......正好是1/2波特率的方波.

2.
如果你的串口要实现远距离传输,你怎么知道传输的可靠性和信号与传输媒介的适配性呢?
你可以这样来做:发送00H 0FFH 55H,如果这三个值都能正确接受,那网络一定能可靠传输了,这就是以点代面的测试方法.
理由:00H 0FFH是最宽的脉冲和电平(代表能量)最大/最小的脉冲,用信号系统话说他们代表是直流,55H是最窄脉冲,它代表是最高频和能量中间值.既然最低的能过,最大也能过,最宽能过最窄也能过,大能量(抗干扰强)低能量(代表抗干扰弱)中能量也能过,你会相信中间的和中不垃圾的过不了吗!

3.
用同步头初始实现波特率自适应和判断数据包起始
同步头用谁?------7FH,且开始同步时连续发送!
7FH的发送  0起始11111110---1停止
011111110多对称!当你收到两个0中间夹了连续个1的数据后,只要用连续1的时间除以0的持续时间=7,说明这就是同步头了,且一个标准码元持续时间就是码元0的持续时间,其波特率=1/(0元持续时间)

系统分类: 单片机  |  用户分类: 单片机  |  标签: 单片机小技巧  |  来源: 转贴  | 

点击查看原文

发表评论 阅读全文(967) | 回复(0)

发表于 2008/4/30 21:50:44

4

关于投票

单片机PPT学习资料

点击下载  MCS-51单片机结构与工作原理.ppt

点击下载 第2章  MCS-51单片机的硬件结构 .rar

 

 

系统分类: 单片机  |  用户分类: 单片机  |  标签: 单片机PPT  |  来源: 整理  | 

点击查看原文

发表评论 阅读全文(1916) | 回复(1)

发表于 2008/4/30 21:28:49

5

关于投票

801251上电复位和复位延时的时序分析

80C51单片机的上电复位POR(Pmver On Reset)实质上就是上电延时复位,也就是在上电延时期间把单片机锁定在复位状态上。为什么在每次单片机接通电源时,都需要加入一定的延迟时间呢?分析如下。

1 上电复位时序
   
在单片机及其应用电路每次上电的过程中,由于电源同路中通常存在一些容量大小不等的滤波电容,使得单片机芯片在其电源引脚VCCVSS之间所感受到的电源电压值VDD,是从低到高逐渐上升的。该过程所持续的时间一般为1100ms(记作tsddrise)。上电延时taddrise的定义是电源电压从lOVDD上升到90VDD所需的时间,如图1所示。

点击开大图

在单片机电源电压上升到适合内部振荡电路运行的范围并且稳定下来之后,时钟振荡器开始了启动过程(具体包括偏置、起振、锁定和稳定几个过程)。该过程所持续的时间一般为150 ms(记作tOSC)。起振延时tOSC的定义是时钟振荡器输出信号的高电平达到Vih1所需的时间。从图1所示的实际测量图中也可以看得很清楚。这里的Vih1是单片机电气特性中的一个普通参数,代表XTALlRST引脚上的输入逻辑高电平。例如,对于常见的单片机型号AT89C5lAT89S5l,厂家给出的Vih1值为07VDDVDD+05V

   
从理论上讲,单片机每次上电复位所需的最短延时应该不小于treset。这里,treset等于上电延时taddrise与起振延时tOSC之和,如图1所示。从实际上讲,延迟一个treset往往还不够,不能够保障单片机有--一个良好的工作开端。

在单片机每次初始加电时,首先投入工作的功能部件是复位电路。复位电路把单片机锁定在复位状态上并且维持一个延时(记作TRST),以便给予电源电压从上升到稳定的一个等待时间;在电源电压稳定之后,再插入一个延时,给予时钟振荡器从起振到稳定的一个等待时间;在单片机开始进入运行状态之前,还要至少推迟2个机器周期的延时,如图2所示。

点击开大图

2 上电复位电路3
   
上述一系列的延时,都是利用在单片机RST引脚上外接一个RC支路的充电时间而形成的。典型复位电路如图3(a)所示,其中的阻容值是原始手册中提供的。在经历了一系列延时之后,单片机才开始按照时钟源的工作频率,进入到正常的程序运行状态。从图2所示的实测曲线中可以同时看到4条曲线:VDDVrstXTAL2ALE。在电源电压以及振荡器输出信号稳定之后,又等待了一段较长的延时才释放RST信号,使得CPU脱离复位锁定状态;而RST信号一旦被释放,立刻在ALE引脚上就可检测到持续的脉冲信号。

点击开大图

由于标准80C51的复位逻辑相对简单,复位源只有RST一个(相对新型单片机来说,复位源比较单一),因此各种原因所导致的复位活动以及复位状态的进入,都要依靠在外接引脚RST上施加一定时间宽度的高电平信号来实现。

   
标准80C5l不仅复位源比较单一,而且还没有设计内部上电复位的延时功能,因此必须借助于外接阻容支路来增加延时环节,如图3(a)所示。其实,外接电阻R还是可以省略的,理由是一些CMOS单片机芯片内部存在一个现成的下拉电阻Rrst。例如,AT89系列的Rrst阻值约为50200kΩP89V51Rx2系列的Rrst阻值约为40225 kΩ,如图4所示。因此,在图3(a)基础上,上电复位延时电路还可以精简为图3(b)所示的简化电路(其中电容C的容量也相应减小了)

在每次单片机断电之后,须使延时电容C上的电荷立刻放掉,以便为随后可能在很短的时间内再次加电作好准备。否则,在断电后C还没有充分放电的情况下,如果很快又加电,那么RC支路就失去了它应有的延迟功能。因此,在图3(a)的基础上添加一个放电二极管D,上电复位延时电路就变成了如图3(c)所示的改进电路。也就是说,只有RC支路的充电过程对电路是有用的,放电过程不仅无用,而且会带来潜在的危害。于是附加一个放电二极管D来大力缩短放电持续时间,以便消除隐患。二极管D只有在单片机断电的瞬间(VCC趋近于0V,可以看作VCC对地短路)正向导通,平时一直处于反偏截止状态。

3 上电复位失败的2种案例分析
   
假如上电复位延迟时间不够或者根本没有延时过程,则单片机可能面临以下2种危险,从而导致CPU开始执行程序时没有一个良好的初始化,甚至陷入错乱状态。
   
在时钟振荡器输出的时钟脉冲还没有稳定,甚至还没有起振之前,就因释放RST信号的锁定状态而放纵CPU开始执行程序。这将会导致程序计数器PC中首次抓取的地址码很可能是0000H之外的随机值,进而引导CPU陷入混乱状态。参考图5所示的实测信号曲线。

点击开大图

在电源电压还没有上升到合适范围之前(自然也是时钟尚未稳定之前),就释放RST信号的锁定状态,将会使单片机永远感受不到复位信号、经历不到复位过程、包含PC在内的各个SFR内容没有被初始化而保留了随机值,从而导致CPU从一个随机地址开始执行程序,进而也陷入混乱状态。参考图6所示的实测信号曲线。

点击开大图

4 外接监控器MAX810x
   
为了提高单片机应用系统的稳定性,以及保障单片机应用系统的可靠复位,许多世界著名的半导体公司,陆续推出了种类繁多、功能各异、封装微小的专用集成电路。本文仅以带有电源电压跌落复位和上电延迟复位功能的3脚芯片MAX810x为例,简单说明。

    MAX810x(x=L
MJTSR)是美国Maxim公司研制的一组CMOS电源监控电路,能够为低功耗微控制器MCU(μC)、微处理器MPU(μP)或数字系统监视35V的电源电压。在电源上电、断电和跌落期间产生脉宽不低于140ms的复位脉冲。与采用分立元件或通用芯片构成的欠压检测电路相比,将电压检测和复位延时等功能集成到一片3引脚封装的小芯片内,大大降低了系统电路的复杂性,减少了元器件的数量,显著提高了系统可靠性和精确度。应用电路如图7所示。

点击开大图

MAX810x系列产品提供高电平复位信号,并且还能提供6种固定的检测门限(463V438V4OOV308V293V263V)。例如,MAX810M的检测门限电压就是438V,回差电压约为O16V

   
对于MAX810,在电源上电、断电或跌落期间,只要VCC还高于11V,就能保证RESET引脚输出高电压。在VCC上升期问RESET维持高电平,直到电源电压升至复位门限以上。在超过此门限后,内部定时器大约再维持240 ms后释放RESET,使其返回低电平。无论何时只要电源电压降低到复位门限以下(即电源跌落)RESET引脚就会立刻变高。

   
关于MAX8lO芯片的更多信息,可以参考该器件的产品手册。作者:李学海 刘治山 宋庆国

系统分类: 单片机  |  用户分类: 单片机  |  标签: 时序分析 复位  |  来源: 转贴  | 

点击查看原文

发表评论 阅读全文(1219) | 回复(0)

发表于 2008/4/30 21:12:00

9

关于投票

单片机硬件设计原则

单片机硬件设计原则
一个单片机应用系统的硬件电路设计包含两部分内容:一是系统扩展,即单片机内部的功能单元,如ROMRAMI/O、定时器/计数器、中断系统等不能满足应用系统的要求时,必须在片外进行扩展,选择适当的芯片,设计相应的电路。二是系统的配置,即按照系统功能要求配置外围设备,如键盘、显示器、打印机、A/DD/A转换器等,要设计合适的接口电路。
系统的扩展和配置应遵循以下原则:

1
、尽可能选择典型电路,并符合单片机常规用法。为硬件系统的标准化、模块化打下良好的基础。
2
、系统扩展与外围设备的配置水平应充分满足应用系统的功能要求,并留有适当余地,以便进行二次开发。
3
、硬件结构应结合应用软件方案一并考虑。硬件结构与软件方案会产生相互影响,考虑的原则是:软件能实现的功能尽可能由软件实现,以简化硬件结构。但必须注意,由软件实现的硬件功能,一般响应时间比硬件实现长,且占用CPU时间。
4
、系统中的相关器件要尽可能做到性能匹配。如选用CMOS芯片单片机构成低功耗系统时,系统中所有芯片都应尽可能选择低功耗产品。
5
、可靠性及抗干扰设计是硬件设计必不可少的一部分,它包括芯片、器件选择、去耦滤波、印刷电路板布线、通道隔离等。
6
、单片机外围电路较多时,必须考虑其驱动能力。驱动能力不足时,系统工作不可靠,可通过增设线驱动器增强驱动能力或减少芯片功耗来降低总线负载。
7
、尽量朝单片方向设计硬件系统。系统器件越多,器件之间相互干扰也越强,功耗也增大,也不可避免地降低了系统的稳定性。随着单片机片内集成的功能越来越强,真正的片上系统SoC已经可以实现,如ST公司新近推出的μPSD32××系列产品在一块芯片上集成了80C32核、大容量FLASH存储器、SRAMA/DI/O、两个串口、看门狗、上电复位电路等等。

单片机系统硬件抗干扰常用方法实践

影响单片机系统可靠安全运行的主要因素主要来自系统内部和外部的各种电气干扰,并受系统结构设计、元器件选择、安装、制造工艺影响。这些都构成单片机系统的干扰因素,常会导致单片机系统运行失常,轻则影响产品质量和产量,重则会导致事故,造成重大经济损失。

    
形成干扰的基本要素有三个:
1)干扰源。指产生干扰的元件、设备或信号,用数学语言描述如下:du/dt di/dt大的地方就是干扰源。如:雷电、继电器、可控硅、电机、高频时钟等都可 能成为干扰源。
2)传播路径。指干扰从干扰源传播到敏感器件的通路或媒介。典型的干扰传 播路径是通过导线的传导和空间的辐射。
3)敏感器件。指容易被干扰的对象。如:A/DD/A变换器,单片机,数字IC 弱信号放大器等。 干扰的分类 1干扰的分类干扰的分类有好多种,通常可以按照噪声产生的原因、传导方式、波形特性等等进行不同的分类。按产生的原因分:可分为放电噪声音、高频振荡噪声、浪涌噪声。按传导方式分:可分为共模噪声和串模噪声。按波形分:可分为持续正弦波、脉冲电压、脉冲序列等等。
2
干扰的耦合方式干扰源产生的干扰信号是通过一定的耦合通道才对测控系统产生作用的。因此,我有有必要看看干扰源和被干扰对象之间的传递方式。干扰的耦合方式,无非是通过导线、空间、公共线等等,细分下来,主要有以下几种:
1)直接耦合:这是最直接的方式,也是系统中存在最普遍的一种方式。比如干扰信号通过电源线侵入系统。
2)公共阻抗耦合:这也是常见的耦合方式,这种形式常常发生在两个电路电流有共同通路的情况。为了防止这种耦合,通常在电路设计上就要考虑。使干扰源和被干扰对象间没有公共阻抗。
3)电容耦合:又称电场耦合或静电耦合 。是由于分布电容的存在而产生的耦合。
4)电磁感应耦合:又称磁场耦合。是由于分布电磁感应而产生的耦合。
5)漏电耦合:这种耦合是纯电阻性的,在绝缘不好时就会发生。

    
常用硬件抗干扰技术 针对形成干扰的三要素,采取的抗干扰主要有以下手段。
1
抑制干扰源抑制干扰源就是尽可能的减小干扰源的du/dtdi/dt。这是抗干扰设计中最优先考虑和最重要的原则,常常会起到事半功倍的效果。 减小干扰源的du/dt主要是通过在干扰源两端并联电容来实现。减小干扰源的di/dt则是在干扰源回路串联电感或电阻以及增加续流二极管来实现。 抑制干扰源的常用措施如下:
1)继电器线圈增加续流二极管,消除断开线圈时产生的反电动势干扰。仅加 续流二极管会使继电器的断开时间滞后,增加稳压二极管后继电器在单位时间内可 动作更多的次数。
2)在继电器接点两端并接火花抑制电路(一般是RC串联电路,电阻一般选几K 到几十K,电容选0.01uF),减小电火花影响。
3)给电机加滤波电路,注意电容、电感引线要尽量短。
4)电路板上每个IC要并接一个0.01μF0.1μF高频电容,以减小IC对电源的 影响。注意高频电容的布线,连线应靠近电源端并尽量粗短,否则,等于增大了电 容的等效串联电阻,会影响滤波效果。 5)布线时避免90度折线,减少高频噪声发射。
6)可控硅两端并接RC抑制电路,减小可控硅产生的噪声(这个噪声严重时可能会把可控硅击穿的)。
2
切断干扰传播路径 按干扰的传播路径可分为传导干扰和辐射干扰两类。 所谓传导干扰是指通过导线传播到敏感器件的干扰。高频干扰噪声和有用信号的频带不同,可以通过在导线上增加滤波器的方法切断高频干扰噪声的传播,有时也可加隔离光耦来解决。电源噪声的危害最大,要特别注意处理。 所谓辐射干扰是指通过空间辐射传播到敏感器件的干扰。一般的解决方法是增加干扰源与敏感器件的距离,用地线把它们隔离和在敏感器件上加 蔽罩。 切断干扰传播路径的常用措施如下:
1)充分考虑电源对单片机的影响。电源做得好,整个电路的抗干扰就 解决了一大半。许多单片机对电源噪声很敏感,要给单片机电源加滤波电路或稳压器,以减小电源噪声对单片机的干扰。比如,可以利用磁珠和电容组成π形滤波电路,当然条件要求不高时也可用 100Ω电阻代替磁珠。
2)如果单片机的I/O口用来控制电机等噪声器件,在I/O口与噪声源之间应加隔离(增加π形滤波电路)。
3)注意晶振布线。晶振与单片机引脚尽量靠近,用地线把时钟区隔离起来,晶振外壳接地并固定。
4)电路板合理分区,如强、弱信号,数字、模拟信号。尽可能把干扰源(如电机、继电器)与敏感元件(如单片机)远离。
5)用地线把数字区与模拟区隔离。数字地与模拟地要分离,最后在一点接于电源地。A/DD/A芯片布线也以此为原则。
6)单片机和大功率器件的地线要单独接地,以减小相互干扰。 大功率器件尽可能放在电路板边缘。
7)在单片机I/O口、电源线、电路板连接线等关键地方使用抗干扰元件如磁珠、磁环、电源滤波器、屏蔽罩,可显著提高电路的抗干扰性能。
3
提高敏感器件的抗干扰性能 提高敏感器件的抗干扰性能是指从敏感器件这边考虑尽量减少对干扰噪声 的拾取,以及从不正常状态尽快恢复的方法。
提高敏感器件抗干扰性能的常用措施如下:
1)布线时尽量减少回路环的面积,以降低感应噪声。
2)布线时,电源线和地线要尽量粗。除减小压降外,更重要的是降低耦 合噪声。
3)对于单片机闲置的I/O口,不要悬空,要接地或接电源。其它IC的闲置端在不改变系统逻辑的情况下接地或接电源。
4)对单片机使用电源监控及看门狗电路,如:IMP809IMP706IMP813 X5043X5045等,可大幅度提高整个电路的抗干扰性能。
5)在速度能满足要求的前提下,尽量降低单片机的晶振和选用低速数字电路。
6IC器件尽量直接焊在电路板上,少用IC座。
4
其它常用抗干扰措施 交流端用电感电容滤波:去掉高频低频干扰脉冲。变压器双隔离措施:变压器初级输入端串接电容,初、次级线圈间屏蔽层与初级间电容中心接点接大地,次级外屏蔽层接印制板地,这是硬件抗干扰的关键手段。次级加低通滤波器:吸收变压器产生的浪涌电压。采用集成式直流稳压电源:因为有过流、过压、过热等保护。I/O口采用光电、磁电、继电器隔离,同时去掉公共地。通讯线用双绞线:排除平行互感。防雷电用光纤隔离最为有效。A/D转换用隔离放大器或采用现场转换:减少误差。外壳接大地:解决人身安全及防外界电磁场干扰。加复位电压检测电路。防止复位不充份,CPU就工作,尤其有EEPROM的器件,复位不充份会改变EEPROM的内容。
印制板工艺抗干扰:
电源线加粗,合理走线、接地,三总线分开以减少互感振荡。
CPURAMROM等主芯片,VCCGND之间接电解电容及瓷片电容,去掉高、低频干扰信号。
独立系统结构,减少接插件与连线,提高可靠性,减少故障率。
集成块与插座接触可靠,用双簧插座,最好集成块直接焊在印制板上,防止器件接触不良故障。
有条件采用四层以上印制板,中间两层为电源及地

系统分类: 单片机  |  用户分类: 单片机  |  标签: 硬件设计  |  来源: 转贴  | 

点击查看原文

发表评论 阅读全文(633) | 回复(3)

发表于 2008/4/30 21:09:51

20

关于投票

Proteus软件资料及视频教程汇总

视频教程:点击下载

点击下载 Proteus_教程2—修改元件.pdf

点击下载 Proteus_与单片机实时动态仿真.pdf

点击下载 Proteus_自学教程上.pdf

点击下载 Proteus_自学教程下.pdf

点击下载 第二章_电路原理图设计.pdf

点击下载 第三章_电路仿真实验.pdf

点击下载 第四章_印刷电路板设计.pdf

系统分类: 单片机  |  用户分类: 单片机  |  标签: Protues教程  |  来源: 整理  | 

点击查看原文

发表评论 阅读全文(17146) | 回复(22)

发表于 2008/4/30 20:53:56

10

关于投票

单片机控制LCD/LED显示资料汇总(自己收藏)

点击下载 51单片机在视频矩阵设计中的应用.pdf

点击下载AT89C51单片机与74LS164动态显示接口.pdf

点击下载 AT89C2051单片机的汉字显示接口技术.pdf

点击下载 MCS-51单片机系统键盘与显示器接口的一种设计.pdf

点击下载 点阵式LCD与AT89C51单片机的接口技术.pdf

点击下载 基于51单片机的汉字LCD智能显示模块设计.pdf

点击下载 基于AT89C51单片机构成的键盘显示电路.pdf

点击下载 利用CRT及8051单片机实现没字的显示输出.pdf

点击下载 液晶显示器的接口和编程技巧.pdf

点击下载 用8051控制T6963C实现液晶显示的C51程序.pdf

点击下载 51单片机在LED数码管显示中的应用.pdf

系统分类: 单片机  |  用户分类: 单片机  |  标签: 显示 单片机资料  |  来源: 整理  | 

点击查看原文

发表评论 阅读全文(2476) | 回复(9)

发表于 2008/4/30 20:48:47

16

关于投票

45个C编写的单片机应用程序

点击下载

45个C编写的单片机应用程序

需要的朋友可以下载啊,希望能够对大家有用!

系统分类: 单片机  |  用户分类: 单片机  |  标签: 程序设计  |  来源: 转贴  | 

点击查看原文

发表评论 阅读全文(1600) | 回复(12)

发表于 2008/4/30 20:02:54

11

关于投票

万年历程序+电路图

sec11  equ  10h
sec12  equ  11h
min11  equ  12h
min12  equ  13h
hour11 equ  14h
hour12 equ  15h
day11  equ  16h
day12  equ  17h
month11  equ  18h
month12  equ  19h
year11   equ  1ah
year12   equ  1bh
year13   equ  1ch
year14   equ  1dh
TEMP     EQU  1EH
N_DAY    EQU  1FH
shu2    equ  20h
adress2 equ  21h
ADRESS1  EQU  23H
SHU1    EQU   24H
SHU3    EQU   25H
TEMP11  EQU  26H
TEMP12  EQU  27H
N_DAY11  EQU  28H
N_DAY12 EQU  29H
N_MONTH11  EQU  2AH
N_MONTH12  EQU  2BH
N_MONTH  EQU    2CH
huan     equ    2dh
SCLK bit  90h
io   bit   91h
RST  bit   92h
sec  data  60h
min   data  61h
hour  data  62h
date data  63h
month  data  64h
day    data  65h

year1  DATA  66H
year2   data  67h

int_min equ   68h
int_hour  equ  69h
int_date   equ  6ah
int_month  equ  6bh
int_year1   equ  6ch
int_day    equ  6dh

start_year EQU 01; 定义查询表起始年份,01--199 表示1901-2099 年
;以下三单元为需转换的公历日期是子程序的入口数据
time_year DATA 66h
time_month DATA 64h ;BIT7 表示世纪,为1 表示19 世纪,为0 表示20 世纪
time_date DATA 63h
;以下三单元存转换后农历日期与入口单元重叠,如要保留入口信息,请重定义出口地址
CONvert_yeAr DATA 33h
CONvert_mONth DATA 34h ;BIT7 为1 表示闰月
CONvert_dAte DATA 35h
temp_Byte1 DATA 37h
temp_Byte2 DATA 38h
temp_Byte3 DATA 39h
temp_Byte4 DATA 3Ah
temp_Byte5 DATA 3Bh
time_week DATA  65h ;星期天出口
;以下为公历转农历子程序



org  0000h

   mov p0,#0ffh
   mov  6eh,#00h
   mov  int_min,#59h
   mov  int_hour,#23h
   mov  int_date,#12h
   mov  int_month,#11h
   mov  int_year1,#04h
   mov  int_day,#07h
   mov  temp,#00h
   mov  year2,#20h
   MOV  SP,#74H

;DS1302读写程序
;**************


     lcall  init

start: mov  70h,hour
       mov  71h,min
       ;mov  day,time_week
       mov  r0,#sec
       mov  r7,#7
       setb  psw.5
       lcall  rwrtc
       lcall  kEY
      
       LCALL  CONvert
       lcall  GetWeek
       LCALL  TRUN
        ;LCALL  DINGSHI
       LCALL  DISP1
       LCALL  DISP3

       ljmp  start
rwrtc: mov  b,#10000001b
       jb   psw.5,rwrtc1
       mov   b,#10000000b
rwrtc1:clr  sclk
       nop
       setb  rst
       mov   r6,#8
       mov   a,b
rwrtc2:clr  sclk
       rrc  a
       mov  io,c
       nop
       setb  sclk
       djnz  r6,rwrtc2
       mov  r6,#8
       jnb  psw.5,rwrtc4
rwrtc3:clr sclk
       nop
       mov   c,io
       rrc   a
       setb  sclk
       djnz  r6,rwrtc3
       mov  @r0,a
       sjmp  rwrtc6
rwrtc4:mov  a,@r0
rwrtc5:clr  sclk
       rrc  a
       mov  io,c
       nop
       setb sclk
       djnz  r6,rwrtc5
rwrtc6:inc  r0
       mov  a,b
       add  a,#02h
       mov  b,a
       clr  rst
       nop
       clr  sclk
       djnz  r7,rwrtc1
    RET

WRRTC:  CLR  SCLK
        NOP
        SETB  RST
        NOP
        NOP
        MOV   R7,#2
WRRTC1: MOV  R6,#8
        MOV  A,@R0
        CLR  C
wrrtc2: CLR  SCLK
        RRC  A
        MOV  IO,C
        nop
        SETB  SCLK
        DJNZ   R6,WRRTC2
        INC  R0
        djnz  r7,wrrtc1
        clr    rst
        nop
        clr   sclk
        ret


 init:
      CLR  SCLK
      CLR  RST
      MOV  SEC,#10001110b
      MOV  MIN,#00000000b
      MOV  R0,#SEC
      LCALL  wrrtc
      MOV  SEC,#10010000b
      MOV  MIN,#10100101b
      MOV  R0,#SEC
      LCALL  wrrtc
      MOV   R0,#SEC
      MOV  SEC,#10000000b
      MOV  MIN,#00000000b
      lcall  writer_f
      lcall  writer_sh
      lcall  writer_date
      lcall  writer_yue
      lcall  writer_nian
      ret

writer_f:LCALL  wrrtc
      mov  r0,#sec
      mov  sec,#82h
      mov  min,int_min
      lcall  wrrtc
       ret

writer_sh:mov  sec,#10000100b
      mov  min,int_hour
      mov  r0,#sec
      lcall  wrrtc
        ret
writer_yue:mov   sec,#88h
      mov   min,int_month
      mov   r0,#sec
      lcall  wrrtc
         ret
writer_nian:mov  sec,#8ch
      mov  min,int_year1
      mov  r0,#sec
      lcall  wrrtc
      ret
writer_date:mov  sec,#86h
            mov  min,int_date
            mov  r0,#sec
            lcall  wrrtc
      RET

 ;********0***************
 ;BCD转换
 TRUN:
      MOV  A,SEC
      MOV  B,#10H
      DIV  AB
      MOV  SEC12,A
      MOV  SEC11,B

      MOV  A,MIN
      MOV  B,#10H
      DIV   AB
      MOV  MIN12,A
      MOV  MIN11,B

      MOV  A,HOUR
      MOV  B,#10H
      DIV  AB
      MOV  HOUR12,A
      MOV  HOUR11,B

      MOV  A,date
      MOV  B,#10H
      DIV  AB
      MOV  DAY12,a
      MOV  DAY11,b

      MOV  A,MONTH
      MOV  B,#10H
      DIV  AB
      MOV  MONTH12,A
      MOV  MONTH11,B

      MOV  A,year1
      MOV  B,#10H
      DIV  AB
      MOV  YEAR12,A
      MOV  YEAR11,B

      MOV  A,YEAr2
      MOV  B,#10H
      DIV  AB
      MOV  YEAR14,A
      MOV  YEAR13,b
      MOV  A,35h
      MOV  B,#10H
      DIV  AB
      MOV  N_DAY12,A
      MOV  N_day11,B

      MOV  A,34h
      MOV  B,#10H
      DIV  AB
      MOV  N_MONTH12,A
      MOV  N_MONTH11,B

      MOV  A,TEMP
      MOV  B,#10H
      DIV  AB
      MOV  TEMP12,A
      MOV  TEMP11,B


          RET

 ;延时程序
 ;********************

 DEALY:MOV R5,#01h
 DEL1: MOV R2,#07dH
 DEL2:NOP
      NOP
      DJNZ  R2,DEL2
      DJNZ  R5,DEL1
      RET
;显示程序
;***********************
DENG:MOV  P2,#0FFH
     MOV  A,#00H
     MOV  SBUF,A
     JNB  TI,$
     CLR  TI

     MOV  P2,ADRESS2
     MOV  A,SHU2
     MOV  SBUF,A
     JNB  TI,$
     CLR  TI

     MOV  A,#00H
     MOV  SBUF,A
     JNB   TI,$
     CLR  TI
     LCALL  DEALY
     MOV  P2,#0FFH
     RET
DENG1:MOV P2,#0FFH
     MOV  A,SHU1
     MOV  SBUF,A
     JNB  TI,$
     CLR  TI

     MOV  P2,#0FFH
     mov  a,#00h
     MOV  SBUF,a
     JNB  TI,$
     CLR TI

     MOV  P2,ADRESS1
     MOV  A,SHU3
     MOV  SBUF,A
     JNB  TI,$
     CLR  TI
     LCALL  DEALY
     RET
DISP1:
      MOV  R3,#0bFH
      MOV  R4,#06H
      MOV  R0,#10H

DISP2:MOV  A,@R0
      MOV  DPTR,#TAB
      MOVC  A,@A+DPTR
      MOV  SHU2,A
      inc  r0
      MOV  A,R3
      Rr   A
      MOV  R3,A
      MOV  ADRESS2,A
      LCALL  DENG
      DJNZ   R4,DISP2
      mov  a,day
      mov  dptr,#xing
      movc  a,@a+dptr
      mov  shu2,a
      mov  adress2,#0bfh
      lcall  deng
         RET
DISP3:MOV  R3,#0FEH
      MOV  R4,#08H

      MOV  R1,#24H
DISP4:MOV  A,@R0
      MOV  DPTR,#TAB
      MOVC  A,@A+DPTR
      MOV   SHU3,A
      INC  r0
      MOV  A,@R1
      MOVC  A,@A+DPTR
      MOV  SHU1,A
      INC  R1
      MOV  A,R3
      RR  A
      MOV   R3,A
      MOV  ADRESS1,A
      LCALL  DENG1
      DJNZ  R4,DISP4
            RET
;********************************

;键盘程序

;********************************
key:jb  p1.3,s2

s1:  lcall disp1
     lcall  disp3
     jnb  p1.3,s1
     mov  a,6eh
     inc  a
     mov 6eh,a
dianliang1:cjne  a,#01h,dianliang2
            mov  p0,#0feh
            ret
dianliang2:cjne  a,#02h,dianliang3
           mov  p0,#0fch
            ret
dianliang3:cjne  a,#03h,dianliang4
           mov  p0,#0f8h
             ret
dianliang4:cjne  a,#04h,dianliang5
           mov  p0,#0f0h
            ret
dianliang5:cjne  a,#05h,mie
            mov  p0,#0e0h
            ret
mie:cjne  a,#06h,out
    mov  06eh,#00h
    mov  p0,#0ffh
     ret

 out:       ret
s2:jb  p3.3,s3
shang:acall  disp1
   acall  disp3
   jnb  p3.3,shang
   mov   a,temp
   inc  a
   mov  temp,a
   cjne  a,#01h,out
   mov  a,6eh
   cjne  a,#05h,out
   mov   r0,#sec
   mov   sec,#0c0h
   mov   min,70h
   lcall  wrrtc
   mov  r0,#sec
   mov  sec,#0c2h
   mov  min,71h
   lcall  wrrtc
   ret
   

s3:    jb  p3.2,out
       MOV  R7,#05H
 xian: MOV  6FH,R7
       lcall  disp1
       lcall  disp3
       MOV  R7,6FH
       DJNZ  R7,XIAN
jia: mov  a,6eh
     cjne  a,#01h,pan2
    LJMP  jia_SH
pan2:cjne  a,#02h,pan3
   LJMP  jia_F
pan3:cjne  a,#03h,pan4
    LJMP jia_nian
pan4:cjne  a,#04h,pan5
    ljmp  jia_yue
pan5:cjne  a,#05h,out
    ljmp  jia_ri

     ret

jia_f:mov  a,int_min
     inc  a
     da     a
     mov  int_min,a
     cjne  a,#60h,diao_jf
     mov   int_min,#00h
diao_jf:
        lcall  writer_f
        lcall  chxie_ds1302
           ret
jia_sh:
       mov  a,int_hour
       inc  a
       da    a
       mov  int_hour,a
       cjne  a,#24h,diao_jsh
       mov  int_hour,#00h
diao_jsh:
         lcall  writer_sh
         lcall  chxie_ds1302

         ret
jia_ri:mov  a,int_date
       inc  a
       da  a
       mov  int_date,a
       MOV  A,MONTH
       clr  c
       mov  R7,#0f8h
       addc  a,R7
       jc   hou
qian: mov  a,month
      mov  b,#02h
      div  ab
      mov  a,b
      rrc  a
      jc   dayue
xiaoyue:mov  a,int_date
        cjne  a,#31h,diao_jri
        mov   int_date,#01h
        sjmp  diao_jri
dayue:mov  a,int_date
      cjne  a,#32h,diao_jri
      mov  int_date,#01h
      sjmp  diao_jri
hou: mov a,month
     mov  b,#02h
     div  ab
     mov  a,b
     rrc  a
     jc   xiaoyue
     sjmp  dayue

diao_jri:
         lcall  writer_date
         lcall  chxie_ds1302
            ret
jia_yue:mov  a,int_month
        inc   a
        da  a
        mov   int_month,a
        cjne   a,#13h,diao_jyue
        mov  int_month,#01h
diao_jyue:
         lcall  writer_yue
        lcall  chxie_ds1302
    ret
jia_nian:mov  a,int_year1
         inc  a
         da  a
         mov  int_year1,a
          cjne  a,#99h,diao_jnian
          mov  int_year1,#00h
diao_jnian:
           lcall  writer_nian
           lcall  chxie_ds1302
  ret

;**************************************
;公农历算法
;*************************************

CONvert: MOV A,time_year ;将年月日转化为HEX 格式
MOV B,#16
DIV AB
MOV CONvert_yeAr,B
MOV B,#10
MUL AB
ADD A,CONvert_yeAr
MOV CONvert_yeAr,A
MOV A,time_month
MOV C,ACC.7
MOV f0,C ;f0暂存世纪标志,仅用于数据表定位
CLR ACC.7
JNB ACC.4,CON_02

CLR ACC.4 ;ACC.4 为1 表示大于10 月
ADD A,#10
CON_02: MOV CONvert_mONth,A
MOV A,time_date
MOV B,#16
DIV AB
MOV CONvert_dAte,B
MOV B,#10
MUL AB
ADD A,CONvert_dAte
MOV CONvert_dAte,A
MOV dptr,#mONth_dAtA ;以下定位本年数据在表格中的位置
MOV A,CONvert_yeAr
JB f0,CON_06 ;当前为19 世纪年跳转
ADD A,#100 ;从19 世纪起定义表格起始年,20 世纪要加100 年
CON_06: CLR C
SUBB A,#stArt_yeAr
MOV B,#3 ;表格每年3 字节
MUL AB
ADD A,dpl
MOV dpl,A
MOV A,B
ADDC A,dph
MOV dph,A
MOV A,#2
MOVC A,@A+dptr ;读本年表格最后一字节(春节日期)
CLR ACC.7 ;ACC.7 是闰年第13 个月大小,在此不用
MOV B,#32
DIV AB
MOV temp_Byte1,A ;春节月份
MOV temp_Byte2,B ;春节日
; 以下计算当前日期距元旦天数
MOV temp_Byte3,#0 ;设距元旦天数高位为0
MOV A,CONvert_mONth
CJNE A,#10,CON_08
CON_08: JC CON_09 ;9月以前日子数小于256 天,高字节为0(9 月份过去的整月为8 个月)
MOV temp_Byte3,#1
CON_09: MOV A,CONvert_yeAr
ANL A,#03h ;ACC 为除4 的余数
JNZ CON_10 ;转常年处理
; 年除4 余数为0 是闰年
MOV A,CONvert_mONth

LCALL get_ruN_dAys_lOw ;取得闰年过去月的天数的低字节
SJMP CON_12
CON_10: MOV A,CONvert_mONth
LCALL get_dAys_lOw ;取得常年过去月的天数的低字节
CON_12: MOV B,CONvert_dAte
DEC B ;因为日期从1 日起,而不是0 日起
ADD A,B ;过去的整月天数加当月天数
MOV temp_Byte4,A
JNC CON_14
INC temp_Byte3 ;temp_Byte3,temp_Byte4 分别为公历年过去的天数的高低字节
; 以下求春节距元旦天数,因肯定小于256 天所以只用一字节表示
CON_14: MOV A,temp_Byte1
LCALL get_dAys_lOw ;春节不会在3 月份,不用考虑闰年
DEC A ;因为日期从1 日起
ADD A,temp_Byte2
MOV temp_Byte5,A ;temp_Byte5,为春节距元旦天数
MOV A,CONvert_mONth
CJNE A,temp_Byte1,CON_20 ;转换月与春节月比较
MOV A,CONvert_dAte
CJNE A,temp_Byte2,CON_20 ;转换日与春节日比较
CON_20: JC CON_22
LJMP CON_60 ;当前日大于等于春节日期,公历年与农历年同年份
CON_22: MOV A,CONvert_yeAr ;不到春节,农历年比公历年低一年
JNZ CON_24
MOV A,#100 ;年有效数0-99
CON_24: DEC A
MOV CONvert_yeAr,A
MOV A,dpl
CLR C
SUBB A,#3
MOV dpl,A
JNC CON_26
DEC dph ;表格指针指向上一年
CON_26: MOV A,temp_Byte5
CLR C
SUBB A,temp_Byte4
MOV temp_Byte3,A ;temp_Byte3 中为当前日离春节的天数
MOV CONvert_mONth,#12 ;农历月为12 月
CLR f0 ;1901-2099 年没有闰12 月,清闰月标志
CLR A
MOVC A,@A+dptr

ANL A,#0f0h
SWAP A;
MOV temp_Byte4,A ;temp_Byte4 中为闰月
JZ CON_30 ;没有闰月转移
MOV A,#2 ;有闰月,取第13 个月天数
MOVC A,@A+dptr
MOV C,ACC.7
MOV A,#1
MOVC A,@A+dptr
RLC A ;ACC 中为最后6 个月的大小值
SJMP CON_34
CON_30: MOV A,#1
MOVC A,@A+dptr ;ACC 中为最后6 个月的大小值
CON_34: MOV temp_Byte5,A
CON_40: MOV A,temp_Byte5
RRC A
MOV temp_Byte5,A

JC CON_42
MOV B,#29 ;小月29 天
SJMP CON_44
CON_42: MOV B,#30 ;大月30 天
CON_44: MOV A,temp_Byte3
CLR C
SUBB A,B
JZ CON_46 ;正好够减,就是农历日1 日
JNC CON_50
;不够减一月天数,结束农历月调整
CPL A ;求补取绝对值
INC A
CON_46: INC A ;加1 即为农历日
MOV B,#10 ;转换并保存农历日,月,年
DIV AB
SWAP A
ORL A,B
MOV CONvert_dAte,A
MOV A,CONvert_mONth
MOV B,#10
DIV AB
SWAP A
ORL A,B
MOV C,f0
MOV ACC.7,C
MOV CONvert_mONth,A

MOV A,CONvert_yeAr
MOV B,#10
DIV AB
SWAP A
ORL A,B
MOV CONvert_yeAr,A
RET ;结束转换
CON_50: MOV temp_Byte3,A ;temp_Byte3 存减去一月后的天数
JB f0,CON_52 ;是闰月,前推一月,月份不减
DEC CONvert_mONth;
CON_52: MOV A,CONvert_mONth
CJNE A,temp_Byte4,CON_54
CPL f0 ;当前月与闰月相同,更改闰月标志
CON_54: SJMP CON_40
CON_60: MOV A,temp_Byte4 ;春节日小于当前日,农历年同公历年
CLR C
SUBB A,temp_Byte5
MOV temp_Byte4,A
JNC CON_62
DEC temp_Byte3 ;temp_Byte3 temp_Byte4 中为公历日离春节的天数
CON_62: MOV CONvert_mONth,#1 ;农历月为1 月
CLR A
MOVC A,@A+dptr
MOV temp_Byte5,A
ANL A,#0f0h
SWAP A;
XCH A,temp_Byte5 ;temp_Byte5 中为闰月,ACC 为当年农历表第一字节
CLR f0 ;第一个月肯定不是闰月
ANL A,#0fh
MOV temp_Byte1,A
MOV A,#1
MOVC A,@A+dptr
MOV temp_Byte2,A
ANL A,#0f0h
ORL A,temp_Byte1
SWAP A
MOV temp_Byte1,A
MOV A,#2
MOVC A,@A+dptr
MOV C,ACC.7
MOV A,temp_Byte2
ANL A,#0fh

SWAP A
MOV ACC.3,C;
MOV temp_Byte2,A ;以上temp_Byte1,temp_Byte2 各BIT 存农历年大小
CON_70: MOV A,temp_Byte2
RLC A
MOV temp_Byte2,A
MOV A,temp_Byte1
RLC A
MOV temp_Byte1,A
JC CON_72
MOV B,#29 ;小月29 天处理
SJMP CON_74
CON_72: MOV B,#30 ;大月30 天
CON_74: MOV A,temp_Byte4
CLR C
SUBB A,B
JNC CON_78 ;低字节够减跳转
MOV B,A ;低字节不够减, B 暂存减后结果,
MOV A,temp_Byte3
JZ CON_76 ;高字节为0,不够减
DEC temp_Byte3
MOV temp_Byte4,B
SJMP CON_80
CON_76: MOV A,temp_Byte4 ;不够减结束月调整
LJMP CON_46 ;转日期加1 后,处理并保存转换后农历年月日
CON_78: MOV temp_Byte4,A ;temp_Byte3 temp_Byte4 天数为减去一月后天数
CON_80: MOV A,CONvert_mONth
CJNE A,temp_Byte5,CON_82
CPL f0 ;当前月与闰月相同,更改闰月标志
JNB f0,CON_82 ;更改标志后是非闰月,月份加1
SJMP CON_70
CON_82: INC CONvert_mONth;
SJMP CON_70
get_dAys_lOw:
MOVC A,@A+PC ;取得常年过去月的天数的低字节
RET
DB 0,31,59,90,120,151,181,212,243,17,48,78
get_ruN_dAys_lOw:
MOVC A,@A+PC ;取得闰年过去月的天数的低字节
RET
DB 0,31,60,91,121,152,182,213,244,18,49,79
mONth_dAtA:
;公历年对应的农历数据,每年三字节,

;格式第一字节BIT7-4 位表示闰月月份,值为0 为无闰月,BIT3-0 对应农历第1-4 月的大小
;第二字节BIT7-0 对应农历第5-12 月大小,第三字节BIT7 表示农历第13 个月大小
;月份对应的位为1 表示本农历月大(30 天),为0 表示小(29 天).
;第三字节BIT6-5 表示春节的公历月份,BIT4-0 表示春节的公历日期
DB 004h,0Aeh,053h; 1901;
DB 00Ah,057h,048h; 1902
DB 055h,026h,0Bdh; 1903
DB 00dh,026h,050h; 1904
DB 00dh,095h,044h; 1905
DB 046h,0AAh,0B9h; 1906
DB 005h,06Ah,04dh; 1907
DB 009h,0Adh,042h; 1908
DB 024h,0Aeh,0B6h; 1909
DB 004h,0Aeh,04Ah; 1910
DB 06Ah,04dh,0Beh; 1911
DB 00Ah,04dh,052h; 1912
DB 00dh,025h,046h; 1913
DB 05dh,052h,0BAh; 1914
DB 00Bh,054h,04eh; 1915
DB 00dh,06Ah,043h; 1916
DB 029h,06dh,037h; 1917
DB 009h,05Bh,04Bh; 1918
DB 074h,09Bh,0C1h; 1919
DB 004h,097h,054h; 1920
DB 00Ah,04Bh,048h; 1921
DB 05Bh,025h,0BCh; 1922
DB 006h,0A5h,050h; 1923
DB 006h,0d4h,045h; 1924
DB 04Ah,0dAh,0B8h; 1925
DB 002h,0B6h,04dh; 1926
DB 009h,057h,042h; 1927
DB 024h,097h,0B7h; 1928
DB 004h,097h,04Ah; 1929
DB 066h,04Bh,03eh; 1930
DB 00dh,04Ah,051h; 1931
DB 00eh,0A5h,046h; 1932
DB 056h,0d4h,0BAh; 1933
DB 005h,0Adh,04eh; 1934
DB 002h,0B6h,044h; 1935
DB 039h,037h,038h; 1936
DB 009h,02eh,04Bh; 1937
DB 07Ch,096h,0Bfh; 1938
DB 00Ch,095h,053h; 1939
DB 00dh,04Ah,048h; 1940

DB 06dh,0A5h,03Bh; 1941
DB 00Bh,055h,04fh; 1942
DB 005h,06Ah,045h; 1943
DB 04Ah,0Adh,0B9h; 1944
DB 002h,05dh,04dh; 1945
DB 009h,02dh,042h; 1946
DB 02Ch,095h,0B6h; 1947
DB 00Ah,095h,04Ah; 1948
DB 07Bh,04Ah,0Bdh; 1949
DB 006h,0CAh,051h; 1950
DB 00Bh,055h,046h; 1951
DB 055h,05Ah,0BBh; 1952
DB 004h,0dAh,04eh; 1953
DB 00Ah,05Bh,043h; 1954
DB 035h,02Bh,0B8h; 1955
DB 005h,02Bh,04Ch; 1956
DB 08Ah,095h,03fh; 1957
DB 00eh,095h,052h; 1958
DB 006h,0AAh,048h; 1959
DB 07Ah,0d5h,03Ch; 1960
DB 00Ah,0B5h,04fh; 1961
DB 004h,0B6h,045h; 1962
DB 04Ah,057h,039h; 1963
DB 00Ah,057h,04dh; 1964
DB 005h,026h,042h; 1965
DB 03eh,093h,035h; 1966
DB 00dh,095h,049h; 1967
DB 075h,0AAh,0Beh; 1968
DB 005h,06Ah,051h; 1969
DB 009h,06dh,046h; 1970
DB 054h,0Aeh,0BBh; 1971
DB 004h,0Adh,04fh; 1972
DB 00Ah,04dh,043h; 1973
DB 04dh,026h,0B7h; 1974
DB 00dh,025h,04Bh; 1975
DB 08dh,052h,0Bfh; 1976
DB 00Bh,054h,052h; 1977
DB 00Bh,06Ah,047h; 1978
DB 069h,06dh,03Ch; 1979
DB 009h,05Bh,050h; 1980
DB 004h,09Bh,045h; 1981
DB 04Ah,04Bh,0B9h; 1982
DB 00Ah,04Bh,04dh; 1983
DB 0ABh,025h,0C2h; 1984
DB 006h,0A5h,054h; 1985
DB 006h,0d4h,049h; 1986
DB 06Ah,0dAh,03dh; 1987
DB 00Ah,0B6h,051h; 1988
DB 009h,037h,046h; 1989
DB 054h,097h,0BBh; 1990
DB 004h,097h,04fh; 1991
DB 006h,04Bh,044h; 1992
DB 036h,0A5h,037h; 1993
DB 00eh,0A5h,04Ah; 1994
DB 086h,0B2h,0Bfh; 1995
DB 005h,0ACh,053h; 1996
DB 00Ah,0B6h,047h; 1997
DB 059h,036h,0BCh; 1998

DB 009h,02eh,050h; 1999
DB 00Ch,096h,045h; 2000
DB 04dh,04Ah,0B8h; 2001
DB 00dh,04Ah,04Ch; 2002
DB 00dh,0A5h,041h; 2003
DB 025h,0AAh,0B6h; 2004
DB 005h,06Ah,049h; 2005
DB 07Ah,0Adh,0Bdh; 2006
DB 002h,05dh,052h; 2007
DB 009h,02dh,047h; 2008
DB 05Ch,095h,0BAh; 2009
DB 00Ah,095h,04eh; 2010
DB 00Bh,04Ah,043h; 2011
DB 04Bh,055h,037h; 2012
DB 00Ah,0d5h,04Ah; 2013
DB 095h,05Ah,0Bfh; 2014
DB 004h,0BAh,053h; 2015
DB 00Ah,05Bh,048h; 2016
DB 065h,02Bh,0BCh; 2017
DB 005h,02Bh,050h; 2018
DB 00Ah,093h,045h; 2019
DB 047h,04Ah,0B9h; 2020
DB 006h,0AAh,04Ch; 2021
DB 00Ah,0d5h,041h; 2022
DB 024h,0dAh,0B6h; 2023
DB 004h,0B6h,04Ah; 2024
DB 069h,057h,03dh; 2025
DB 00Ah,04eh,051h; 2026
DB 00dh,026h,046h; 2027
DB 05eh,093h,03Ah; 2028

DB 00dh,053h,04dh; 2029
DB 005h,0AAh,043h; 2030
DB 036h,0B5h,037h; 2031
DB 009h,06dh,04Bh; 2032
DB 0B4h,0Aeh,0Bfh; 2033
DB 004h,0Adh,053h; 2034
DB 00Ah,04dh,048h; 2035
DB 06dh,025h,0BCh; 2036
DB 00dh,025h,04fh; 2037
DB 00dh,052h,044h; 2038
DB 05dh,0AAh,038h; 2039
DB 00Bh,05Ah,04Ch; 2040
DB 005h,06dh,041h; 2041
DB 024h,0Adh,0B6h; 2042
DB 004h,09Bh,04Ah; 2043
DB 07Ah,04Bh,0Beh; 2044
DB 00Ah,04Bh,051h; 2045
DB 00Ah,0A5h,046h; 2046
DB 05Bh,052h,0BAh; 2047
DB 006h,0d2h,04eh; 2048
DB 00Ah,0dAh,042h; 2049
DB 035h,05Bh,037h; 2050
DB 009h,037h,04Bh; 2051
DB 084h,097h,0C1h; 2052
DB 004h,097h,053h; 2053
DB 006h,04Bh,048h; 2054
DB 066h,0A5h,03Ch; 2055
DB 00eh,0A5h,04fh; 2056
DB 006h,0B2h,044h; 2057
DB 04Ah,0B6h,038h; 2058
DB 00Ah,0Aeh,04Ch; 2059
DB 009h,02eh,042h; 2060
DB 03Ch,097h,035h; 2061
DB 00Ch,096h,049h; 2062
DB 07dh,04Ah,0Bdh; 2063
DB 00dh,04Ah,051h; 2064
DB 00dh,0A5h,045h; 2065
DB 055h,0AAh,0BAh; 2066
DB 005h,06Ah,04eh; 2067
DB 00Ah,06dh,043h; 2068
DB 045h,02eh,0B7h; 2069
DB 005h,02dh,04Bh; 2070
DB 08Ah,095h,0Bfh; 2071
DB 00Ah,095h,053h; 2072

DB 00Bh,04Ah,047h; 2073
DB 06Bh,055h,03Bh; 2074
DB 00Ah,0d5h,04fh; 2075
DB 005h,05Ah,045h; 2076
DB 04Ah,05dh,038h; 2077
DB 00Ah,05Bh,04Ch; 2078
DB 005h,02Bh,042h; 2079
DB 03Ah,093h,0B6h; 2080
DB 006h,093h,049h; 2081
DB 077h,029h,0Bdh; 2082
DB 006h,0AAh,051h; 2083
DB 00Ah,0d5h,046h; 2084
DB 054h,0dAh,0BAh; 2085
DB 004h,0B6h,04eh; 2086
DB 00Ah,057h,043h; 2087
DB 045h,027h,038h; 2088
DB 00dh,026h,04Ah; 2089
DB 08eh,093h,03eh; 2090
DB 00dh,052h,052h; 2091
DB 00dh,0AAh,047h; 2092
DB 066h,0B5h,03Bh; 2093
DB 005h,06dh,04fh; 2094
DB 004h,0Aeh,045h; 2095
DB 04Ah,04eh,0B9h; 2096
DB 00Ah,04dh,04Ch; 2097
DB 00dh,015h,041h; 2098
DB 02dh,092h,0B5h; 2099
DB 00dh,053h,049h; 2100
;以下子程序用于从当前公历日期,推算星期,
;入口:time_yeAr,time_month ,time_date ,定义公历年月日,BCD 码,其中月的
;BIT7 表示世纪,0 表示20 世纪,1 表示19 世纪,与PCF8563 一致
;出口 time_week, 0-6 表示星期日-星期六,与PCF8563 一致,程序不改变入口数据
;使用资源:ACC,B,psw,temp_Byte1,temp_Byte2,temp_Byte3
GetWeek: MOV A,time_yeAr
MOV B,#16
DIV AB
MOV temp_Byte1,B
MOV B,#10
MUL AB
ADD A,temp_Byte1
MOV temp_Byte1,A ;temp_Byte1=年
MOV A,time_month
JB ACC.7,getw02

MOV A,#100
ADD A,temp_Byte1
MOV temp_Byte1,A ;20世纪年+100
MOV A,time_month
CLR ACC.7
getw02: JNB ACC.4,getw04
ADD A,#10
CLR ACC.4
getw04: MOV temp_Byte2,A ;temp_Byte2=月
MOV A,time_date
MOV B,#16
DIV AB
MOV temp_Byte3,B
MOV B,#10
MUL AB
ADD A,temp_Byte3
MOV temp_Byte3,A ;temp_Byte3=日
MOV A,temp_Byte1;
ANL A,#03h
JNZ getw10 ;非闰年转移
MOV A,temp_Byte2
CJNE A,#3,getw06
getw06: JNC getw10 ;月大于2 转移
DEC temp_Byte3 ;份小于等于2,又是闰年,日减1
getw10: MOV A,temp_Byte2;
LCALL get_CorreCt ;取月校正表数据
ADD A,temp_Byte1
MOV B,#7
DIV AB ;B放年加校正日数之和后除7 的余数不先做这一步
;有可能数据溢出
MOV A,temp_Byte1
ANL A,#0fCh
RR A
RR A ;以上年除4 即闰年数
ADD A,B
ADD A,temp_Byte3
MOV B,#7
DIV AB
MOV time_week,B
RET
get_COrreCt:
MOVC A,@A+PC
RET
DB 0,3,3,6,1,4,6,2,5,0,3,5
xing:db 0FEH,060H,0DAH,0F2H,066H,0B6H,0BEH,
TAB:DB 0FCH,060H,0DAH,0F2H,066H
      DB 0B6H,0BEH,0E0H,0FEH,0F6H
chxie_ds1302:  mov  r0,#sec
       mov  r7,#7
       setb  psw.5
       lcall  rwrtc
       ret
dingshi :MOV  r0,#70h
        mov  r7,#02h
        setb  psw.5
        lcall  rwrtc
        MOV  A,70H
        CJNE  A,HOUR,DINGSHI1
        RET
DINGSHI1:MOV  A,71H
         CJNE  A,#MIN,OUT4
         CLR  P0.6
   OUT4 :    ret 

       END
点击下载(用Protel可以打开,结果如下图)
点击开大图


系统分类: 单片机  |  用户分类: 单片机  |  标签: 万年历  |  来源: 整理  | 

点击查看原文

发表评论 阅读全文(3086) | 回复(7)

2Next >Total , Page /