求指导,要求做一个51单片机的转速计的c程序,脉冲输入后,可以在4位led上显示转速,但是我不是很明白

求指导,要求做一个51单片机的转速计的c程序,脉冲输入后,可以在4位led上显示转速,但是我不是很明白,第1张

从LZ描述看来,测速的硬件已经具备,只是不明白如何测量脉冲计数并计算转速.

首先你应该知道你的转速范围是多大?每秒几十转还是几百转甚至上千转?

不同的转速对应不同的设计.

可以使用51的定时器/计数器来实现脉冲捕获计数.比如使用T0.

设置T0的工作模式,一般可用自动重装8位计数的模式2.

在T0的溢出中断中,设计二重计数cntT0.比如T0为200转溢出,则中断时再累加一次即累加了200转.

设置T1为定时器模式,可以定时1S或10ms(计为t),由你转速及程序复杂度决定.

在T1中断程序中,读取cntT0的值和T0的值(计算为rt),则转速为rt/t

开关控制指示灯显示

MY8255_AEQU 0A860H;8255A口地址

MY8255_BEQU 0A861H;8255B口地址

MY8255_CEQU 0A862H;8255C口地址

MY8255_MODE EQU 0A863H;8255控制口地址

CODE SEGMENT

ASSUME CS:CODE

START: MOV DX,MY8255_MODE

MOV AL,82H

OUT DX,AL;将控制字82H写入8255控制口,A口方式0输出,B口方式0输入, C口未用到。

A1:MOV DX,MY8255_B

IN AL,DX ;读8255 B口内容

MOV DX,MY8255_A

OUT DX,AL ; 将前面读到的B口内容送到A口,即A口内容=B口内容

CALL BREAK;调用子程序BREAK

JMP A1;跳转到A1

BREAK PROC NEAR ;BREAK子程序

MOV AH,1

INT 16H

JZ RETURN ;读按键字符,ZF=1,则返回;ZF=0,则AL=字符

MOV AX,4C00H

INT 21H ;返回DOS 

RETURN:RET

BREAK ENDP

CODE ENDS 

END START

流水灯显示

MY8255_AEQU 0b860H;8255A口地址

MY8255_BEQU 0b861H;8255B口地址

MY8255_CEQU 0b862H;8255C口地址

MY8255_MODE EQU 0b863H;8255控制口地址

DATA SEGMENT

LA DB ?;留出1个字节

LB DB ?;留出1个字节

DATA ENDS

CODE SEGMENT

ASSUME CS:CODE,DS:DATA

START: MOV AX,DATA

MOV DS,AX

MOV DX,MY8255_MODE

MOV AL,80H

OUT DX,AL ;控制字80H送入8255控制口,A口、B口都是方式0输出,C口未用到。

MOV DX,MY8255_A

MOV AL,7FH

OUT DX,AL ;将7FH送入A口

MOV LA,AL ;将7FH送入LA存储单元

MOV DX,MY8255_B

MOV AL,0FEH

OUT DX,AL;将FEH送入B口

MOV LB,AL ;将FEH送入LB存储单元

CALL DALLY

A1:MOV AL,LA

ROR AL,1;LA内容循环右移1次

MOV LA,AL

MOV DX,MY8255_A

OUT DX,AL ;将循环右移后的LA内容送A口,其目的是让A口连接的LED灯依次向右循环点亮

MOV AL,LB

ROL AL,1 ;LB内容循环左移1次

MOV LB,AL

MOV DX,MY8255_B

OUT DX,AL ;将循环左移后的LB内容送B口,其目的是让B口连接的LED灯依次向左循环点亮

CALL DALLY ;延时,让一个LED灯发光稳定之后再点亮另一个

CALL BREAK ;调用BREAK子程序,看是否有键按下

JMP A1 ;跳转到A1

DALLY: MOV CX,3FFH ;延时子程序

D1:MOV AX,0FFFFH

D2:DEC AX

JNZ D2

LOOP D1

RET

BREAK PROC NEAR ;是否有键按下

MOV AH,06H

MOV DL,0FFH

INT 21H

JE RETURN ;若无,则转RETURN

MOV AX,4C00H

INT 21H ;返回DOS

RETURN:RET

BREAK ENDP

CODE ENDS

END START

#include <reg51.h>

#include <INTRINS.H>

#define FOSC 11.0592

unsigned int speed

unsigned char key

unsigned char led_table[10]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xff,0xf6}

long speed_count,speed_count1

unsigned char speed_check

unsigned int second_flag

unsigned char speed_table[4]

unsigned char speed_table1[10]

//定时器频率1000Hz

void timer1_init(void)

{

EA=0

TMOD=0x10

//TH1=1000*FOSC/12/256

//TL1=(unsigned int)(1000*FOSC/12)%256

TH1=254

TL1=51

TR1=1

TCON|=0X04 //外部中断下降触发

EX1=1 //允许外部中断

ET1=1

EA=1

}

void int1_routine(void) interrupt 2

{

speed_count++

P1^=0X02

}

void timer1_routine(void) interrupt 3

//void timer1_routine(void)

{

TH1=254

//TH1=0xf0

TL1=51

//speed_count++

second_flag++

}

void main(void)

{

unsigned int i,j,k

// unsigned char sum

unsigned speed_table[3]

long time_id

timer1_init()

speed=0

P2=0x0f

P0=0xf0

P3=0x08

key=0

P1=0x00

speed_check=0

while(1)

{

//P1^=0XFE

j=1

//speed=1234

speed_table[0]=speed/1000

speed_table[1]=speed%1000/100

speed_table[2]=speed%100/10

speed_table[3]=speed%10

for(i=0i<4i++)

{

P2=j^0xff

j<<=1

P0=(led_table[speed_table[i]])&0xfe

for(k=0k<250k++)

}

//speed=speed_count

if(second_flag>=1000) /*中断1000次进入 */

{

second_flag=0

time_id++

speed_table1[time_id%10]=speed_count/*外部中断量转存(是很聪明的方法学习了)*/

speed_count=0

speed=(speed_table1[0]+speed_table1[1]+speed_table1[2]+speed_table1[3]+speed_table1[4]+speed_table1[5]+speed_table1[6]+speed_table1[7]+speed_table1[8]+speed_table1[9])*6/*(10X6)10秒的外部中断量乘以6就是转速了*/

//speed=speed/2+(speed_table[0]+speed_table[1]+speed_table[2])*6

}

}

}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/8135082.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-13
下一篇 2023-04-13

发表评论

登录后才能评论

评论列表(0条)

保存