用51单片机实现风扇转速测量的源程序+电路图
时间:2023-11-25 07:07:02
项目功能:
将被测风扇叶片(三叶风扇)放置在红外光电传感器及其反射板之间,当光电传感器接收反射板反射的信号(即叶片之间的间隙通过)时,当光电传感器没有收到反射板反射的信号(即叶片通过)时,输出高电平。这样,我们从光电传感器中接收到的信号就是一串方波信号。
单片机不断接收光电传感器的信号,同时有定时器在计时,计数器在计数中接收方波的数量。计时器设置计时1秒,每1秒中断一次。统计数器中收到的方波数除以3后,得到每秒风扇转动的圆数。最后,通过我们设置的程序将其值转换为标准转速单元r/min并在8段数字管上显示数值,便于读取。
因为AT89C52兼容AT89C51.因此,在本次模拟试验中使用AT89C52。
数项目使用的八段数字管型号为7SEG-MPX6-CA,是共阳极数码管。123456号数码管从左到右对应数码管。ABCDEFG,DP分别接AT89C52的P0口,123456接单片机P1口。即用P1控制显示哪个数字管,使用P控制显示的数据。
系统原理图:
方波发生器的参数设置如下:
如图所示,频率 设计为64Hz,即每秒
钟输入64个信号,
转换为一分钟
3840,因为风扇是三
叶片的,所以除以3
以后是实际的风扇
速度,结果是
3840/3=1280,而显示
结果也是1280(如上)
图),表示单片机正
确实实现了我们实现了
需的功能。
我们在这里设置AT89C52晶振频率为11.0592Hz(设置如下图所示)为了满足实际效果,定时器T0的初始值设置为TH0=10H, TL0=00H, 时间是15次,只有1秒。
模拟结果如下:
实现程序:
程序代码如下:C语言和汇编语言:
C语言:#include //头文件包含单片机寄存器
#include //包含_nop_()函数定义的头文件
unsigned int v; //存储电机转速
unsigned char count;//储存定时器T0中断次数
bit flag; //计算1秒钟标志位
void delay1ms() //函数功能:延迟1ms
{ //(3j 2)*i=(30×3 2)×10=920
unsigned char i,j; //对11.0592MHz晶振约为1ms
for(i=0;i<10;i )
for(j=0;j<30;j )
;
}
void delay(unsigned char n) ///延迟n毫秒
{
unsigned char i;
for(i=0;i
delay1ms();
}
void change(unsigned char a) ////数字对应段码的转换
{ if(a==0) P0=0xc0;
if(a==1) P0=0xf9;
if(a==2) P0=0xa4;
if(a==3) P0=0xb0;
if(a==4) P0=0x99;
if(a==5) P0=0x92;
if(a==6) P0=0x82;
if(a==7) P0=0xf8;
if(a==8) P0=0x80;
if(a==9) P0=0x90;
}
void display_val(unsigned int x) //显示值
{
unsigned char i,j,k,l; //i,j,k,l千位、百位、十位和个位分别存储转速
i=x/1000; //取千位
j=(x00)/100; //取百位
k=(x0)/10; //取十位
l=x; //取个位
P1=8; nbsp; //选3号数码管
change(i);
delay1ms();
P1=4; //选4号数码管
change(j);
delay1ms();
P1=2; //选5号数码管
change(k);
delay1ms();
P1=1; //选6号数码管
change(l);
delay1ms();
}
void main(void) //主函数
{
TMOD=0x51; //定时器T1工作于计数模式1,定时器T0工作于计时模式1;
TH0=0x10; //定时器T0的高8位设置初值,每66.67ms产生一次中断
TL0=0; //定时器T0的低8位设置初值
EA=1; //开总中断
ET0=1; //定时器T0中断允许
TR0=1; //启动定时器T0
count=0; //将T0中断次数初始化为0
while(1) //无限循环
{
TR1=1; //计数器T1启动
TH1=0; //计数器T1高8位赋初值0
TL1=0; //计数器T1低8位赋初值0
flag=0;
while(flag==0) //时间未满1s等待
{
display_val(v); //显示转速
} ;
v=TL1*20; //计算速度,每周产生3个脉冲
}
}
void Time0(void ) interrupt 1 using 1 //定时器T0的中断编号为1,使用第1组工作寄存器
{
count++; //T0每中断1次,count加1
if(count==15) //若累计满15次,即计满1秒钟
{
flag=1; //计满1秒钟标志位置1
count=0; //清0,重新统计中断次数
}
TH0=0x10; //定时器T0高8位重新赋初值
TL0=0x00; //定时器T0低8位重新赋初值
}
汇编语言:
开始说明:T0是定时器,T1是计数器。50H存放定时器计数的次数,56H存放T1对输入信号的计数值。P0控制显示的数据,P1控制显示哪个数码管。
LEDBuf equ 40h ;显示数据存放处
org 0000h
ljmp main
org 000bh
AJMP PTF00
org 0100h
main: mov sp,#60h
mov TMOD,#51H ;01010001,T1是16位计数器方式1,T0是16位定时器方式1
mov TCON,#54h ;TR1=1,TR0=1,IT1=1,即T1在下降沿计数
mov TL0,#00H ;单次66.67ms
mov TH0,#10H ;
mov TL1,#00H
mov TH1,#00H
mov IE,#8ah ;1000 1010 EA,ET0,ET1
MOV 50H,#15 ;计数15次,即66.67ms*15=1s
mov 40h,#00h ;初始化
mov 41h,#00h
mov 42h,#00h
mov 43h,#00h
mov 44h,#00h
mov 45h,#00h
dispagain:
acall display
sjmp dispagain
PTDS: MOV R1,A ;拆字子程序
ACALL PTDS1
MOV A,R1
SWAP A
PTDS1: ANL A,#0FH
MOV @R0,A
DEC R0
RET
PTF00:
push psw
push acc
SETB PSW.3
MOV TH0,#10H
MOV A,50H
DEC A
MOV 50H,A
JNZ PTFY
MOV 50H,#15
MOV A,TL1
mov 56H,a
mov TH1,#00H
mov TL1,#00H
PTFY:
pop acc
pop psw
RETI
LOOP4: CLR A ;二转十子程序
MOV R4,A
MOV R5,A
MOV R6,A
MOV R7,#10H
LOOP5: CLR C
MOV A,52H
RLC A
MOV 52H,A
MOV A,51H
RLC A
MOV 51H,A
MOV A,R6
ADDC A,R6
DA A
MOV R6,A
MOV A,R5
ADDC A,R5
DA A
MOV R5,A
MOV A,R4
ADDC A,R4
DA A
MOV R4,A
DJNZ R7,LOOP5
mov 53H,r4
mov 54H,r5
mov 55H,r6
RET
Delay:
mov r7, #0 ; 延时子程序
DelayLoop:
djnz r7, DelayLoop
djnz r6, DelayLoop
ret
DISPLAY:
mov a,56H
mov b,#20
mul ab
mov 51H,b
mov 52H,a
MOV R0,#45H ;将转换结果存至45H--40H
lcall LOOP4
MOV A,55H
LCALL PTDS
MOV A,54H
LCALL PTDS
MOV A,53H
LCALL PTDS
setb 0d3h
mov r0, #LEDBuf
mov r1, #6 ; 共6个八段管
mov r2, #00100000b ; 从左往右显示
Loop: mov p1,#0 ; 关所有八段管
mov a, @r0
mov dptr,#LEDmap
movc a,@a+dptr
mov p0, a ; 显示一位八段管
mov p1,r2
mov r6, #1
call Delay
mov a, r2 ; 为显示下一位做准备
rr a
mov r2, a
inc r0
djnz r1, Loop
mov p1,#0
clr 0d3h
ret
LEDMAP: ; 八段数码管显示段码
;db 3fh, 06h, 5bh, 4fh, 66h, 6dh, 7dh, 07h ;共阴极段码
;db 7fh, 6fh, 77h, 7ch, 39h, 5eh, 79h, 71h
db 0c0h, 0f9h, 0a4h, 0b0h, 99h, 92h, 82h, 0f8h;共阳极段码
db 80h, 90h, 88h, 83h, 0c6h, 0a1h, 86h, 8eh
END
遇到的困难及解决办法:
数码管的显示问题。
因为不知道数码管的使用,所以先用一段程序来实验一下数码管。如下:
Mov P0,#0c0h //P0.0-P0.7分别接数码管的ABCDEFG DP引脚
Mov P1,#01h //P1.5-P1.0分别接数码管的123456引脚
结果显示效果是六号数码管亮,显示数字是0。
完整的Word格式文档51黑下载地址:
文档.doc
(890.28 KB, 下载次数: 23)
2019-7-17 01:17 上传
点击文件名下载附件
转速测量
下载积分: 黑币 -5