找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1695|回复: 0
收起左侧

单片机电话拨号防盗报警器程序设计

[复制链接]
ID:556863 发表于 2020-11-18 18:09 | 显示全部楼层 |阅读模式

硬件系统方案设计

图2.1为电话拨号报警器的系统构成方框图,由单片机控制器、键盘输入、数码管显示、触发电路、拨号电路及电源等6部分组成。

单片机控制器是整个系统的核心,负责控制检测输入/输出显示、模拟摘机、拨号摘机、拨号报警、挂机等一系列的程序动作。这里使用了小引脚、高性能、低价位的AT89S2052。

  键盘输入电路负责输入电片机中一系列工作参数及功能设定。

  发光二极管数码管显示器在整个系统工作过程中充当一个简单的人机界面,用以显示工作状况及输入/输出的数据等。

  电话拨号防盗报警器的触发电路用磁性开关(门磁开关),简单可靠,也可用红外探测器或无线门磁,以实现全方位远距离监测。报警器应采用隐蔽安装,防止小偷发现。

  拨号及报警电路用来完成模拟摘机、拨号、发出报警音、挂机等工作过程,它的工作由单片机控制。

  电源部分负责对整个系统供电。平时由电话线上取得工作电流并对后备电池充电,拨号报警时转由后备电池供电。

                         图2.1 电话拨号防盗报警器方框图

2.1.2脉冲拨号原理

脉冲拨号是目前电话机两种拨号方式中的一种,另一种为双音多频拨号方式。

脉冲拨号就是指在电话机上拨入的电话号码以脉冲个数的形式发出,也就是说,在已经通以直流电流的回路上,利用拨号盘及发号电路将回路断开、再接通而形成的脉冲信号,来完成输入电话号码的发送。在操作中,若用户拨1,则送出1个脉冲,回路中断一次、接通一次;拨2,则发出2个脉冲,回路断一次、接通一次、再断一次;……;而拨0时,则发出10个脉冲,回路断、接通轮流10次。图2.2为电话号码“32”的脉冲波形。

                    图2.2  电话号码“32”的脉冲波形


   正常拨号时,电路电流中断的时间一般在58~65ms之间,视断续比的不同而不同。快速拨号时,只要取一半时间即可。电路电流接通的时间(即在同一位号码中的2个断脉冲之间的接通电流时间)约在32~42ms之间,视断续比的不同而不同。快速拨号时,只要取一半时间即可。显然脉冲周期等于脉冲中断时间和脉冲接通时间之和,每一个周期的时间为100ms左右。快速拨号时,在50ms左右。2位号码(即2组脉冲串)之间的最小时间间隔,通常为800ms左右;而快速拨号时,其值减半,为400ms左右。

我国目前采用的电话脉冲拨号的速率是10PPS(每秒的脉冲数),即每秒发出10个脉冲,因此上述各参数不存在快速拨号时的值。

   为了提高拨号的可靠性及稳定性,这里设计时选定更低的脉冲拨号速率:1个脉冲代表播出1,2个脉冲代表拨出2,……,10个脉冲代表拨出0,每个脉冲的宽度和间隔为100ms。工作时首先进行模拟摘机,然后开始脉冲拨号,拨出1位号码后停顿500ms(保持接通)再拨下一位,直至全部拨完后再发报警音,……,最后挂机。


2.1.3  脉冲拨号实现过程

图2.3为脉冲拨号的实现电路。平时电话线上的电压约为50~60V左右。未拨号时电片机的P3.0、P3.1 均输出低电平。

拨号过程如下:

①单片机的P3.0输出高电平,使TR1导通,由于电话线路上接入了负载R1,这样电话线的电压下降,模拟摘机。

②单片机的P3.0开始输出拨号脉冲,使电话线的电压(电平)也呈高、低变化。1个脉冲代表拨出1,2个脉冲代表拨出2,……,10个脉冲代表拨出0,每个脉冲的宽度和间隔均为100ms。拨出1位号码后停顿500ms(保持P3.0高电平)再拨下一位,直至全部拨完。

