采用AT89C2051的数字可调稳压电源单片机源程序
- 格式:doc
- 大小:33.50 KB
- 文档页数:3
; AT89C2051风扇定时阵风控制器源程序(三位数)显示OK!!; p3.2=阵风设置开关; 硬件:P3.0=-1键、P3.1=功能键、P3.5=个位显示、; P3.4=十位显示、P3.3=百位显示、P3.7=输出端org 0000hajmp mainnoporg 01bhajmp dszdljmp 0000hnopnopajmp 0000horg 30hmain: mov 40h,#00hmov 41h,#00hmov 42h,#00h ;个位显示数据mov 43h,#00h ;十位显示数据mov 44h,#06h ;佰位显示数据mov 45h,#00hmov 46h,#00hmov 4ah,#09hmov 4bh,#09hmov 4ch,#09hmov r5,#00hnca equ 48hsetb p3.0setb p3.1setb p3.2mov sp,#50hmov tmod,#10hmov ie,#88hmov tl1,#37hmov th1,#70hsetb tr1clr p3.7clr ncanopnopdisp:;动态显示mov dptr,#tabclr p3.4clr p3.3mov a,42hanl p1,#01horl p1,ajb nca,xsz1setb p3.5lcall ms10acall keyclr p3.5clr p3.3mov a,43hmovc a,@a+dptranl p1,#01horl p1,ajb nca,xsz2setb p3.4lcall ms10acall keyclr p3.5clr p3.4mov a,44hmovc a,@a+dptranl p1,#01horl p1,ajb nca,xsz3setb p3.3lcall ms10ajmp dispnopnopajmp dispxsz1: cjne r5,#01h,xsz2 xsa: clr p3.4clr p3.3mov a,42hmovc a,@a+dptranl p1,#01horl p1,asetb p3.5acall ms10acall keyxsz2: cjne r5,#02h,xsz3 xsb: clr p3.5clr p3.3mov a,43hanl p1,#01horl p1,asetb p3.4acall ms10acall keyxsz3: cjne r5,#03h,disp xsc: clr p3.5clr p3.4mov a,44hmovc a,@a+dptranl p1,#01horl p1,asetb p3.3acall ms10acall keyajmp dispnopnopajmp disp dszd:;定时计数中断子程序clr tr1setb rs0push pswpush accmov tl1,#37hmov th1,#70hsetb tr1inc 40hmov r0,40hcjne r0,#8,timmov 40h,#00hcpl p1.0jb p3.2,zf0inc 46hmov r6,46hcjne r6,#30h,t11cpl p3.7mov 46h,#00hajmp t11zf0: clr p3.7t11: inc 41hmov r0,41hcjne r0,#60,timmov 41h,#00hmov r0,42hcjne r0,#00,tiaajmp tibtia: dec 42hajmp timtib: mov r1,43hcjne r1,#00,ticajmp tidtic: dec 43hmov 42h,#09hajmp timtid: mov r2,44hcjne r2,#00,tiemov p1,#0ffhsetb p3.7clr p1.0clr tr1mov 46h,#00hmov 42h,#0ahmov 43h,#0ahmov 44h,#0ah ajmp timtie: dec 44hmov 43h,#09hmov 42h,#09h tim: pop accpop pswretinopnopretikey:;-按键扫描处理nopnopacall ms10k0: jb p3.1,k1acall ms10acall ms10acall ms10acall ms10jnb p3.1,szljmp k1nopnopljmp k1sz: jnb p3.1,$acall ms10acall ms10setb ncasetb p3.7inc 45hmov r5,45hk1: cjne r5,#01h,k2mov 46h,#00hmov ie,#00hjb p3.0,fhacall ms10acall ms10jnb p3.0,ct1k2: cjne r5,#02h,k3mov 46h,#00hmov ie,#00hjb p3.0,fhacall ms10acall ms10jnb p3.0,ct2k3: cjne r5,#03h,k4mov 46h,#00hmov ie,#00hjb p3.0,fhacall ms10acall ms10jnb p3.0,ct3k4: cjne r5,#04h,fhmov r5,#00hljmp qdnopnopljmp qdfh: retnopnopretct1:;个位定时减jnb p3.0,$mov r4,4ahdec 4ahcjne r4,#00h,ct1amov 4ah,#09hct1a: m ov 42h,4ahret;nopnopretct2:;十位定时减jnb p3.0,$mov r4,4bhdec 4bhcjne r4,#00h,ct2amov 4bh,#09hct2a: m ov 43h,4bhretnopnopretct3:;佰位定时减jnb p3.0,$mov r4,4chdec 4chcjne r4,#00h,ct3amov 4ch,#09hct3a: m ov 44h,4chretnopnopretqd: mov 46h,#00h mov 45h,#00hmov 42h,4ahmov 43h,4bhmov 44h,4chmov ie,#88hsetb tr1clr p3.7clr ncaretnopnopretms10:;- 延时毫秒mov r0,#100ms: nopdjnz r0,msretnopnoprettab: db 80h,0f2h,48h,60h,32h,24hdb 04h,0f0h,00h,20h,7ehendkg bit B.1 ;用来判断开机等待t bit B.2 ;用来判断正反转,t=1正转,t=0反转w bit B.3 ;用来辅助正反转判断,选择了就为1,不选则为0KK1 BIT B.4 ;用来辅助加速按键,使其不用延时可以按一次速度指甲一档KK2 BIT B.5 ;同上cctv bit b.7 ;用来辅助中断显示程序计时org 0000hlJMP MAINORG 000BHLJMP CTC0ORG 0034hGraphemic:DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,88H,83H,0C6H,0A1H ,86H,84H,0FFH;共阳0~9字型码;PN1 EQU 30H ;PN1用来记脉冲的低二位数;PN2 EQU 31H ;PN2用来记脉冲的高二位数PN3 EQU 32H ;PN3用来做延时程序PN4 EQU 33H ;PN4用来做延时程序ORG 100HMAIN:MOV R6,#00H ;用R6来辅助显示计时MOV B, #00HCLR KGCLR WMOV TMOD,#01H ;T1和T0都是方式一计数MOV TL0,#18HMOV TH0,#0E0H;MOV TL1, #0AFH; MOV TH1, #3CHSETB EASETB ET0 ;T0中断允许SETB TR0SETB P3.4; SETB ET1 ;T1中断允许;SETB TR1SETB PT0 ;设置T1T2的中断优先,都设其为高级中断; SETB PT1MOV R1,#5H ;默认开始的时候速度为5档SETB KK1SETB KK2MOV A,#00H ;把PN1,PN2都清零;MOV PN1,A; MOV PN2,AMOV DPTR,#GraphemicANL P1,#0FH;ANL P0,#00Hmainline:jb p2.2,ks ;关机等待clr wclr kgsetb p1.0setb p1.1clr p1.2clr p1.3ks: jnb kg,wait ;是否开机?开了就往下执行,不开就跳到开机等待ANL P1,#00011111B ;显示最后一位为1,即是可以工作了的意思SETB P1.4MOV A,#1HMOVC A,@A+DPTRMOV P0,ASETB P3.6NOPNOPCLR P3.6LCALL DELAYSPD2:JB P2.1,KEY1CLR KK1KEY1: JNB P2.1,KEY2 ;当p2.1高电平时就往下执行,但是只要执行一次后,kk就为1,往后就不再执行JB KK1, KEY2INC R1SETB KK1 ;这段的任务是不用延时也能消除按键抖动的程序KEY2: JB P2.4,KEY3CLR KK2KEY3: JNB P2.4,posJB KK2, posSETB KK2DEC R1pos: jb p2.0,rev ;正转按钮setb tsetb wrev: jb p2.3,tt ;反转按钮clr tsetb wtt: jnb w,pos ;选择正反转了吗,选了电机就开始转了,不选电机就不转,等待正反转按钮jb t,positivejnb t,reversepositive: ;电机正转setb p1.0clr p1.1clr p1.2setb p1.3lcall BIJIAO0 ;PWM调制; lcall ShowSpeed ;显示速度程序LCALL showdigit1Ljmp mainlinereverse: ;电机反转clr p1.0setb p1.1setb p1.2clr p1.3lcall BIJIAO0 ;PWM调制; lcall ShowSpeed ;显示速度程序LCALL showdigit2Ljmp mainlinewait: mov a,#00h ;如果不开始,那么程序就在这里等待, mov p0,await1: setb p0.6setb p0.7anl p1,#0fhsetb p1.4setb p1.5setb p1.6setb p1.7SETB P3.6NOPCLR P3.6lcall delayjb p2.5,wait1 ;开机等待setb kgLjmp mainlineshowdigit1:ANL P1,#10001111B ;显示12在首位SETB P1.7MOV A,#1HMOVC A,@A+DPTRMOV P0,ASETB P3.6NOPNOPCLR P3.6LCALL DELAYANL P1,#01001111BSETB P1.6MOV A,#2HMOVC A,@A+DPTRMOV P0,ASETB P3.6NOPNOPCLR P3.6LCALL DELAYRETshowdigit2:ANL P1,#10001111B ;显示21在首位 SETB P1.7MOV A,#2HMOVC A,@A+DPTRMOV P0,ASETB P3.6NOPNOPCLR P3.6LCALL DELAYANL P1,#01001111BSETB P1.6MOV A,#1HMOVC A,@A+DPTRMOV P0,ASETB P3.6NOPNOPCLR P3.6LCALL DELAYRETBIJIAO0: MOV A,R1SUBB A,#0H JZ JJ0BIJIAO1: MOV A,R1SUBB A,#1H JZ JJ1BIJIAO2: MOV A,R1SUBB A,#2H JZ JJ2BIJIAO3: MOV A,R1SUBB A,#3H JZ JJ3BIJIAO4: MOV A,R1SUBB A,#4H JZ JJ4BIJIAO5: MOV A,R1SUBB A,#5H JZ JJ5BIJIAO6: MOV A,R1SUBB A,#6HJZ JJ6BIJIAO7: MOV A,R1SUBB A,#7HJZ JJ7BIJIAO8: MOV A,R1SUBB A,#8HJZ JJ8BIJIAO9: MOV A,R1SUBB A,#9HJZ JJ9BIJIAO10:MOV A,R1SUBB A,#0AHJZ JJ10MOV A,R1 ;如果R1的值小于零,则速度和pwm0的速度不变。
摘要本设计讨论了镍镉、镍氢电池的充电问题,以此为基础设计了一个快速充电器。
论文中首先介绍了镍镉、镍氢电池各自的特点以及它们的充电特性,研究了几种常用的充电方法和充电终止控制方法,分析了这几种方法各自的优缺点。
基于以上分析,本设计采用了一种较好的充电终止控制方法——电压负增量控制方法,以AT89C2051单片机为核心设计了一个智能快速充电器。
该充电器主要利用模数转换,将电池电压这一模拟量转换为单片机定时器中的数字量,经过数字量的运算、比较,对电池的工作状态进行判断,并相应地采取不同的充电方法。
其中快速充电过程采用了大电流脉冲充放电的方法,消除了电池极化反应这一现象,充电过程中检测电路检测到电池出现负压后,快速充电终止。
关键词:电压负增量;快速充电;模数转换AbstractThe reference design discusses the issue of charge for NiCd/NiMH batteries; on this basis a quick charger is designed. The characteristic and charge feature of them are introduced, some kind of charging method and stop-charge controlling method are particularly investigated,The advantages and disadvantages of them are analyzed. Based on the analysis above, a kind of well controlling method is adopted (-ΔV) and an intelligent quick charger based on AT89C2051 single-chip microcomputer designed. This charger uses the A/D conversion, changing analogical quantity of batteries voltage into digital quantity of timer in single-chip microcomputer. After operating and comparing of this digital quantity, it judges the state of batteries, accordingly adopts different charge method. To eliminate the effect of polarization, it uses large current pulse to conduct charging and discharging. Quick charge stops after negative voltage appearing during the process of charge.Key words:Negative voltage increment;Quick charge;A/D conversion前言最近几年以来,数码技术的发展使人们对能源的要求越来越高,作为能源市场上的佼佼者,性价比高的镍镉镍氢电池可满足很多方面的需求,得到了众人的青睐,各种镍镉镍氢电池的充电器也得到了很大发展。
第1章绪论随着人们生活水平的不断提高,单片机控制无疑是人们追求的目标之一。
由于单片机适用与机,电,仪一体化的智能产品,它具有精度高,低功耗,控制功能强,小巧等优点。
把它用到仪器仪表上,可使产品的体积缩小,功能增强,实现不同程度的智能化。
因而受到人们高度重视,并取得了一系列科研成果,成为传统工业技术改造和新产品更新换代的理想机种,更有广阔的发展前景。
数字电容表就是单片机应用的一个实例,在实际应用中给人民带来了极大的便利。
测量电容器充电达到该电压的时间,便能知道充电器的容量。
现在国内市场上上海,广东等电子科技发达地区比较火爆,而在国际上则是日本,美国,德国的产品处于领先地位。
近年来随着国内电子事业的飞速发展,广东,台湾等地的产品已经赶上或是接近了国际先进水平,其精确度,稳定性,以及多功能的设计得到了人们的认可,被越来越多的工作者所接受。
本文介绍了一种对电容器进行数字测量的设计方案,数字电容表采用AT89C2051单片机做编程控制器,实现对电容器的测量。
此仪器是一种性能价格比高的具有结构简单,精度高的智能仪表。
其量程范围采用3位半数字显示,最大显示值为1999,读数单位统一采用毫微法(nf),量程分四挡,实际电容值为读书乘以相应的倍数;测量误差各挡误差均小于0.5%;显示方式为4位LED显示,并具有超量程显示功能。
第2章系统组成框图由图一可知,本电容表的硬件电路由AT89C2051单片机、复位电路、时钟振荡电路、电源滤波电路、键盘扫描电路、数码管显示电路、测试电路以及电源电路组成。
其中89C2051单片机是中央计算处理器,它内中ROM烧录了程序,它统一调度和管理所有接口电路工作。
复位电路是为单片机提供复位信号而设计的。
时钟振荡电路是为单片机提供时钟振荡信号而设计的。
电源滤波电路是为系统抗高频或低频干扰而设计的。
键盘扫描电路是为扫描人机键盘接口而设计的。
数码管显示电路是为显示测量结果而设计的。
测试电路是为测试电容冲充电且电容充电过程中与基准电压比较而知道电容充电完毕而设计的。
A T89C2051中文资料电子驿站http:// E-mail: support@AT89C2051是美国ATMEL公司生产的低电压,高性能CMOS 8位单片机,片内含2k bytes的可反复擦写的只读程序存储器(PEROM)和128 bytes的随机存取数据存储器(RAM),器件采用ATMEL公司的高密度、非易失性存储技术生产,兼容标准MCS-5l指令系统,片内置通用8位中央处理器和Flash存储单元,功能强大。
AT89C2051单片机可为您提供许多高性价比的应用场合。
·与MCS-51产品指令系统完全兼容·2k字节可重擦写闪速存储器·1000次擦写周期·2.7V-6V的工作电压范围·全静态操作:0Hz-24MHz·两级加密程序存储器·128×8字节内部RAM·15个可编程I/O口线·2个l6位定时/计数器·6个中断源·可编程串行UART通道AT89C2051 ·可直接驱动LED的输出端口·内置一个模拟比较器·低功耗空闲和掉电模式功能特性概述:AT89C2051提供以下标准功能:2k字节Flash闪速存储器,128字节内部RAM,15个I/O口线,两个16位定时/计数器,—个5向量两级中断结构,一个全双工串行通信口,内置—个精密比较器,片内振荡器及时钟电路。
同时,AT89C2051可降至0HZ的静态逻辑操作,并支持两种软件可选的节电工作模式。
空闲方式停止CPU的工作,但允许RAM,定时/计数器,串行通信口及中断系统继续工作。
掉电方式保存RAM中的内容,但振荡器停止工作并禁止其它所有部件工作直到下一个硬件复位。
方框图引脚功能说明·Vcc:电源电压·GND:地·P1口:P1口是一组8位双向I/O口,P1.2-P1.7提供内部上拉电阻,P1.0和P1.1内部无上拉电阻,主要是考虑它们分别是内部精密比较器的同相输入端(AIN0)和反相输入端(AIN1),如果需要应在外部接上拉电阻。
AT89C2051是精简版的51单片机,精简掉了P0口和P2口,只有20引脚,但其内部集成了一个很实用的模拟比较器,特别适合开发精简的51应用系统,毕竟很多时候我们开发简单的产品时用不了全部32个I/O 口,用AT89C2051更合适,芯片体积更小,而且AT89C2051的工作电压最低为2.7V,因此可以用来开发两节5号电池供电的便携式产品。
本文以ATMEL公司生产的51系列家族的AT89S51和AT89C2051两种单片机来讲解,两种单片机是目前最常用的单片机,其中AT89S51为标准51单片机,当然其功能比早期的51单片机更强大,支持ISP 在系统编程技术,内置硬件看门狗。
一、AT89S51单片机引脚介绍AT89S51有PDIP、PLCC、TQFP三种封装方式,其中最常见的就是采用40Pin封装的双列直接PDIP封装,外形结构下图。
芯片共有40个引脚,引脚的排列顺序为从靠芯片的缺口(见图)左边那列引脚逆时针数起,依次为1、2、3、4。
40,其中芯片的1脚顶上有个凹点(见右图)。
在单片机的40个引脚中,电源引脚2根,外接晶体振荡器引脚2根,控制引脚4根以及4组8位可编程I/O引脚32根。
1、主电源引脚(2根)VCC(Pin40):电源输入,接+5V电源GND(Pin20):接地线2、外接晶振引脚(2根)XTAL1(Pin19):片内振荡电路的输入端XTAL2(Pin20):片内振荡电路的输出端3、控制引脚(4根)RST/VPP(Pin9):复位引脚,引脚上出现2个机器周期的高电平将使单片机复位。
ALE/PROG(Pin30):地址锁存允许信号PSEN(Pin29):外部存储器读选通信号EA/VPP(Pin31):程序存储器的内外部选通,接低电平从外部程序存储器读指令,如果接高电平则从内部程序存储器读指令。
4、可编程输入/输出引脚(32根)AT89S51单片机有4组8位的可编程I/O口,分别位P0、P1、P2、P3口,每个口有8位(8根引脚),共32根。
目录摘要 (1)一、前言 (1)1.1课题背景及意义 (5)二、总体方案论证 (5)2.1方案的比较与选择 (5)2.2系统主要模块的概述 (6)2.2.1 AT89C51单片机性能 (7)2.2.2 DAC0832数模转换器 (9)2.2.3 四运算放大器LM324 (10)2.2.4 LCD显示电路 (11)2.2.5 键盘电路 (12)三、硬件电路设计 (13)3.1单片机控制模块的设计 (13)3.2单片机时钟电路的设计 (14)3.3单片机复位电路的设计 (15)3.4键盘模块的设计 (16)3.5显示模块的设计 (17)3.6数模转换模块的设计 (20)3.7电压比较输出模块的设计 (20)四、软件设计 (22)4.1 软真开发平台Proteus仿真 (22)4.2 软件程序开发平台KEIL (23)4.3 主程序设计 (23)4.4 子程序设计 (25)4.4.1 液晶显示(读写数据)的设计 (25)4.4.2 D/A转换的设计 (26)4.4.3 键盘的设计 (26)五、系统测试与误差分析 (27)5.1 系统测试结果分析 (27)题目:基于单片机AT89C51的数字稳压电源摘要:本文所设计的基于单片机控制的直流稳压电源就是能用数字来控制电源输出电压的大小,而且能使输出的直流电压能保持稳定、精确的直流电压源。
本设计采用了AT89C51单片机、DAC0832、四运算放大器LM324、独立键盘和液晶显示LCD1602来实现整体电路功能。
主要是对AT89C51单片机的各个I/O口的充分利用。
P0口连接液晶显示电路,P1口连接独立键盘电路,P2口直接连接DAC0832芯片输出电压,最终的电压通过带有真差动输入的四运算放大器。
这种设计总体上能充分利用单片机各个接口而不必添加额外芯片,大大减少成本和电路板面积,除此之外,此设计还打破了传统的电阻式的可调稳压直流电源的局限,以此能够在众多的电子设备中广泛应用。
用AT89C2051做的保护电路(含源码)现在的A T89C2051单片机极其便宜,淘宝上不到2元钱,里面带一个比较器,因此利用它来做保护电路性价比不错。
保护电路实现如下功能:1.直流检测保护电路要检测正负窗口电压,但现在是在单电源下,如果要另外加DC检测,就失去了电路的简洁性,所以设计了如下单电源下的DC检测电路,只需一只单电源的比较器即可。
AT89C2051里面的比较器也是单电源的比较器,其输入电压可以等于地电平,因此用在这里很合适。
当输入电压为0时,两个二极管都不通,比较器负输入端电压为820K/39K分压,大概为0.22V,正输入端为0,因此比较器出0。
正电平检测闸值为二极管导通电压+0.22V,仿真大约是0.75V。
而负电平检测时,此时D1不通,比较器+输入端电压约为0,但-输入端为+0.22V,此时只要输入端电压小于一定程度,D2会导通,会将-输入端的电压拉低,直到为负的电压,此时比较器反转。
仿真大约是-0.55V触发。
2.交流断电检测这里交流检测是检测交流过零脉冲,检测电路由光耦组成,交流电是50Hz,因此光耦每20mS会导通,产生一个中断脉冲,MCU用这个脉冲复位定时器。
一旦在50mS内检测不到交流的脉冲,程序就认为是掉电了,就将继电器断开。
3.延时任何故障排除后,都延时9秒左右时间才将继电器吸合。
4.外接扩充信号控制用于扩展其功能,例如过流保护等等。
5.报警显示在故障状态(交流断电、DC保护、外接信号有效)时,故障灯闪烁在排除了故障后,正常灯会闪烁一段时间,然后才将继电器吸合,并正常灯常亮。
电路图如下:源码如下:#include <A T89X51.h>#define FLASHTIME 6000 //闪烁计时#define DELAYTIME 100000L //延时时间#define H_50mS 22 //看门狗定时时间,时钟14.318M,大约延时50mS,即超过2个50HZ交流周期。
之欧侯瑞魂创作;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; AT89C2051时钟程序 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 定时器T0、T1溢出周期为50MS,T0为秒计数用, T1为调整时闪烁用,; P3.7为调整按钮,P1口为字符输出口,采取共阳显示管。
; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 中断入口程序;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ORG 0000H ;程序执行开始地址LJMP START ;跳到标号START执行ORG 0003H ;外中断0中断程序入口RETI ;外中断0中断返回ORG 000BH ;定时器T0中断程序入口LJMP INTT0 ;跳至INTTO执行ORG 0013H ;外中断1中断程序入口RETI ;外中断1中断返回ORG 001BH ;定时器T1中断程序入口LJMP INTT1 ;跳至INTT1执行ORG 0023H ;串行中断程序入口地址RETI ;串行中断程序返回;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 主程序;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;START: MOV R0,#70H ;清70H-7AH共11个内存单元MOV R7,#0BH ;CLEARDISP: MOV @R0,#00H ;INC R0 ;DJNZ R7,CLEARDISP ;MOV 20H,#00H ;清20H(标记用)MOV 7AH,#0AH ;放入"熄灭符"数据MOV TMOD,#11H ;设T0、T1为16位定时器MOV TL0,#0B0H ;50MS定时初值(T0计时用)MOV TH0,#3CH ;50MS定时初值MOV TL1,#0B0H ;50MS定时初值(T1闪烁定时用)MOVTH1,#3CH ;50MS定时初值SETB EA ;总中断开放SETB ET0 ;允许T0中断SETB TR0 ;开启T0定时器MOV R4,#14H ;1秒定时用初值(50MS×20)START1: LCALL DISPLAY ;调用显示子程序SETMM1: LJMP SETMM ;转到时间调整程序SETMM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1秒计时程序;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;T0中断服务程序INTT0: PUSH ACC ;累加器入栈呵护PUSH PSW ;状态字入栈呵护CLR ET0 ;关T0中断允许CLR TR0 ;关闭定时器T0MOV A,#0B7H ;中断响应时间同步修正ADD A,TL0 ;低8位初值修正MOV TL0,A ;重装初值(低8位修正值)MOV A,#3CH ;高8位初值修正ADDC A,TH0 ;MOV TH0,A ;重装初值(高8位修正值)SETB TR0 ;开启定时器T0DJNZ R4, OUTT0 ;20次中断未到中断退出ADDSS: MOV R4,#14H ;20次中断到(1秒)重赋初值MOV R0,#71H ;指向秒计时单元(71H-72H)ACALL ADD1 ;调用加1程序(加1秒操纵)MOV A,R3 ;秒数据放入A(R3为2位十进制数组合)CLR C ;清进位标记CJNE A,#60H,ADDMM ;ADDMM: JC OUTT0 ;小于60秒时中断退出ACALL CLR0 ;大于或等于60秒时对秒计时单元清0MOV R0,#77H ;指向分计时单元(76H-77H)ACALL ADD1 ;分计时单元加1分钟MOV A,R3 ;分数据放入ACLR C ;清进位标记CJNE A,#60H,ADDHH ;ADDHH: JC OUTT0 ;小于60分时中断退出ACALL CLR0 ;大于或等于60分时分计时单元清0MOV R0,#79H ;指向小时计时单元(78H-79H)ACALL ADD1 ;小时计时单元加1小时MOV A,R3 ;时数据放入ACLR C ;清进位标记CJNE A,#24H,HOUR ;HOUR: JC OUTT0 ;小于24小时中断退出ACALL CLR0 ;大于或等于24小时小时计时单元清0OUTT0: MOV 72H,76H ;中断退出时将分、时计时单元数据移MOV 73H,77H ;入对应显示单元MOV 74H,78H ;MOV 75H,79H ;POP PSW ;恢复状态字(出栈)POP ACC ;恢复累加器SETB ET0 ;开放T0中断RETI ;中断返回INTT1: PUSH ACC ;中断现场呵护PUSH PSW ;MOV TL1, #0B0H ;装定时器T1定时初值MOV TH1, #3CH ;DJNZ R2,INTT1OUT ;0.3秒未到退出中断(50MS中断6次)JB 02H,FLASH1 ;02H位为1时显示单元"熄灭"MOV 72H,76H ;02H位为0时正常显示MOV 73H,77H ;MOV 74H,78H ;MOV 75H,79H ;INTT1OUT: POP PSW ;恢复现场POP ACC ;RETI ;中断退出FLASH1: JB 01H,FLASH2 ;01H位为1时,转小时熄灭控制MOV 72H,7AH ;01H位为0时,"熄灭符"数据放入分MOV 73H,7AH ;显示单元(72H-73H),将不显示分数据MOV 74H,78H ;MOV 75H,79H ;AJMP INTT1OUT ;转中断退出FLASH2: MOV 72H,76H ;01H位为1时,"熄灭符"数据放入小时MOV 73H,77H ;显示单元(74H-75H),小时数据将不显示MOV 74H,7AH ;MOV 75H,7AH ;AJMP INTT1OUT ;转中断退出;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 加1子程序;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ADD1: MOV A,@R0 ;取当前计时单元数据到ADEC R0 ;指向前一地址SWAPA ;A中数据高四位与低四位交换ORL A,@R0 ;前一地址中数据放入A中低四位ADD A,#01H ;A加1操纵DA A ;十进制调整MOV R3,A ;移入R3寄存器ANL A,#0FH ;高四位变0MOV @R0,A ;放回前一地址单元MOV A,R3 ;取回R3中暂存数据INC R0 ;指向当前地址单元SWAP A ;A中数据高四位与低四位交换ANL A,#0FH ;高四位变0MOV @R0,A ;数据放入当削地址单元中RET ;子程序返回;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 清零程序 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;对计时单元复零用CLR0: CLR A ;清累加器MOV @R0,A ;清当前地址单元DEC R0 ;指向前一地址MOV @R0,A ;前一地址单元清0RET ;子程序返回;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 时钟调整程序 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;当调时按键按下时进入此程序SETMM: cLR ET0 ;关定时器T0中断CLR TR0 ;关闭定时器T0LCALL DL1S ;调用1秒延时程序JB P3.7,CLOSEDIS ;键按下时间小于1秒,关闭显示(省电)MOV R2,#06H ;进入调时状态,赋闪烁定时初值SETB ET1 ;允许T1中断SETB TR1 ;开启定时器T1SET2: JNB P3.7,SET1 ;P3.7口为0(键未释放),等待SETB 00H ;键释放,分调整闪烁标记置1SET4: JB P3.7,SET3 ;等待键按下LCALL ADD1 ;调用加1子程序MOV A,R3 ;取调整单元数据CLRC ;清进位标记CJNE A,#60H,HHH ;调整单元数据与60比较HHH: JC SET4 ;调整单元数据小于60转SET4循环LCALL CLR0 ;调整单元数据大于或等于60时清0CLR C ;清进位标记AJMP SET4 ;跳转到SET4循环CLOSEDIS: SETB ET0 ;省电(LED不显示)状态。
单片机AT89C2051中文资料(1)2007-04-05 09:52AT89C205189C2051是由ATMEL 公司推出的一种小型单片机。
95年出现在中国市场。
其 主要特点为采用Flash 存贮器技术,降低了制造成本,其软件、硬件与 MCS-51 完全兼容,可以很快被中国广大用户接受,其程序的电可擦写特性,使得开发 与试验比较容易。
1引脚89C2051共有20条引脚,详见图1.从图中可见,2051继承了 8031最重要引脚:rill ®tS06H1W>iP1 口共8脚,准双向端口。
P3.0〜P3.6共7脚,准双向端口,并且保留了全部的 P3的第二功能,如P3.0、 P3..1的串行通讯功能,P3.2、P3..3的中断输入功能,P3.4、P3.5的定时器输入功 能。
在引脚的驱动能力上面,89C2051具有很强的下拉能力,P1,P3 口的下拉能力均 可达到20mA.相比之下,89C51/87C51的端口下拉能力每脚最大为 15mA 。
但是 限定9脚电流之和小于71mA.这样,引脚的平均电流只 9mA 。
89C2051驱动能 力的增强,使得它可以直接驱动 LED 数码管。
为了增加对模拟量的输入功能,2051在内部构造了一个模拟信号比较器,其输 入端连到P1.0和P1.1 口,比较结果存入 P3.6对应寄存器,(P3.6在2051外部 无引脚),原理见图2。
对于一些不大复杂的控制电路我们就可以增加少量元件来实现,例如,对温度 的控制,过压的控制等。
图3为测量示意图。
其中,R 用于测量门限的调节,IN 端接输入模拟信号。
2电源89C2051有很宽的工作电源电压,可为2.7〜6V,当工作在3V 时,电流相当于6V 工作时的1/4。
89C2051工作于12Hz 时,动态电流为 5.5mA ,空闲态为1mA, 掉电态仅为20nA 。
这样小的功耗很适合于电池供电的小型控制系统。
3存储器89C2051片内含有2k 字节的Flash 程序存储器,128字节的片内RAM,与80C31 内部完全类似。
采用AT89C2051制作的智能时钟一、智能电子钟的功能1、全日历计时。
2、12/24小时转换。
3、8路定时输出(可关/开控制)4、误差:15S+1uS5、大、小月,润年,周,自动追踪二、调校上电后,电子钟显示“1:00”。
1、8路定时时间查询按下K1键依此显示8路定时时间。
星期位显示:“H”表示:打开当前定时输出;“L” 表示:关闭当前定时输出。
此时按K2键可进行“H”、“L”的切换。
所有输出,均由蜂鸣器输出!2、显示状态的控制按下K2键可进入以下工作状态:1)12小时/ 日月交替显示。
2)12小时固定显示。
3)24小时/ 日月交替显示。
4)24小时固定显示。
3、校时按下K2键3S后,进入校时菜单。
按下K1键依次进入校时状态:分、时、天、月、年、微调系数。
此时按K2键,完成+1。
当显示“d”时,表示要调整微调系数(0-99),其值越小,时钟走时越慢。
当使用的6MHz的晶振偏差大时,应仔细调整微调系数!当显示“out”时,按K2键,即可退出!退出后,按任意键即可启动时钟。
4、设置定时时间按下K1键3S后,进入设置菜单。
按下K1键依次进入8路定时调整状态:时、分。
此时按K2键,完成+1。
当显示“out”时,按K2键,即可退出!三、原理图和PCB图下一页AT89C2051的智能时钟单片机源程序以下为AT89C2051的智能时钟的内部程序;2001.5.24;***************;all_clk1 _program 2000-10-12;***************fl_250ms bit 00hfl_500ms bit fl_250ms+1set_clk_f bit fl_500ms+1set_al4_f bit set_clk_f+1am_f bit set_al4_f+1fl_3s bit am_f+1al1_f bit fl_3s+1al2_f bit fl_3s+2al4_f bit fl_3s+4set_over bit al4_f+1ha_f bit set_over+1ha_over bit ha_f+1fl_ms_f bit ha_over+1fl_s_f bit fl_ms_f+1key_over bit fl_s_f+1;************************************************** key_data equ 08htimers equ key_data+1t_30ms equ timers+1t_20ms equ t_30ms+1t_1s equ t_20ms+1k1_data equ t_1s+1k2_data equ k1_data+1stat_work equ k2_data+1stat_led equ stat_work+1t_1ms equ stat_led+1t_20m equ t_1ms+1beep equ t_20mal1 equ beep+1al2 equ beep+2al3 equ beep+3al4 equ beep+4al5 equ beep+5al6 equ beep+6al7 equ beep+7al8 equ beep+8ret_timer equ al8+1;************************************************** sec equ 23hmin equ sec+1hhour equ min+1hday equ hour+1hmon equ day+1hyear equ mon+1hw_adj equ year+1hweek equ w_adj+1h;***************************************al1_h equ week+1hal1_m equ al1_h+1hal2_h equ al1_m+1hal2_m equ al2_h+1hal3_m equ al3_h+1hal4_h equ al3_m+1hal4_m equ al4_h+1hal5_h equ al4_m+1hal5_m equ al5_h+1hal6_h equ al5_m+1hal6_m equ al6_h+1hal7_h equ al6_m+1hal7_m equ al7_h+1hal8_h equ al7_m+1hal8_m equ al8_h+1hbeep_t equ al8_m+1frist equ beep_t+1;**************************************led1 equ frist+1led2 equ led1+1led3 equ led2+1led4 equ led3+1led5 equ led4+1sp_data equ led5+1;**************************************led_1 bit p3.5led_2 bit p3.4led_3 bit p3.3led_4 bit p3.2led_5 bit p3.1beep_f BIT P3.7key_f bit p3.0;******************************************************** t_h_100ms equ 05dh ;100 ms for 6MHzt_l_100ms equ 07fh ;c6 for 100mstimer_no equ 8d ;3c90+30d=3cb0hw_adj_dat equ 50dkey_da equ 00000110b;********************************************************* blk_led equ 20ddot_led equ 21df_led equ 22dn_led equ 23du_led equ 24dt_led equ 25db_led equ 26dd_led equ 27doRG 0000H; ;sJMP startORG 0003H; ;reti;ORG 000BH ;;ajmp t0reti ;ORG 0013Hreti ;ORG 001BH ;aJMP T1 ;ORG 0023H ;RETI; AJMP RS_485 ;;************************************** start:call clr_ramMOV SP,#sp_data ;call int_t0call timer_intcall timer_20msSTAR_BI:call clockcall week_autocall al_outCALL KEY_bordcall key_delcall set_clk_alcall key_jmpcall rebackcall led_jmpsjmp star_bi;******************************************* reback:mov a,stat_workjz reback_endjb al1_f ,ka1mov ret_timer,secsetb al1_fsjmp reback_endka1:mov a,ret_timeradd a,#05dmov b,#60ddiv abmov a,seccjne a,b,reback_endclr al1_fmov stat_work,#00d reback_end:retkey_jmp:mov a,key_datajz key_jmp_endmov ret_timer,seccjne a,#01d,kk1mov a,stat_workinc a ;k1_keycjne a,#9d,kka1mov a,#00dkka1:mov stat_work ,asjmp key_jmp_endkk1:mov a,stat_work ;k2_key jnz kk2mov a,stat_ledinc acjne a,#05d,kka2mov a,#00dkka2:mov stat_led,asjmp key_jmp_endkk2:acall all1cpl amov @r0,akey_jmp_end:retall1:mov r0,#al1mov a,stat_workdec aadd a,r0mov r0,amov a,@r0retled_jmp:;**********************************;mov stat_work,#01d;mov stat_tw,#01dmov a,stat_workjnz led_al1mov a,stat_ledacall led_t_dmov led1,weeksjmp led_jmp_endled_al1:acall all1mov led1,#f_ledjnz le_t2mov led1,#n_ledle_t2:jb fl_250ms ,le_t4mov led1,#blk_ledle_t4:acall al_ledled_jmp_end:acall ledret;*************************************time_24:mov a,houracall bcd_8mov led2,ajnz tim4mov led2,#blk_ledtim4:mov led3,bjb fl_500ms,tim1mov a,badd a,#10dmov led3,atim1:acall led_mintime_12_end:ret;***********************************led_min:mov a,minacall bcd_8jb fl_500ms ,tim2add a,#10dtim2:mov led4,amov led5,bret;*************************************date_led:mov a,monacall bcd_8mov led2,ajnz da1mov led2,#blk_ledda1:mov a,badd a,#10dmov led3,amov a,dayacall bcd_8mov led4,ajnz da2mov led4,#blk_ledda2:mov led5,bdate_led_end:ret;*************; D_8=>BCD;*************BCD_8:MOV B,#10DDIV ABRET;**************************************** LED:mov p1,#0mov dptr,#led_asc;***************************led1 mov a,led1movc a,@a+dptrmov p1,aclr led_1acall timer_1msacall timer_1ms;acall timer_1ms;acall timer_1ms;acall timer_1mssetb led_1;*************************led2 led_led2:mov a,led2movc a,@a+dptrmov p1,aclr led_2acall timer_1mssetb led_2;*************************led3 led_led3:mov a,led3movc a,@a+dptrmov p1,aclr led_3acall timer_1mssetb led_3;*************************led4 led_led4:mov a,led4movc a,@a+dptrmov p1,aclr led_4acall timer_1mssetb led_4;*************************led5 led_led5:mov a,led5movc a,@a+dptrmov p1,aclr led_5acall timer_1mssetb led_5;*************************led_end:mov p1,#0ret;************************************ ; bafhcdegled_asc:db 11101110B;0db 10001000B;1db 11000111B;2db 11001101B;3db 10101001B;4db 01101101B;5db 01101111B;6db 11001000B;7db 11101111B;8db 11101101B;9db 11111110B;0. =>10ddb 10011000B;1.db 11010111B;2.db 11011101B;3.db 10111001B;4.db 01111101B;5.db 01111111B;6.db 11011000B;7.db 11111111B;8.db 11111101B;9.DB 00000000B;BLACK=>20dDB 00010000B;dot=>21dDB 00100110b;l=>22ddB 10101011B;h=>23dDB 10101110B;u=>24dDB 00100111B;t=>25ddB 00101111B;b=>26ddB 10001111B;d=>27d; bafhcdeg;********************************** ;delay;******************************** timer_1ms:mov t_1ms,#030hr2_1:djnz t_1ms , r2_1rettimer_20ms:mov t_20m,#050dr2_2:call clockcall leddjnz t_20m , r2_2call week_autocall al_outret;############################################# ;if mon<=2 and year=4Z(0,1,2,3...);gs1=>week=mod([5/4]*year+mon_asc(mon)+day-1)/7 ;else; gs2=>week=mod([5/4]*year+mon_asc(mon)+day)/7 week_auto:mov a,YEARmov b,#05mul abmov r4,bmov r5,amov r7,#04call mul_2MOV DPTR,#MON_ASCMOV A,MONdec aMOVC A,@A+DPTRADD A,r3;*********************MOV B,DAYADD A,Bmov r3,a;r3=gs2;*******jb mon<=2 ******MOV A,MONCJNE A,#02D,WEEK_1SJMP WEEK_2WEEK_1:JC WEEK_2week_3:mov b,#07div abmov a,bsjmp week_4WEEK_2:;*****jb year=4N ******mov a,yearmov b,#04div abmov a,bjnz week_3mov a,r3dec amov b,#07div abmov a,bweek_4:MOV WEEK,ajnz week_endmov week,#07hweek_end:RETMON_ASC:DB 6d, 2d, 2d, 5d, 0d, 3d, 5d, 1d, 4d, 6d, 2d, 4d ;2002.5.5 ;r4r5/r7=r3mul_2:D457: CLR CMOV A,R4SUBB A,R7JC DV50SETB OVRETDV50: MOV R6,#8 ;;求平均值(R4R5/R7-→R3)DV51: MOV A,R5RLC AMOV R5,AMOV A,R4RLC AMOV R4,AMOV F0,CCLR CSUBB A,R7ANL C,/F0MOV R4,ADV52: CPL CMOV A,R3RLC AMOV R3,ADJNZ R6,DV51MOV A,R4 ;;四舍五入ADD A,#0;R4JC DV53SUBB A,R7JC DV54DV53: INC R3DV54: CLR OVRET;************************************************************* clr_ram:MOV R7,#78h ;MOV R0,#0bH ;CLR A ;CR: INC R0 ;MOV @R0,A ;djnz r7,cr ;CLR RAMret;************** INT_CTRLint_t0:setb et1MOV TMOD,#00010001b ;mov w_adj,#w_adj_datsetb eajmp adj_w;**********************************************al_led:mov r0,#al1_hmov a,stat_workdec arl aadd a,r0mov r0,amov a,@r0acall bcd_8mov led2,ajnz al_1mov led2,#blk_ledmov a,badd a,#10dmov led3,ainc r0mov a,@r0acall bcd_8add a,#10dmov led4,amov led5,bal_led_end:ret;******************************** set_clk_al:jnb set_clk_f,see1call set_clockclr set_clk_fsjmp see2see1:jnb set_al4_f,see2call set_al4clr set_al4_fsee2:ret;********************************* proc led_t_dled_t_d:mov dptr,#led_ord_3mov b,#02hmul abjmp @a+dptrled_ord_3: ajmp led_k0_2ajmp led_k1_2ajmp led_k2_2ajmp led_k3_2ajmp led_k4_2led_k0_2: ; timer_12 and date to led acall time_12jnb fl_3s ,lk1acall date_ledlk1:ajmp led_jmp_5_endled_k1_2: ; timer_12 to ledacall time_12ajmp led_jmp_5_endled_k2_2: ;timer_24and date to ledacall time_24jnb fl_3s ,lk2acall date_ledlk2:ajmp led_jmp_5_endled_k3_2: ;timer_24to ledacall time_24ajmp led_jmp_5_endled_k4_2: ;sec to ledmov led1,#blk_ledmov led2,#blk_ledmov led3,#dot_ledmov a,secacall bcd_8add a,#10dmov led4,amov led5,bled_jmp_5_end:retend;**************************************** proc set_al4set_al4:mov k1_data,#01dmov k2_data,#01dclr set_overacall led_alacall key_bordcall sf_keymov key_data,#0mov frist,#0set_al41:call clockcall week_autoacall led_alacall key_bordcall key_delacall key_aljnb set_over,set_al41clr amov k1_data,amov k2_data,amov key_data,amov frist,aretend;************************************** proc key_alkey_al:mov a,key_datajz key_al_endcjne a,#01d,k2_alinc k1_data ;(1-9)mov a,k1_datacjne a,#19d,key_al_endmov k1_data,#01dsjmp key_al_endk2_al:mov a,k1_datacjne a,#018d,ke2setb set_oversjmp key_al_endke2:mov r0,#al1_hdec aadd a,r0mov r0,ainc @r0acall jj_bitmov b,#24djnz ke3mov b,#60dke3:mov a,@r0div abmov a,bmov @r0,akey_al_end:retendjj_bit:mov a,k1_datamov b,#02ddiv abmov a,b ;(a=1,0)ret;********************************* led_out1:mov led2,#00hmov led3,#u_ledmov led4,#t_ledmov led5,#blk_ledmov led1,#blk_ledret;******************************** led_al:mov a,k1_datacjne a,#017d,lo1acall beep_timersjmp led_al_endlo1:cjne a,#18d,ld1acall led_out1sjmp led_al_endld1:inc amov b,#02ddiv ab;**********mov led1,a;**********dec arl amov r0,#al1_hadd a,r0mov r0,amov a,@r0acall bcd_8mov led2,ajnz ld2mov led2,#blk_ledld2:mov a,badd a,#10dmov led3,a;************************************ inc r0mov a,@r0acall bcd_8add a,#10dmov led4,amov led5,b;***************************flash bitjb fl_250ms,led_al_endacall jj_bitjnz led_al_emov led4,#blk_ledmov led5,#blk_ledsjmp led_al_endled_al_e:mov led2,#blk_ledmov led3,#blk_ledled_al_end:acall ledret;*************************************** proc set_clockset_clock:mov k1_data,#01dmov k2_data,#01dclr set_overcall led_clcall key_bordcall sf_keymov key_data,#0mov frist,#0set_al41:call clockacall week_autocall al_outacall led_clacall key_bordcall key_delacall key_cljnb set_over,set_al41;acall key_bordmov k1_data,amov k2_data,amov key_data,amov frist,aretend;************************************** proc key_clkey_cl:mov a,key_datajz key_al_endcjne a,#01d,k2_alinc k1_data ;(1-8)mov a,k1_datacjne a,#9d,key_al_endmov k1_data,#01dsjmp key_al_endk2_al:mov a,k1_datacjne a,#08d,ke2setb set_oversjmp key_al_endke2:dec amov dptr,#asc_hmovc a,@a+dptrmov b,a;********************************mov r0,#secmov a,k1_datadec aadd a,r0mov r0,ainc @r0mov a,@r0div abmov a,bmov @r0,akey_al_end:retenddb 60d,60d,24d,32d,13d,100d,100dproc led_clled_cl:mov dptr,#led_ord_3mov a,k1_datadec amov b,#02hmul abjmp @a+dptrled_ord_3: ajmp led_k0_2ajmp led_k1_2ajmp led_k2_2ajmp led_k3_2ajmp led_k4_2ajmp led_k5_2ajmp led_k6_2ajmp led_k7_2led_k0_2: ; led secmov led2,#blk_ledmov led3,#dot_ledmov a,secacall bcd_8add a,#10dmov led4,amov led5,bjb fl_250ms ,lk1mov led4,#blk_ledmov led5,#blk_ledlk1:ajmp led_jmp_5_endled_k1_2: ; led min,houracall led_hourjb fl_250ms ,lk2mov led4,#blk_ledmov led5,#blk_ledlk2:ajmp led_jmp_5_endled_k2_2: ;led min,houracall led_hourjb fl_250ms ,lk3mov led2,#blk_ledmov led3,#blk_ledlk3:ajmp led_jmp_5_endled_k3_2: ;led day,mon acall led_monjb fl_250ms ,lk4mov led4,#blk_ledmov led5,#blk_ledlk4:ajmp led_jmp_5_endled_k4_2: ; led day,mon acall led_monjb fl_250ms ,lk5mov led2,#blk_ledmov led3,#blk_ledlk5:ajmp led_jmp_5_endled_k5_2: ; led year mov led2,#2dmov led3,#0dmov a,yearacall bcd_8mov led4,amov led5,bjb fl_250ms ,lk6mov led4,#blk_ledmov led5,#blk_ledlk6:ajmp led_jmp_5_endled_k6_2: ;led w_adj mov led2,#d_ledmov led3,#blk_ledmov a,w_adjacall bcd_8mov led4,amov led5,bjb fl_250ms ,lk7mov led4,#blk_ledmov led5,#blk_ledlk7:ajmp led_jmp_5_endled_k7_2: ;led outacall led_out1led_jmp_5_end:mov led1,weekacall ledretendled_hour:mov a,houracall bcd_8mov led2,ajnz lj1mov led2,#blk_ledlj1:mov a,badd a,#10dmov led3,a;********************* mov a,minacall bcd_8add a,#10dmov led4,amov led5,bretled_mon:mov a,monjnz lj5inc monmov a,monlj5:acall bcd_8mov led2,ajnz lj2mov led2,#blk_ledlj2:mov led3,b;********************* mov a,dayjnz lj4inc daymov a,daylj4:acall bcd_8mov led4,ajnz lj3mov led4,#blk_ledmov led5,bret;********************************************al_out:jb ha_over,al_out_endmov r7,#8dmov r1,#al8_mal_ch_1:mov r0,#minmov r6,#02d ;min houral_l:mov a,@r0mov b,@r1cjne a,b ,al_chinc r0dec r1djnz r6 ,al_l;************************************************** mov a,r7dec amov r0,#al1add a,r0mov r0,amov a,@r0mov c,acc.0cpl canl c,fl_250mscpl cmov beep_f,cacall beep_outal_ch:clr cmov a,r1subb a,r6mov r1,adjnz r7,al_ch_1al_out_end:retbeep_out:jb ha_f,ba1mov beep,secsetb ha_fmov a,beepadd a,beep_tmov b,#60ddiv abmov a,seccjne a,b,beep_out_endsetb beep_fsetb ha_overclr ha_fbeep_out_end:rettimer_int:MOV T_1S,#TIMER_nomov beep_t,#15dmov year ,#01dmov mon , #011dmov day , #06dmov hour ,#13dmov min , #00dmov sec , #00dmov r7,#16mov dptr ,#al_ascmov r0,#al1_hal_read:clr amovc a,@a+dptrmov @r0,ainc r0inc dptrdjnz r7,al_readret;************************************ beep_timer:mov led1,#blk_ledmov led2,#b_ledmov led3,#blk_ledmov a,beep_tacall bcd_8mov led4,amov led5,bjb fl_250ms,ft1mov led4,#blk_ledmov led5,#blk_ledft1:rettime_12:mov dptr,#asc_12mov a,hourrl amovc a,@a+dptrmov led2,ajnz iu2mov led2,#blk_lediu2:inc dptrmov a,hourrl amovc a,@a+dptrjb fl_500ms ,iu1add a,#10diu1:mov led3,a;*************************************** min to ledacall led_mintime_24_end:retasc_12:db 11d,2d,21d,1d,21d,2d,21d,3d,21d,4d,21d,5d,21d,6d,21d,7ddb 21d,8d,21d,9d,11d,0d,11d,1ddb 1d,2d,0d,1d,0d,2d,0d,3d,0d,4d,0d,5d,0d,6d,0d,7d,0d,8d,0d,9d db 1d,0,1d,1dclock:;********************************mov a,seccjne a,#60d,clock_end;!!!!!!!!!!!!!!!!!!!!!!mov sec,#00hinc min;**********clr ha_over ;2001.5.6mov a,mincjne a,#60d,clock_endmov min,#00hmov a,hourcjne a,#24d,clock_endmov hour,#00hmov a,monxrl a,#02djnz mm_1mov dptr,#year_dmov a, yearmovc a,@a+dptrsjmp mm_2mm_1:mov a,mondec amov dptr,#mou_12movc a,@a+dptrmm_2:mov b,ainc binc day ;***************day+1 mov a,daycjne a ,b ,clck_endsjmp clck1clck_end:jc clock_endclck1:mov day,#01hinc monmov a,moncjne a,#13d ,clock_endmov mon,#01dinc yearmov a,yearcjne a,#100d ,clock_endmov year,#00dclock_end:call fl_outretmou_12:db 31d, 28d, 31d, 30d, 31d,30d db 31d, 31d, 30d,31d, 30d,31ddb 29d, 28d, 28d, 28d, 29d, 28d , 28d, 28d, 29d, 28d db 28d, 28d, 29d, 28d, 28d, 28d , 29d, 28d, 28d, 28d db 29d, 28d, 28d, 28d, 29d, 28d , 28d, 28d, 29d, 28d db 28d, 28d, 29d, 28d, 28d, 28d , 29d, 28d, 28d, 28d db 'li jie 2000.5.15';***************************************t1:push apush pswpush bclr fl_ms_fdjnz t_1s ,t1_endclr fl_s_finc seccall adj_w;********************************t1_end:pop bpop pswpop aretiadj_w:clr tr1mov a,#T_L_100msadd a, w_adj ;*******have 5 ordermov tl1 ,amov a,#T_H_100msaddc a, #00hmov th1,amov t_1s,#timer_nosetb tr1retfl_out:jb fl_ms_f ,fl_out_endsetb fl_ms_fmov a,t_1smov b,#02ddiv abmov a,bjnz to_d1cpl fl_250msmov a,t_1smov b,#04ddiv abmov a,bjnz to_d2cpl fl_500msto_d2:fl_out_end:call sec_outretsec_out:jb fl_s_f ,sec_out_endsetb fl_s_fmov a,secmov b,#07djnb fl_3s,za1mov b,#02dza1:div abmov a,bjnz sec_out_endcpl fl_3ssec_out_end:ret;********************************** key_del:mov a,key_datajnz kl_12mov a,fristjnz kl_13retkl_13:mov key_data,fristmov frist,#0clr key_overjmp sf_beepkl_12:jnb key_over,kl11mov a,t_30msadd a,#03mov b,#60ddiv abcjne a,b,key_del_endclr key_overjmp set_keykl11:mov t_30ms,secsetb key_overkey_del_end:call sf_acjne a,#key_da,sfg_12clr key_overjmp sf_beepsfg_12:mov frist,key_datamov key_data,#0ret;**************************************** key_bord:acall re_kmov a,key_datajz key_bord1_end;acall psf_key0key_bord1_end:setb key_fretset_key:mov a,key_datacjne a,#01h,set_cc1setb set_al4_fsjmp sf23set_cc1:cjne a,#02h,sf23setb set_clk_fsf23:ret;************************************sf_key:call clockcall week_autocall al_outsetb key_fcall ledcall sf_acjne a,#key_da,sf_keycall sf_beepretsf_beep:clr beep_fcall timer_20mssetb beep_fret;******************************** re_k:mov key_data,#00hmov p1,#00hmov a,p3orl a,#01111111bmov p3,aclr key_fmov a,p3setb key_fmov p1,#0ffhanl a ,#00000110bcjne a,#00000110b,you_keyre_k_end:retyou_key:call timer_20ms;call ledmov p1,#00hmov a,p3orl a,#01111111bmov p3,aclr key_fmov a,p3setb key_fmov p1,#0ffhanl a ,#key_dacjne a,#key_da,you_key1ret;sjmp re_k_endyou_key1:jb acc.1,key_kbmov key_data,#02hkey_kb:jb acc.2,sf_key0mov key_data,#01hsf_key0:retsf_a:mov p1,#00hmov a,p3orl a,#01111111bmov p3,aclr key_fmov a,p3setb key_fanl a ,#key_daretal_asc:db 06d,40d, 06d,50d, 07d,00d, 07d,10d;am 4_al db 07d,15d, 013d,40d, 13d,45d, 14d,15d;pm 4_al。
基于单片机AT89C2051的无刷直流电动机调速系统作者:吴欣来源:《科学与财富》2017年第20期(凯斯纽荷兰工业(哈尔滨)机械有限公司)摘要:本文介绍了基于AT89C2051的无刷直流电动机控制器的硬件结构,软件设计以及调速方案的具体实现。
本系统采用电流单闭环控制策略,PWM调速方式对无刷直流电机进行控制。
经过验证表明,系统结构简单,性能稳定可靠,调速效果良好。
关键词:AT89C2051;无刷直流电机;PWM;调速1 引言AT89C2051是ATMEL公司生产的高性能CMOS 8位微处理器。
该芯片内含2k bytes的可反复擦写的只读Flash程序存储器和128 bytes的随机存取数据存储器(RAM),器件采用ATMEL公司的高密度、非易失性存储技术生产,兼容标准MCS-51指令系统,片内置通用8位中央处理器和Flash存储单元。
由于该芯片价格便宜,性能稳定,本系统设计的基于单片机AT89C2051的无刷直流电动机调速系统具有实际应用价值。
2 硬件设计2.1 系统的硬件框图本系统采用单闭环(电流环)控制策略。
采样电流与给定通过TL494进行PI调节,输出一定占空比的PWM控制信号,对电机进行调速。
位置传感器检测电机转子的位置,经过信号处理,从而确定下一时刻电机的驱动方式。
系统的硬件框图如图1所示。
2.2 系统的控制、隔离和驱动①控制部分。
本系统的控制对象三相直流无刷电机采用两两导通,360°度为一周期,三相六状态控制方式。
在定子内部每隔120°电角度放置了3片霍尔型位置传感器,位置传感器的输出信号输入到单片机AT89C2051的I/O口P3.2~P3.4,单片机通过捕捉位置传感器任一路输出上的跳变沿,读取跳变沿后的编码器输出状态,就可以确定转子的新位置,实现定子绕组电流换向。
单片机通过软件编程根据检测的位置信号经I/O输出6路PWM控制信号来驱动IGBT。
本例PWM调制方式采用半桥调制,即上桥臂功率开关恒通、下桥臂功率开关通过PWM调制。
随着汽车工业的不断发展,能源危机以及汽车尾气对大气环境造成的污染日趋严重。
而发动机点火时刻的精确控制在提高汽车整体性能的同时,有效地缓解了这一状况。
与传统的机械调节式点火时刻控制系统相比,基于微控制器的电子式控制系统具有及时性好、精确度高、控制灵活等优点。
为此,从发动机点火控制系统的控制策略出发,设计了一种能提高发动机点火控制精度的新型电子点火控制装置。
1 系统工作原理发动机点火时刻是通过控制点火提前角(即点火时活塞位置到上止点曲轴转过的角度)来实现的。
影响火花塞点火时刻的因素主要有发动机转速、负荷大小、发动机冷却水温度以及发动机缸体爆震等。
整个点火系统硬件电路主要由传感器及信号调理电路、A/D转换器、电控单元、点火电路、电源及火花塞等部分组成。
系统原理框图如图1所示。
各传感器的输出信号经相应调理电路调理、A/D转换器转换后,送入单片机。
单片机依据一定的控制策略、算法对输入信号运算处理,依据运算结果,在合适时刻给出控制信号。
控制信号经驱动电路后,控制点火控制电路工作,通过火花塞最终实现发动机点火。
2 系统硬件设计2.1 传感器及其调理电路主要包括转速传感器、水温传感器、爆震传感器和节气门开度传感器及其相应调理电路。
2.1.1 转速传感器及其调理电路采用光电式转速传感器,其作用是测量发动机转速和曲轴转角位置。
传感器输出信号经调理电路整形、放大后号送入单片机外部计数器T0(P3.4)引脚上,由单片机在一定时间内对其计数便可测量其转速和曲轴位置。
2.1.2 水温传感器及其调理电路采用集成温度传感器MAX6611测量发动机冷却水温度。
单片机依据水温信号对点火提前角作相应调整:当水温低时增大点火提前角,而水温高时减小点火提前角。
传感器输出信号经二极管双向限幅和RC滤波电路调理后接到ADC0809的信道0上。
2.1.3 爆震传感器及其调理电路采用安装在发动机缸体上的压电加速度传感器来测量发动机爆震信号,并依据是否发生爆震而对点火提前角作相应调整。
AT89C2051是精简版的51单片机,精简掉了P0口和P2口,只有20引脚,但其内部集成了一个很实用的模拟比较器,特别适合开发精简的51应用系统,毕竟很多时候我们开发简单的产品时用不了全部32个I/O口,用AT89C2051更合适,芯片体积更小,而且AT89C2051的工作电压最低为2.7V,因此可以用来开发两节5号电池供电的便携式产品。
本文以ATMEL公司生产的51系列家族的AT89S51和AT89C2051两种单片机来讲解,两种单片机是目前最常用的单片机,其中AT89S51为标准51单片机,当然其功能比早期的51单片机更强大,支持ISP在系统编程技术,内置硬件看门狗。
一、AT89S51单片机引脚介绍AT89S51有PDIP、PLCC、TQFP三种封装方式,其中最常见的就是采用40Pin封装的双列直接PDIP封装,外形结构下图。
芯片共有40个引脚,引脚的排列顺序为从靠芯片的缺口(见图)左边那列引脚逆时针数起,依次为1、2、3、4。
40,其中芯片的1脚顶上有个凹点(见右图)。
在单片机的40个引脚中,电源引脚2根,外接晶体振荡器引脚2根,控制引脚4根以及4组8位可编程I/O 引脚32根。
1、主电源引脚(2根)VCC(Pin40):电源输入,接+5V电源GND(Pin20):接地线2、外接晶振引脚(2根)XTAL1(Pin19):片内振荡电路的输入端XTAL2(Pin20):片内振荡电路的输出端3、控制引脚(4根)RST/VPP(Pin9):复位引脚,引脚上出现2个机器周期的高电平将使单片机复位。
ALE/PROG(Pin30):地址锁存允许信号PSEN(Pin29):外部存储器读选通信号EA/VPP(Pin31):程序存储器的内外部选通,接低电平从外部程序存储器读指令,如果接高电平则从内部程序存储器读指令。
4、可编程输入/输出引脚(32根)AT89S51单片机有4组8位的可编程I/O口,分别位P0、P1、P2、P3口,每个口有8位(8根引脚),共32根。
采用AT89C2051的数字可调稳压电源单片机源程序
ORG 0000H ;定位
LJMP MAIN ;跳转到MAIN主程序
;
ORG 0003H ;定位
LJMP IT_0 ;转入INT0的中断服务程序
;
ORG 000BH ;定位
LJMP IT_1 ;转入INT0的中断服务程序
;
ORG 0100H ;定位
MAIN: MOV R6,#32H ;将50送R6
ANL P3,#4FH ;将P3.4、P3.5、P3.7置为0,使输出电压为0.0V
MOV P1,#0FFH ;将0FFH送P1
SETB P3.0 ;将P3.0置1
CLR P3.1 ;将P3.1置0
MOV R2,#0CH ;将0CH送R2
LCALL DELAY ;调用DELAY延时子程序
SETB P3.1 ;将P3.1置1
CLR P3.0 ;将P3.0置0
MOV R2,#0CH ;将0CH送R2
LCALL DELAY ;调用DELAY延时子程序
DJNZ R6,MAIN ;若R6-1不等于0,跳转到MAIN
MOV P1,#00H ;将00H送P1
MOV R2,#25H ;延时1S
LCALL DELAY ;调用DELAY延时子程序
SETB EX0 ;开INT0中断
SETB EX1 ;INT1中断
SETB EA ;开CPU中断
SETB IT0 ;将INT0设为负边沿触发
SETB IT1 ;将INT1设为负边沿触发
MOV R7,#00H ;将00H送R7
LOOP: MOV A,R7 ;将R7值送A
MOV DPTR,#TABLE0 ;将TABLE0地址送DPTR
MOVC A,@A+DPTR ;查表,将查到的值送A
ANL P3,A ;将A值与P3值相与,结果送P3
MOV DPTR,#TABLE1 ;将TABLE1地址送DPTR
MOVC A,@A+DPTR ;查表,将查到的值送A
ORL P3,A ;将A值与P3值相或,结果送P3
MOV DPTR,#TABLE2 ;将TABLE2地址送DPTR
MOVC A,@A+DPTR ;查表,将查到的值送A
MOV P1,A ;将A值送P1
SETB P3.0 ;将P3.0置1
CLR P3.1 ;将P3.1置0
MOV R2,#0CH ;将0CH送R2
LCALL DELAY ;调用DELAY延时子程序
MOV DPTR,#TABLE3 ;将TABLE3地址送DPTR
MOVC A,@A+DPTR ;查表,将查到的值送A
MOV P1,A ;将A值送P1
SETB P3.1 ;将P3.1置1
CLR P3.0 ;将P3.0置0
MOV R2,#0CH ;将0CH送R2
LCALL DELAY ;调用DELAY延时子程序
SJMP LOOP ;跳转到LOOP循环
;
ORG 0200H ;定位
IT_0: MOV R2,#14H ;将14H置送R2
LCALL DELAY ;调用DELAY延时子程序(延时约为57ms)
JB P3.2,EXIT0 ;若INT0(P3.2)为1,说明为干扰信号,退出
INC R7 ;若INT0(P3.2)为0,将R7加1
CJNE R7,#07H,EXIT0 ;当R7值不为7时,跳转到EXIT0
MOV R7,#00H ;当R7值为7时,令R7等于0
EXIT0: RETI ;INT0中断返回
;
IT_1: MOV R2,#14H ;将14H置送R2
LCALL DELAY ;调用DELAY延时子程序(延时约为57ms)
JB P3.3,EXIT1 ;若INT1(P3.3)为1,说明为干扰信号,退出
DEC R7 ;若INT0(P3.3)为0,将R7减1
CJNE R7,#0FFH,EXIT1 ;当R7值不为0FFH时,跳转到EXIT1
MOV R7,#06H ;当R7值为0FFH时,令R7等于6
EXIT1: RETI ;INT1中断返回
;
TABLE0:DB 4FH,4FH,4FH,4FH,4FH,4FH,4FH,4FH ;控制信号
TABLE1:DB 00H,10H,20H,30H,80H,90H,0A0H,0B0H ;控制信号
TABLE2:DB 0CFH,0E6H,0EDH,0FDH,0EFH,03H ;第一数码管位显示信号TABLE3:DB 3FH,6DH,3FH,3FH,3FH,5BH ;第二数码管位显示信号
;以下为通用延时子程序
;当R2=0CH时,延时约为10ms;当R2=14H时,延时约为57ms DELAY:PUSH 02H ;将R2中的值推入堆笺
LP1: PUSH 02H ;将R2中的值推入堆笺
LP2: PUSH 02H ;将R2中的值推入堆笺
LP3: DJNZ R2,LP3 ;若R2-1不为0,跳转到LP3 POP 02H ;将堆笺中值弹出到R2中
DJNZ R2,LP2 ;若R2-1不为0,跳转到LP2 POP 02H ;将堆笺中值弹出到R2中
DJNZ R2,LP1 ;若R2-1不为0,跳转到LP1
POP 02H ;将堆笺中值弹出到R2中
DJNZ R2,DELAY ;若R2-1不为0,跳转到DELAY
RET ;子程序返回
END ;结束
主程序MAIN中,从MOV P1,#0FFH到SETB EX0的前一行,其作用是刚开机时,让数码管显示全笔段,然后熄灭,以便于检查数码管的好坏,并做好准备。
在初始化程序中,令IT0和IT1为1,是让INT0和INT1变为负边沿触发,以达到每按一次S1或S2(无论时间长短,当然时间必须超过57ms),输出电压和数码管改变一次。
在LOOP循环中,先对P3相与后相或的目的是要将P3.4,P3.5,P3.7先清零后置位,相当于这一段代码就是一个简单的与或逻辑电路,具体操作情况读者可参照电路图自行分析。
另外,主程序中的R7用于存放预设电压的序号,其值在0~6之间变化,每一个值对应一个电压值,依次为0—0.0V,1—3.0V,2—4.5V,3—5.0V,4—6.0V,5—9.0V,6—12V的电压。
由于经常用的都是这些电压,所以上面几个电压对电子制作者来说已经足够了。
TABLE0中存放控制信号,TABLE1中存放第一个数码管的字显示信号,TABLE2中存放第二个数码管的字显示信号。
当按S1时,输出电压就按照上述电压依次增加;当按S2时,输出电压就依次减少。
若此时电压为0.0V,再按S2就会使输出电压变为12V;反之,若此时电压为12V,再按S1就会使输出电压变为0.0V。