电子时钟 直流发动机控制 万年历.docx
《电子时钟 直流发动机控制 万年历.docx》由会员分享,可在线阅读,更多相关《电子时钟 直流发动机控制 万年历.docx(38页珍藏版)》请在冰豆网上搜索。
![电子时钟 直流发动机控制 万年历.docx](https://file1.bdocx.com/fileroot1/2023-6/28/5dc21cbe-7251-49b9-b92c-ab3fa63fe418/5dc21cbe-7251-49b9-b92c-ab3fa63fe4181.gif)
电子时钟直流发动机控制万年历
单片机研究性学习报告
姓名:
王文玺
学号:
09221018
班级:
机电0901
日期:
2011-05-25
学习目的:
1)熟练掌握已学的单片机知识。
2)锻炼自主学习能力,达到能够按照需求,了解各种元器件功能并运用。
3)掌握Proteus、Keiluvision、VW等仿真软件
4)锻炼团队协作、沟通能力。
课题选择:
1)组队课题:
直流电动机控制模块设计
2)个人课题:
1基于AT89S52的LED数字时钟
2基于DS12887的LCD数字时钟
3基于80C51的跑马灯设计
团队课题:
直流电动机控制模块设计
设计目的
1)掌握串行ADC0831A/D转换器的工作原理与使用方法;
2)掌握利用AT89S52单片机产生占空比可调的PWM波形的方法;
3)了解直流电动机驱动电路的工作原理及设计方法。
4)为大创移动式售货机项目打好基础,通过实践发现、并解决遇到的困难。
设计任务
利用AT89S52单片机对直流电动机进行转速,旋转方向控制。
用以单刀双掷开关控制直流电动机的旋转方向,用电位器通过ADC0831将模拟电压量转换为数字值,作为PWM波形的延时常数,从而控制电动机的转数。
设计原理
直流电动机简介:
它的固定部分有磁铁,称为主磁极;固定部分上(定子)还有电刷。
转动部分有环形铁芯和绕在环形铁芯上的绕组。
在直流电动机固定部分上,装设了一对直流励磁的静止的主磁极N和S,在旋转部分(转子)上装设有电枢铁心。
定子与转子之间有一气隙。
在电枢铁心上放置了两根导体连成的电枢线圈。
线圈的首端和末端分别连到两个圆弧形的铜片上,此铜片称为转向片。
幻想片之间互相绝缘,由换向片构成的整体称为换向器。
换向器固定在转轴上,换向片与转轴之间亦互相绝缘。
在换向片上放置着一对固定不动的电刷,当电枢线圈通过换向片和电刷与外电路接通。
直流电动机工作过程:
对直流电动机,如果去掉原动机,并给两个电刷加上直流电源,这有直流电流从一个电刷,经过线圈,从另一个电刷流出,根据电磁力定律,载流导体受到电磁力作用,其方向可由左手定则判定,两段导体受到的力形成了一个转矩,使得转子逆时针转动。
如果转子转到如图位置,电刷A和换向片2接触,电刷B和换向片1接触,直流电流从电刷A流入,在线圈中的流动方向是dcba,从电刷B流出。
此时载流导体ab和cd受到电磁力的作用方向通样可由左手定则判定,它们产生的转矩仍然使得转子逆时针转动。
这就是直流电动机的工作原理。
外加的电源是直流的,但由于电刷和换向片的作用,在线圈中流过的电流是交流的,其产生的转矩的方向确实不变的。
实用中的直流电动机转子上的绕组也不是由一个线圈构成,同样是由多个线圈连接而成,以减少电动机电磁转矩的波动,绕组形式同发电机。
旋转方向控制
如图所示,当DIR端输入为高电平时,VT4和VT2导通,VT1和VT3关断,此时图中电动机左端为低电平,当PWM端输入低电平时,VT6和VT8关断,VT5和VT7导通,VT5和VT7关断,没有电流通过电动机;当DIR端输入低电平时,VT4和VT2关断,VT3和VT1导通,当PWM端为高电平时,VT8和VT6导通,VT5和VT7关断,电流从VT1流向VT6,电动机反转,若PWM端为低电平,则VT8和VT5,没有电流通过电动机。
单片机的P3.2口接一单刀双掷开关,当开关输入高电平时,单片机的DIR端输出高电平,控制电动机正转;开关输入低电平时,单片机的DIR端输出低电平,控制电动机反转。
电动机转速控制:
如图所示,用一个电位器作为ADC0831的模拟量输入,最大输入电压及参考电均为5V,数字量输出范围为0单片机的P3.2口接一单刀双掷开关SW1,在程序运行时查询开关所选通的电平,从而决定电动机的旋转方向。
ADC0831工作过程
首先,将ADC0831的时钟线拉低,再将片选端置低电平,启动A/D转换。
接下来第一个时钟信号的下降沿到来时,ADC0831的数据输出端被拉低,准备输出转换数据。
从时钟信号的第二个下降沿到来的开始,ADC0831开始输出转换数据,直到第九个下降沿为止,共八位,输出的顺序为从最高位到最低位。
程序流程图:
源程序:
CSBITP2.0
CLKBITP2.4
D0BITP2.5
AD_TMPEQU30H
PWMBITP3.7
SWBITP3.2
DIRBITP3.6
ORG00H
MAIN:
LCALLAD_CONV
SETBSW
JBSW,POS
AJMPNEG
POS:
SETBDIR
SETBPWM
MOVA,AD_TMP
LCALLDELAY
CLRPWM
MOVA,#255
SUBBA,AD_TMP
LCALLDELAY
SJMPMAIN
NEG:
CLRDIR
CLRPWM
MOVA,AD_TMP
LCALLDELAY
SETBPWM
MOVA,#255
SUBBA,AD_TMP
LCALLDELAY
SJMPMAIN
AD_CONV:
SETBCS
CLRCLK
NOP
NOP
CLRCS
NOP
NOP
SETBCLK
NOP
NOP
CLRCLK
NOP
NOP
SETBCLK
NOP
NOP
CLRCLK
NOP
NOP
SETBCLK
NOP
MOVR0,#08H
AD_READ:
CLRCLK
MOVC,D0
RLCA
SETBCLK
NOP
NOP
DJNZR0,AD_READ
SETBCS
MOVAD_TMP,A
RET
DELAY:
MOVR6,#5
D1:
DJNZR6,D1
DJNZACC,D1
RET
END
系统仿真:
使用Proteus仿真,可以清楚的看到单片机在输入不同模拟电压时,输出占空比不同的PWM波形。
输入为0:
输入为1.25V:
输入为2.5V:
输入为3.75V:
输入为5V:
个人课题:
<1>基于AT89S52的LED数字时钟
<1.1>设计目的:
1)自主学习AT89S52内部定时器/计数器的原理及应用
2)掌握使用单片机处理复杂逻辑的方法
3)掌握多位数码动态显示方法
4)掌握多个独立按键的读键和处理方法
<1.2>实现的功能:
用AT89S52单片机的定时/计数器T0产生1s的定时时间,作为秒计数时间,当1s产生时,秒计数加1开始计数。
显示00-00-00的时间,开始计时:
P1.0控制“秒”的调整,没按一次加1s:
P1.1控制“分”的调整,没按一次加1min:
P1.2控制“时”的调整,没按一次加1h。
计时满23-59-59时,返回00-00-00重新计时。
P1.3用作复位键,在计时过程中如果按下复位键,则返回00-00-00重新计时。
<1.3>硬件电路设计:
<1.4>程序设计:
1)程序流程图:
2)源程序:
S_SETBITP1.0;数字钟秒控制位
M_SETBITP1.1;分钟
H_SETBITP1.2;小时
RESETBITP1.3;复位
SECONDEQU30H
MINUTEEQU31H
HOUREQU32H
TCNTEQU34H
ORG0000H
SJMPSTART
ORG000BH
LJMPINT_T0
START:
MOVDPTR,#TABLE
MOVHOUR,#0;初始化
MOVMINUTE,#0
MOVSECOND,#0
MOVTCNT,#0
MOVTMOD,#01H
MOVTH0,#60;定时50ms
MOVTL0,#176
MOVIE,#82H
SETBTR0
A1:
LCALLDISPLAY;判断是否有按键按下,按按键扫描
MOVP1,#0FFH
JNBS_SET,S1
JNBM_SET,S2
JNBH_SET,S3
JNBRESET,START
LJMPA1
S1:
LCALLDELAY;延时消抖
JBS_SET,A1
INCSECOND;秒加1
LCALLDISPLAY
MOVA,SECOND
CJNEA,#60,J0;判断是否加到60
MOVSECOND,#0
LJMPK1
S2:
LCALLDELAY
JBM_SET,A1
K1:
INCMINUTE;分加1
MOVA,MINUTE
CJNEA,#60,J1;判断是否加到60
MOVMINUTE,#0
LJMPK2
S3:
LCALLDELAY
JBH_SET,A1
K2:
INCHOUR;时加1
MOVA,HOUR
CJNEA,#24,J2;判断是否加到24
MOVHOUR,#0
MOVMINUTE,#0
MOVSECOND,#0
LJMPA1
J0:
JBS_SET,A1;判断按键是否抬起
LCALLDISPLAY
SJMPJ0
J1:
JBM_SET,A1
LCALLDISPLAY
SJMPJ1
J2:
JBH_SET,A1
LCALLDISPLAY
SJMPJ2
INT_T0:
MOVTH0,#60;定时器中断服务程序,开始计时
MOVTL0,#176
INCTCNT
MOVA,TCNT
CJNEA,#20,RETUNE
INCSECOND
MOVTCNT,#0
MOVA,SECOND
CJNEA,#60,RETUNE
INCMINUTE
MOVSECOND,#0
MOVA,MINUTE
CJNEA,#60,RETUNE
INCHOUR
MOVMINUTE,#0
MOVA,HOUR
CJNEA,#24,RETUNE
MOVHOUR,#0
MOVMINUTE,#0
MOVSECOND,#0
MOVTCNT,#0
RETUNE:
RETI
DISPLAY:
MOVA,SECOND;显示程序,扫描,显示秒
MOVB,#10
DIVAB
CLRP3.6
MOVCA,@A+DPTR
MOVP0,A
LCALLDELAY
SETBP3.6
MOVA,B
CLRP3.7
MOVCA,@A+DPTR
MOVP0,A
LCALLDELAY
SETBP3.7
CLRP3.5
MOVP0,#40H;显示分隔号
LCALLDELAY
SETBP3.5
MOVA,MINUTE;显示分
MOVB,#10
DIVAB
CLRP3.3
MOVCA,@A+DPTR
MOVP0,A
LCALLDELAY
SETBP3.3
MOVA,B
CLRP3.4
MOVCA,@A+DPTR
MOVP0,A
LCALLDELAY
SETBP3.4
CLRP3.2
MOVP0,#40H;显示分隔号
LCALLDELAY
SETBP3.2
MOVA,HOUR;显示时
MOVB,#10
DIVAB
CLRP3.0
MOVCA,@A+DPTR
MOVP0,A
LCALLDELAY
SETBP3.0
MOVA,B
CLRP3.1
MOVCA,@A+DPTR
MOVP0,A
LCALLDELAY
SETBP3.1
RET
TABLE:
DB3FH,06H,5BH,4FH,66H
DB6DH,7DH,07H,7FH,6FH
DELAY:
MOVR6,#5
D1:
MOVR7,#250
DJNZR7,$
DJNZR6,D1
RET
END
<1.5>系统仿真:
1)时钟仿真:
复位和初始:
秒加1:
分加1:
时加1:
<1.6>模块整体电路:
<1.7>PCB板:
<1.8>3D效果图:
附:
个人课题:
<2>基于DS12887的LCD数字时钟(C语言)
<2.1>源程序:
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
ucharmiao,fen,shi,ri,zhou,yue,nian,time_flag,key_num;
sbitDS_cs=P2^7;
sbitDS_as=P2^3;
sbitDS_rw=P3^6;
sbitDS_ds=P3^7;
sbitLCD_rs=P2^0;
sbitLCD_en=P2^1;
sbitbeep=P2^2;
sbitkey1=P2^5;
sbitkey2=P2^6;
ucharcodetable1[]={"20--"};
ucharcodetable2[]={":
:
"};
voiddelay(ucharz)
{
ucharx,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
voidDS_write(ucharadd,uchardate)
{
DS_as=1;
DS_ds=1;
DS_rw=1;
DS_cs=0;
P1=add;
DS_as=0;
DS_rw=0;
P1=date;
DS_rw=1;
DS_as=1;
DS_cs=1;
}
ucharDS_read(ucharadd)
{
ucharDS_read_dat;
DS_as=1;
DS_ds=1;
DS_rw=1;
DS_cs=0;
P1=add;
DS_as=0;
DS_ds=0;
P1=0xff;
DS_read_dat=P1;
DS_ds=1;
DS_as=1;
DS_cs=1;
return(DS_read_dat);
}
voidLCD_write_com(ucharcom)
{
LCD_rs=0;
LCD_en=0;
delay(5);
LCD_en=1;
P0=com;
LCD_en=0;
}
voidLCD_write_data(uchardate)
{
LCD_rs=1;
LCD_en=0;
delay(5);
LCD_en=1;
P0=date;
LCD_en=0;
}
voidDisplay_Btime(ucharadd,uchardate)
{
LCD_write_com(add);
;
LCD_write_data(date);
}
voidDisplay_BCDtime(ucharadd,uchardate)
{
uchargw,sw;
sw=date/10;
gw=date%10;
LCD_write_com(0x80+add);
LCD_write_data(0x30+sw);
LCD_write_data(0x30+gw);
}
voidBCD_time()
{
miao=DS_read(0x00);
Display_BCDtime(0x4a,miao);
fen=DS_read(0x02);
Display_BCDtime(0x47,fen);
shi=DS_read(0x04);
Display_BCDtime(0x44,shi);
ri=DS_read(0x07);
Display_BCDtime(0x0a,ri);
yue=DS_read(0x08);
Display_BCDtime(0x07,yue);
nian=DS_read(0x09);
Display_BCDtime(0x04,nian);
zhou=DS_read(0x06);
switch(zhou)
{
case1:
{
Display_Btime(0x80+0x0d,'M');
Display_Btime(0x80+0x0e,'O');
Display_Btime(0x80+0x0f,'N');
}
break;
case2:
{
Display_Btime(0x80+0x0d,'T');
Display_Btime(0x80+0x0e,'U');
Display_Btime(0x80+0x0f,'E');
}
break;
case3:
{
Display_Btime(0x80+0x0d,'W');
Display_Btime(0x80+0x0e,'E');
Display_Btime(0x80+0x0f,'D');
}
break;
case4:
{
Display_Btime(0x80+0x0d,'T');
Display_Btime(0x80+0x0e,'H');
Display_Btime(0x80+0x0f,'U');
}
break;
case5:
{
Display_Btime(0x80+0x0d,'F');
Display_Btime(0x80+0x0e,'R');
Display_Btime(0x80+0x0f,'I');
}
break;
case6:
{
Display_Btime(0x80+0x0d,'S');
Display_Btime(0x80+0x0e,'A');
Display_Btime(0x80+0x0f,'T');
}
break;
case7:
{
Display_Btime(0x80+0x0d,'S');
Display_Btime(0x80+0x0e,'U');
Display_Btime(0x80+0x0f,'N');
}
break;
default:
break;
}
}
voidkeyscan()
{
if(key1==0)
{
delay(10);
if(key1==0)
{
key_num++;
time_flag=1;
switch(key_num)
{
case1:
{
while(!
key1);
delay(10);
while(!
key1);
LCD_write_com(0x80+0x40+11);
LCD_write_com(0x0f);
}
break;
case2:
{
while(!
key1);
delay(10);
while(!
key1);
LCD_write_com(0x80+0x40+8);
LCD_write_com(0x0f);
}
break;
case3:
{
while(!
key1);
delay(10);
while(!
key1);
LCD_write_com(0x80+0x40+5);
LCD_write_com(0x0f);
}
break;
case4:
{
while(!
key1);
delay(10);
while(!
key1);
LCD_write_com(0x80+11);
LCD_write_com(0x0f);
}
break;
case5:
{
while(!
key1);
delay(10);
while(!
key1);
LCD_write_com(0x80+0x08);
LCD_write_com(0x0f);
}
break;
case6:
{
while(!
key1);
delay(10);
while(!
key1);
LCD_write_com(0x80+0x05);
LCD_write_com(0x0f);
}
break;
case7:
{
LCD_write_com(0x0c);
key_num=0;
time_flag=0;
while(!
key1);
delay(10);
while(!
key1);
DS_write(0x09,nian);
DS_write(0x08,yue);
DS_write(0x07,ri);
DS_write(0x06,2);
DS_write(0x04,shi);
DS_write(0x02,fen);
DS_write(0x00,miao);
}
break;
default:
break;
}
}
}
if(key2==0)
{
delay(10);
if(key2==0)
{
switch(key_num)
{
case1:
{