③P3.0 保持高电平(保持电话线路接通),P3.1输出1KHz的报警音脉冲驱动TR2,以2Hz进行调制(即接通1kHz信号0.5s、断开1kHz信号0.5s),这样从接听方的电话中就会听到“嘟、嘟……”的报警声。报警音的时间根据设计为60s。

④60后,P3.1输出低电平,TR2 截止,停止报警。随后P3.0也输出低电平,模拟挂机。完成一次报警过程。



电路原理如图所示,共有4个按键,即rst、ok、up、set。

rst:系统复位键。

ok:输入数据确认键。

up:显示的数字增加键。

set:工作模式设定键,可设定管机、工作、输入时间t1、输入时间t2及输入电话号码5种模式。

   磁性开关即为装于门或窗口的防盗感应开关,门关闭时常开,门打开时闭合接通。当然也可改用其他的感应器件,如激光探测、超声波感应、热释电感应、主动红外线探测或无线门磁等,以实现全方位远距离检测。为了防止磁性开关离控制器较远而产生引入干扰,使用了光耦作信号传递,效果良好。LED数码管用于工作状态指示或输入数据指示。L1、L2接电话线,ZND为击穿电压120V的压敏二极管,防止电路受雷电干扰。平时系统处于低功耗待机状态(此时耗电仅2mA左右),由电话线上取电工作,并对3.6V/60mA镍铬电池充电,当输入数据进行设定或进行拨号报警时,耗电会达到10mA,这时主要由镍铬电池供电。由于有镍铬电池后备供电,即使电话线断电也不会使已输入的数据丢失。该机除用于防盗报警外,若对软件进行一些修改,也可通过电话线进行远程数据传递。三极管T1、T2及电阻R1、R2构成拨号及报警电路,其工作原理前面已作详细介绍。

4.1.2时钟计时器的硬件电路设计描述

时钟计时器的硬件电路,采用AT89S52单片机最小化应用设计,显示采用共阳七段LED显示器,P0口输出段数码数据,P2.0~P2.5口作列扫描输出,P1.0,P1.1和P1.2口接三个按钮开关用以实现调时,调分功能.为了提供共阳LED数码管的驱动电压,用三极管8550作电源驱动输出。采用12MHZ晶振有利于提高秒计时的精确性。硬件电路图如图3.2示。


系统的软件设计

3.1电话拨号防盗报警器程序设计

3.1.1主程序设计

主程序的工作过程为:先进行初始化工作,随后根据输入的键值分别散转输入的键值分别散转至对应的子程序(管机、警戒工作、输入时间t1、输入时间t2、输入电话号码)循环工作。T0为100ms定时中断服务子程序,它实现精确的拨号脉冲时序。INT0外中断服务子函数用于实现功能选择;而INT1外中断服务子函数则检测防盗触发开关的状态。

   主程序状态流程图如图3.6所示。INT0外中断服务子函数状态流程图及INT1外中断服务子函数的状态流程图分别如图3.7、图3.8所示。

                                                                                                         - 1 -


3.2 时钟显示程序设计

3.2.1主函数

  本设计中计时采用定时器T0中断完成,其余状态循环调用显示子函数及键扫描子函数,当端口开关按下时,转入相应调时功能。其主函数执行流程如图3.3所示。



3.2.2 LED显示子函数

  数码管显示的数据存放在内存单元dis[0]~dis[5]中,其中dis[0]~dis[1]存放秒数据,dis[2]~dis[3]存放分数据,dis[4]~dis[5]存放时数据,每一单元内均为十进制BCD码。由于采用软件动态扫描实现数据显示功能,显示用的十进制BCD码数据的对应段码存放在ROM表(dis7[11])中,显示时,先取出dis[0]~dis[5]中的某一数据,然后查得对应得显示段码从P0口输出,P2口将对应得数码管选中供电,就能显示该地址单元的数据值。

3.2.3定时器T0中断函数

  定时器T0用于时间计时。定时溢出中断周期可设为50ms,中断进入后先判断,中断计时累计20次(即1ms)时对妙计数单元进行加1操作。时钟计数单元在 义的6个单元(timedata[6])中。timedata[0]~timedata[1]存放秒数据,timedata[2]~timedata[3]存放分数据,timedata[4]~timedata[5]存放时数据。最大计时值为23小时59分59秒。在计数单元中采用十进制BCD码计数,秒,分、时之间满60进位。T0中断服务程序执行流程如图3.4所示。







3.2.4中断函数

  T1中断服务程序用于指示调整数字单元的亮闪,在时间调整状态下,每过0.4s,将对应单元的显示数据换成“熄灭符”数据(0x0a)。这样,在调整时间时,对应调整单元的显示数据会间隔闪亮。

3.2.5功能函数

  调时功能函数的设计方法是:按下T0键,进入调分状态,时钟停止走动;按T1或T2键可进行加1或减1操作 ;继续按T0键可分别进行分十位、时个位和时十位调整;最后按T0建将退出调整状态,时钟开始计时运行。



系统的调试部分

4.1 时钟系统的调试

4.1.1时钟系统的硬件调试

硬件调试时可先检查印制板及焊接的质量情况,在检查无误后可通电检查LED显示器的点亮状况。若亮度不理想,可以调整P0口的电阻大小,一般情况下取200欧姆电阻即可获得满意的亮度效果。

4.1.2时钟系统的件调试

软件调试Keil C51编译器,源程序编译及仿真调试应分段或以子函数为单位一个个地进行,最后可结合硬件实时运行调试。

4.1.3性能分析

按照设计程序分析,LED显示器动态扫描频率约为167Hz,实际使用观察时完全没有闪烁,实际计时时精度较高,可满足一般场合的应用需要。


4.2拨号报警器功能调试

通电前应检查焊接质量,确认无短路、虚焊等故障。将拨码开关J2指向下侧,即断开3.6V镍铬电池与系统的连接。将外部直流可调稳压电源调整为3.6V。接入系统的Vcc与地。如果系统耗电小于15mA为正常,否则应检查是否有短路、元器件不良或错焊现象存在。随后取下外接直流稳压电源,恢复3.6V镍铬电池与系统的连接,进行软、硬件统调测试。

由于AT89S52的I/O引脚有限,故数码管只设一位,因此输入数字时只能分阶段一位一位输入。

假设需输入t1=061,t2=025,电话号码=12345678,在此详述如下:

地1步:接上电话线(也即接上电源)后,数码管显示“E”,意为数据错误,因为此时我们尚未输入任何数据。

第2步:

①点按一下set键,键值加1,即此时set=1.这时数码管最下的一横点亮,显示“_”,意为可输入时间t1,点按ok键确认(小数点被同时点亮)。然后数码管显示数字“0”。

②按下up键后,数字开始从0~9循环递增,调至0后松开up键,点按ok键确认(小数点被同时点亮)。此时百位数字“0”存入内存。

③按下up键后,数字开始循环递增,调至1后松开up键,点按ok键确认(小数点被同时点亮)。此时十位数字“6”存入内存。

④按下up键后,数字开始循环递增,调至1后松开up键,点按ok键确认(小数点被同时点亮)。此时个位数字“6”存入内存。

这样就完成了将061(代表t1=61s)存入内存的过程。同时数码管又恢复显示“_”

第3步:

①点按一下set键,键值加1,即此时set=2。这时数码管下面的二横点亮,显示“二”,意为可输入时间t2,点按ok键确认(小数点被同时点亮)。然后数码管显示数字“0”。

②按下up键后,数字开始从从0~9循环递增,调至0后松开up键,点按ok键确认(小数点被同时点亮)。此时百位数字“0”存入内存。

③按下up键后,数字开始循环递增,调至2后松开up键,点按ok键确认(小数点被同时点亮)。此时十位数字“2”存入内存。

④按下up键后,数字开始循环递增,调至5后松开up键,点按ok键确认(小数点被同时点亮)。此时个位数字“5”存入内存。

这样就完成了将025(代表t1=25s)存入内存的过程。同时数码管又恢复显示“二”

以后的调试同前面的方法相同。


(1) 电话拨号报警程序
程序设计时需要设立3个数组DATA[20]、X[3]、Y[3]。DATA[20]用于存放电话号码(最长20位),X[3]用于存放时间t1(000~999s),Y[3]用于存放时间t2(000~999s)。
  另外还要设立3个软件计数器data_flag、t1_flag、t2_flag。Data_flag用于统计输入的电话号码位长,t1_flag用于统计输入的时间t1位长,t2位长。
  1. uchar DATA[20];     /*存放电话号码的数组*/
  2. uchar X[3];         /*存放时间t1数组*/
  3. uchar Y[3];         /*存放时间t2数组*/
  4. uchar flag;         /*RAM区防干扰标志*/
  5. uchar data_flag=0; /*输入电话号码计数器(最长20位)*/
  6. uchar set=0;     /*功能键值*/
  7. uchar m=0;      //全局变量
  8. uchar n=0;
  9. uint f;
  10. uchar t1_flag=0;     /*输入时间t1计数器(最长3位)*/
  11. uchar t2_flag=0;     /*输入时间t2计数器(最长3位)*/
  12. uchar cnt_1=0;        /*时间t1单元数学运算后暂存单元*/
  13. uchar cnt_2=0;       /*时间t2单元数学运算后暂存单元*/
  14. /*定时器T0初始化*/
  15. viod init_timer()
  16. {
  17. TMOD=0x01;             //定时器T0方式1
  18. TH0=-(50000/256);      //装载100ms定时初值
  19. TL0=-(50000%256);
  20. IE=0x82;               //开中断
  21. }
  22.   启动报警器子程序模块

  23. /*---启动报警器进入警戒---*/
  24. void work()
  25. {uchar h;
  26. p1=0xdf;    /*数码管左上角显示“1”*/
  27. delay(1);
  28. if(set==1)   /*进入时间1循环*/
  29. {while(cnt<=x[0]*100+X[1]*10+X[2])
  30.      {
  31.       delay(1000);
  32.       cnt_1++;                 /*计数器cnt_1累加*/
  33.       if(set!=1){EX1=0;cnt_1=0;break;}
  34.       }                         /*如按下Set键,则推出此循环*/
  35. }
  36. else {EX1=1;PCON=0x00;}
  37. if(set==1)
  38. {if(cnt_1>=X[0]*100+X[1]*10+X[2])
  39.    {EX1=1;cnt_1=0;}   /*时间1到,打开外中断1,计数器归零*/
  40. /*进入待机。若有1s以上开关动作,退出待机*/
  41. while(1)
  42. {PCON=0x01;if(f>=5{PCON=0x00;break;})
  43. }
  44. /*-----------------------------------------------------------*/
  45. EX1=0;  /*关闭外中断1*/
  46. if(set==1)    /*进入时间2循环*/
  47. {while(cnt_2<=Y[0]*100+Y[1]*10+Y[2])
  48.    {
  49.      delay(1000);
  50.      cnt_2++;   /*计时器cnt_2累加*/
  51.      if(set!=1){cnt_2=0;break;}
  52.    }           /*如按下Set键,则退出此循环*/
  53. }
  54. if(set==1)
  55. {
  56. bh();        /*时间2到,调用拨号子程序*/
  57. delay(3000);
  58. p3_7=0;    //控制输出端为低,可驱动蜂鸣器等
  59. for(h=0;h<60;h++)   /*发出60s警音*/
  60. {   for(f=0;f<500;f++)
  61.     {f++;
  62.      P3_1=! P3_1;P1=0x5f;
  63.      delay(1);
  64.      }
  65.     P3_1=0;P1=0x7f;delay(500);
  66. }
  67. P3_7=1;//控制输出端恢复高
  68. cnt_1=0;cnt_2=0;   /*有关计数器、端口回到初始状态*/
  69. P3_0=0;P3_1=0;P1_7=1;
  70. for(f=0;f<3;f++)delay(60000);  /*关闭3min,让接警人进行手机或电话座机报警*/
  71. }
  72. }

  73.      拨号脉冲子程序模块

  74. /*---拨号---*/
  75. void bh()
  76. {data_flag=0;   /*电话号码计数器(20位)归零*/
  77.    P3_0=1;     /*接通线路*/
  78.    p1_7=0;     /*数码管小数点亮*/
  79.    delay(1000);
  80. while (DATA[data_flag]<10)  /*号码小于10进入循环拨号状态*/

  81. {
  82.   if(DATA[data_flag]==0)    /*若号码为0*/
  83.   {TR0=1;                 /*启动T0定时器*/
  84.     if(n==20){data_flag++;   /*进行20次中断,产生10个脉冲*/
  85.       n=0;TR0=0;
  86.       P3_0=1;P1_7=0;
  87.       delay(500);
  88.               }
  89. }
  90. if(DATA[data_flag]>0)   /*若号码〉0但<10*/
  91. {TR=1;                 /*启动T0定时器*/
  92. if(n==((DATA[data_flag]*2))   /*进行号码x2次中断,产生号码个脉冲*/
  93.       {data_flag++;
  94.         n=0;TR0=0;
  95.         P3_0=1;P1_7=0;
  96.         delay(500);
  97.        }
  98. }
  99. }
  100. TR0=0;
  101. }

  102.       关机子程序模块

  103. void stop()             //*关机子程序
  104. {if(flag==0x55)P1=0xfb; //*若标志为55H,说明内存区未受干扰,数码
  105.                         //管右下角显示“1”
  106.     else P1=0x86;      //否则数码管显示“E”
  107. delay(1);               //延时1ms再判
  108. if(flag==0x55)PCON=0x01; //进入低耗节电待机状态
  109. delay(1);    //延时1ms
  110. }

  111.      完整代码

  112. #include<AT89x052.H>   //器件配置文件
  113. #define uchar unsigned char  //变量类型的宏定义
  114. #define uint unsigned int
  115. uchar code DATA_7SEG[10]={0xC0,0xF9,0xA4,0xB0,0x99
  116.                           0x92,0x82,0xF8,0x80,0x90,}; /*0~9数码管段码*/
  117. uchar DATA[20]; /*存放电话号码的数组*/
  118. uchar x[3];    /*存放时间t2数组*/
  119. uchar flag;   /*RAM区防干扰标志*/
  120. uchar data_flag=0;   /*输入电话号码计数器(最长20位)*/
  121. uchar set=0;    /* 功能键值*/
  122. uchar m=0;  //全局变量
  123. uchar n=0;
  124. uint f;
  125. uchar t1_flag=0;    /*输入时间1计数器(最长3位)*/
  126. uchar t2_flag=0;   /*输入时间2 计数器(最长3位)*/
  127. uchar cnt_1=0;     /*时间t1单元数学运算后暂存单元*/
  128. uchar cnt_2=0;     /*时间t2单元数学运算后暂存单元*/
  129. /*************************************************/
  130. void delay(uint k);   /*延时子函数声明*/
  131. void stop();          /*关机子函数声明*/
  132. void bh();           /*拨号子函数声明*/
  133. /*************************************************/
  134. /*定时器T0初始化*/
  135. void init_timer()
  136. {
  137. TMOD=0x01;
  138. TH0=-(50000/256);
  139. TL0=-(50000%256);
  140. IE=0x82;
  141. }
  142. /***********************************************************/
  143. /*100ms定时中断服务子函数*/
  144. void zd0()interrupt 1
  145. {
  146. P3_0=! P3_0;   //P3.0每100ms取反一次,送出脉冲
  147. P1_7=! P1_7;   //数码管小数点同步闪烁
  148. n++;
  149. TH0=-(50000/256);
  150. TL0=-(50000%256);
  151. }
  152. /********************************************************/
  153. /*100ms定时中断服务子函数*/
  154. void zd0()interrupt 1
  155. {
  156. p3_0=!P3_0;  //P3.0每100ms取反一次,送出脉冲
  157. P1_7=!P1_7;  //数码管小数点同步闪烁
  158. n++;
  159. TH0=-(50000/256);
  160. TL0=-(50000%256);
  161. }
  162. /*********************************************/
  163. /*INT0中断服务子函数*/
  164. viod zd_int0()interrupt 0
  165. {
  166. delay(10);            
  167. if(P3_2==0)set++;    //功能键值递增
  168. if(set>=5)set=0;       //键值的范围0~4
  169. if(set==1)flag=0x55;   //向RAM区的标志flag写入55H
  170. PCON=0x00;f=8;
  171. again:if(P3_2==0)goto again;  //若按键未释放,则等待
  172. }
  173. /*****************************************/
  174. /*INT1中断服务子函数*/
  175. void zd_int1()interrupt 2
  176. {uchar h;
  177. f=0;
  178. for(h=0;h<10;h++)   /*检查磁性开关(P3_3状态)10次,共1s*/
  179. {
  180. delay(100)
  181. if(P3_3==0)f++;
  182. }
  183. }
  184. /********************************************************************/
  185. /*---关机---*/
  186. void stop()
  187. {if(flag==0x55)P1=0xfb;
  188. elsep1=0x86;                           //数码管右下角显示“1”。
  189. delay(1);
  190. if(flag==0x55)PCON=0x01;               /*进入节电待机状态*/
  191. delay(1);
  192. }
  193. /*********************************************************************/
  194. /*延时1ms*K子函数*/
  195. void delay(uint k)
  196. {
  197. uint i,j;
  198. for(i=1;j<k;i++){
  199. for(j=0;j<60;j++)
  200. {;}}
  201. }
  202. /*********************************************************************/
  203. /*----输入时间t1----*/
  204. viod in_time1()
  205. {
  206. P1=0xf7;delay(1);                    /*数码管显示“—”*/
  207. if(P3_5==0)
  208. {
  209.    delay(10);                        /*按下OK键确认并点亮小数点*/
  210.    if(P3_5==0){P1=0x7f;m=0;t1_flag=0;delay(500);}
  211. while(t1_flag<3)
  212.     {
  213.      if(P3_4==0)
  214. {delay(10);if(P3_4==0)               /*按下UP键数码管作0~9递增显示*/
  215.             {m++;if(m==10)m=0;P1=DATA_7SEG[m];delay(300);}
  216. }
  217. P1=DATA_7SEG[m];delay(1);           /*若不按下UP键数码管也作0~9显示*/
  218. if(P3_5==0)                        
  219. {delay(10);if(P3_5==0)              /*按下OK键显示的数据存入数组X中*/
  220.    {X[t1_flag]=m;t1_flag++;P1=0x7f;delay(500);}
  221.     }
  222.    }
  223. }
  224. if(t1_flag>=3)t1_flag=0;            /*时间1计数器>=3时归零*/
  225. }
  226. /**********************************************************************
  227. /
  228. /*-----输入时间t2-----*/
  229. viod in_time2()
  230. {
  231. P1=0xb7;delay(1);                  /*数码管显示“二”*/
  232. if(P3_5==0)
  233. {
  234.    delay(10);                      /*按下OK键确认并点亮小数点*/
  235.    if(P3_5==0){P1=0X7f;m=0;t2_flag=0;delay(500);}
  236. while(t2_flag<3)
  237. {
  238. if(P3_4==0)
  239.    {delay(10);if(P3_4==0)           /*按下UP键数码管作0~9递增显示*/
  240.                {m++;if(m==10)m=0;P1=DATA_7SEG[m];delay(300);}
  241. }
  242. P1=DATA_7SEG[m];delay(1);           /*若不按UP键数码管也作0~9显示*/
  243. if(P3_5==0)
  244. {delay(10);if(P3_5==0)              /*按下OK键显示的数据存入数组Y中*/
  245.   {Y[t2_flag=m;t2_flag++;P1=0x7f;delay(500);}

  246.    }
  247.   }
  248. }
  249. if(t2_flag>=3)t2_flag=0;            /*时间2计数器>=3时归零*/
  250. }
  251. /***********************************************************************
  252. /
  253.     /*----输入电话号码----*/
  254. vioa in_data()
  255. {uchar g;                        
  256. P1=0xb6;delay(1);                    /*数码管显示三*/
  257. if(P3_5==0)
  258. {delay(10);if(P3_5==0)
  259.            {p1=0x7f;m=0;data_flag=0; /*按下OK键确认并点亮小数点*/
  260.            for(g=0;g<20;g++){DATA[g]=10;}
  261.            delay(500);                /*同时DATA数组中全部写入10*/
  262.            while(1)
  263.            {
  264.            if(P3_4==0){delay(10);      /*按下UP键数码管作0~9递增显示*/        
  265.                if(P3_4==0);{m++;if(m==10)m=0;P1=DATA_7SEG[m];delay(300);}
  266.                       }
  267.            P1=DATA_7SEG[m];delay(1);     /*若不按UP键数码管也作0~9显示*/
  268.            if(P3_5==0)
  269.                {delay(10);
  270.                 if(P3_5==0)                /*按下OK键显示的数据(号码)存入数组DATA中*/
  271.                 {DATA[data_flag]=m;data_flag++;P1=0x7f;delay(500);}
  272.                  }                          /按下OK键超过2s则退出向数组DATA送入号码*/
  273.                 if(P3_5==0){delay(2000);if(P3_5==0)break;}
  274.                 }
  275. }
  276. }
  277. F1:if(P3_5==0){delay(10);if(P3_5==0){P1=0xb6;delay(1);goto F1;}}


  278. /********************************************************************/
  279. /*--主函数--*/
  280. void main()
  281. {
  282. int_timer();   /*定时器T0初始化*/
  283. EA=1;EX0=1;    /*开总中断,开外中断0*/
  284. p3_0=0;        /*关闭线路(挂机)*/
  285. p3_1=0;
  286. while(1)       /*无限循环*/
  287. {
  288. switch(set)    /*根据Set标志散转*/
  289. {
  290. case 0:stop();break;  /*关机*/
  291. case 1:work();break;  /*警戒工作*/
  292. case 3:in_time2();break; /*输入时间t1*/
  293. case 4:in_data();break;
  294. }
  295.      if(flag!=0x55)
  296.        {p1=0x86;delay(1);}
  297. }
  298. }


  299. (2) 时钟计时器程序
  300. /**************************************************************/
  301. //          采用6位LED动态扫描时钟演示程序
  302. //         使用Keil C51
  303. //         2004.03.31
  304. /*************************************************************/
  305. /*使用AT89S52单片机,12MHZ晶振,P0口输出段码,P2口作列扫描,用共阳LED数码管*/
  306. //key0为调时位选用,key1为加1键,key2为减1键
  307. #include "reg51.h"
  308. #define char unsigned char
  309. //
  310. char code dis_7[11]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xff};
  311. /*共阳LED段码表"0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "不亮"*/
  312. char code scan_con[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};  //列扫描控制字
  313. char data timedata[6]={0x00,0x00,0x00,0x00,0x00,0x00};             //计时单元数据初值,共6个
  314. char data dis[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x0a,0x00,};      //显示单元数据,共6个数据
  315. char data con1s=0x00,con04s=0x00,con=0x00;    //秒定时用
  316. sbit key0=P1^0;
  317. sbit key1=P1^1;
  318. sbit key2=P1^2;
  319. //
  320. /************/
  321. //1ms延时函数//
  322. /***********/
  323. dalaylms(int t)
  324. {
  325. int i,j;
  326. for(i=0;i<t;i++)
  327.   for(j=0;j<120;j++)
  328.   ;
  329. }
  330. /*************/
  331. //键扫描子函数//
  332. keyscan()
  333. {
  334. EA=0;
  335. if(key0==0)
  336. {
  337. delaylms(10);
  338. while(key0==0);
  339. if(dis[con]==10)
  340. {dis[7]=dis[con];dis[con]=dis[6];dis[6]=dis[7];}
  341. con++;TR0=0;ET0=0;TR1=1;ET1=1;
  342. if(con >=6)
  343.   {con=0;TR1=0;ET1=0;TR0=1;ET0=1;}
  344. }
  345. //
  346. if(con!=0)
  347. {
  348.   if(key1==0)
  349.   {
  350.    delaylms(10);
  351.   while(key1==0);
  352.   timedata[con]++
  353.   if(timedata[con]>=10)
  354.     {timedata[con]=0;}
  355. dis[con]=timedata[con];dis[6]=0x0a;

  356.     }
  357. }
  358. //
  359. if(con!=0)
  360. {
  361. if(key2==0)
  362. {
  363.   delaylms(10);
  364. while(key2==0);
  365.    if(timedata[con]==0)
  366.      {timedata[con]=0x90;}
  367.    else{timedata[con]--;}
  368. dis[con]=timedata[con];dis[6]=0x0a;

  369.   }
  370. }
  371. EA=1;
  372. }
  373. //
  374. /***********/
  375. //显示函数//
  376. /***********/
  377. scan()
  378. {
  379. char k;
  380. for(k=0;k<6;k++)
  381. {
  382. p0=dis_7[dis[k]];p2=scan_con[k];delaylms(1);p2=0xff;
  383.   }
  384. }
  385. /*************/
  386. //初始化函数//
  387. /*************/
  388. clearmen()
  389. {
  390. int i;
  391. for(i=0;i<6;i++)
  392.   {
  393.   dis[i]=timedata[i];}
  394. TH0=0x3C;TL0=0xB0;                             //50ms定时初值(T0计时用)
  395. TH1=0x3C;TL1=0xB0;                             //50ms定时初值(T1计时用)
  396. TMOD=0X11;ET0=1;ET1=1;TR1=0;TR0=1;EA=1;
  397. }
  398. /**********/
  399. //主函数//
  400. /*********/
  401. main()
  402. {
  403. clearmen();
  404. while(1)
  405.   {
  406.    scan();
  407.    keyscan();
  408.    }
  409. }
  410. /********************/
  411. //1s中断处理函数//
  412. /*******************/
  413. viod time_intt0(viod) interrupt 1
  414. {
  415. ET0=0;TR0=0;TH0=0x3C;TL0=0xB0;TR0=1;
  416. con1s++;
  417. if(con1s==20)
  418.   {
  419. con1s=0x00;
  420. timedata[0]++;
  421. if(timedata[0]>=10)
  422. {
  423. timedata[0]=0;timedata[1]++;
  424. if(timedata[1]>=6)
  425.   {
  426.    timedata[1]=0;timedata[2]++;
  427.      if(timedata[2]>=10)
  428.        {
  429.         timedata[2]=0;timedata[3]++;
  430.         if(timedata[3]>=6)
  431.           {
  432.            timedata[3]=0;timedata[4]++;
  433.            if(timedata[4]>=10)
  434.              {
  435.               timedata[4]=0;timedata[5]++;
  436.                  }
  437.               if(timedata[5]==2)
  438.                     {
  439.                   if(timedata[4]==4)
  440.                     {
  441.                      timedata[4]=0;timedata[5]=0;
  442.                     }
  443.                  }
  444.               }
  445.          }
  446.       }
  447.   }
  448. dis[0]=timedata[0];dis[1]=timedata[1];dis[2]=timedata[2];
  449. dis[3]=timedata[3];dis[4]=timedata[4];dis[5]=timedata[5];
  450.   }
  451. ET0=1;
  452. }
  453. /********************/
  454. //0.4S闪烁中断函数//
  455. /*******************/
  456. viod time_intt1(viod) interrupt3
  457. {
  458. EA=0;TR1=0;TH1=0x3C;TL1=0xB0;TR1=1;
  459. con04s++;
  460. if(con04s==8)
  461.   {
  462.    con04s=0x00;
  463.    dis[7]=dis[con];dis[con]=dis[6];dis[6]=dis[7];
  464.    }
  465.    EA=1;
  466. }
复制代码


以上的Word格式文档51黑下载地址:
文档.doc (255.5 KB, 下载次数: 15)
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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