【单片机】脉冲计数(定时/计数器实验)

【单片机】脉冲计数(定时/计数器实验)

  • 一、操作目的
  • 二、操作内容
  • 三、程序框图
  • 四、程序接线图
  • 五、程序清单
  • 六、代码详解

一、操作目的

  • 熟悉单片机内部定时/计数器功能,掌握初始化编程方法。

二、操作内容

  • 把定时器0外部输入的脉冲进行计数,并送显示器显示。

三、程序框图

【单片机】脉冲计数(定时/计数器实验)_第1张图片

四、程序接线图

【单片机】脉冲计数(定时/计数器实验)_第2张图片

五、程序清单

ORG 0000H
LJMP SE15
ORG 06E0H
SE15:	   			
   MOV SP,#53H
   MOV P2,#0FFH
	MOV A,#81H
	MOV DPTR,#0FF23H
	MOVX @DPTR,A	
	MOV TMOD,#05H       
	MOV TH0,#00H                ;定时计数器初始化
   MOV TL0,#00H                ;开计数器
   SETB TR0
LO29:	
   MOV R2,TH0
   MOV R3,TL0                  ;取出TH0,TL0内容
	LCALL ZOY0
	MOV R0,#79H                 ;二转十进制
	MOV A,R6
	LCALL PTDS
	MOV A,R5
	LCALL PTDS
	MOV A,R4
	LCALL PTDS                   ;送显示缓冲区
	LCALL SSEE                   ;显示
	SJMP LO29                    ;循环计数
ZOY0:
	CLR A
	MOV R4,A
	MOV R5,A
	MOV R6,A                     ;0送R4 R5 R6
	MOV R7,#10H
LO30:	
  	CLR C                        ;R2 R3左移,移出的
	MOV A,R3                     ;最高位送CY
	RLC A
	MOV R3,A
	MOV A,R2
	RLC A
	MOV R2,A
	MOV A,R6
	ADDC A,R6                  ;(R4 R5 R6)*2送R4 R5 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,LO30                ;循环16次
	RET
PTDS:  
	MOV R1,A                    ;拆送显示缓冲区
	ACALL PTDS1
	MOV A,R1
	SWAP A
PTDS1: 
	ANL A,#0FH
	MOV @R0,A
	INC R0
	RET
SSEE:	
	SETB RS1                     ;换工作区
  	MOV R5,#05H
SSE2:	 
	MOV 30H,#20H
  	MOV 31H,#7EH
  	MOV R7,#06H
SSE1:	
	MOV R1,#20H
	MOV A,30H
	CPL A
	MOVX @R1,A                   ;字位送入
	MOV R0,31H
	MOV A,@R0
	MOV DPTR,#DDFF
	MOVC A,@A+DPTR               ;取字形代码
	MOV R1,#21H
	MOVX @R1,A                   ;字形送入
	MOV A,30H                    ;右移
	RR A
	MOV 30H,A
	DEC 31H
	MOV A,#0FFH
	MOVX  @R1,A                  ;关显示
	DJNZ R7,SSE1                 ;6位显示完了吗?
	DJNZ R5,SSE2                 ;5次显示完了吗?
	CLR RS1
	RET
DDFF:
	DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H
  	DB 88H,83H,0C6H,0A1H,86H,8EH,0FFH,0CH,89H,0DEH
END

六、代码详解

#include 
#include 

#define uchar unsigned char

#define com8255 XBYTE[0xff23] //宏定义口地址
#define pa8255 XBYTE[0xff20]
#define pb8255 XBYTE[0xff21]
//unsigned char code mon51[3] _at_ 0x3b;//保留0X3B开始三个程序空间作全速中断用
uchar code table[10] = { 0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90 };
uchar code wei[] = { 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };

unsigned int number = 0;
unsigned int temp = 0;

void delay(unsigned int i)
{
	unsigned int j, k;
	for (k = 0; k < i; k++)
		for (j = 0; j < 100; j++)
			;
}

void main(void)
{
	uchar m = 0;
	com8255 = 0x80; //控制口赋值
	pa8255 = 0x00;	//PA初始化
	pb8255 = 0x00;	//PB口初始化

	//设置16位,并且设置T0为计数器,T1为定时器 参考P114图7.3
	TMOD = 0x15;

	// 设置计数器
	// 计数器置零
	TH0 = 0x00;
	TL0 = 0x00;

	// 设置定时器T1
	// 根据公式计算得出,设置时间为50ms 参考P113推导公式
	TH1 = 0x3c;
	TL1 = 0xb0;

	//设置中断
	//中断总体允许控制位
	EA = 1;

	//计数器T0的溢出中断允许控制位 参考P151
	ET0 = 0;
	//TR0是计数器T0的启动位,1代表计数器T0开始计数
	TR0 = 1;

	//定时器T1的溢出中断允许控制位 参考P151
	ET1 = 1;
	//TR1是定时器T1的启动位,1代表定时器T1开始计数
	TR1 = 1;

	delay(2);

	//通过计数在数码管显示相应的数字
	while (1)
	{
		pb8255 = table[(number / 1) % 10];
		pa8255 = ~wei[5];

		pb8255 = table[(number / 10) % 10];
		pa8255 = ~wei[4];

		pb8255 = table[(number / 100) % 10];
		pa8255 = ~wei[3];

		pb8255 = table[(number / 1000) % 10];
		pa8255 = ~wei[2];

		pb8255 = table[(number / 10000) % 10];
		pa8255 = ~wei[1];

		pb8255 = table[(number / 100000) % 10];
		pa8255 = ~wei[0];
	}
}

void Dealy(void) interrupt 3 using 0
{
	//重置时间为50ms
	TH1 = 0x3c;
	TL1 = 0xb0;

	//将计数器中的高8位传送到temp变量中
	temp = TH0;
	//将高八位转换成十进制
	temp = temp * 256;
	//将计数器中的低8位传送到number变量中
	number = TL0;
	//将低8位与高八位相加,得出现在的记的数
	number = number + temp;

	//将计数器清零
	TH0 = 0x00;
	TL0 = 0x00;

	//计数器T0的溢出中断标志位,当T0从初值开始加一计数到产生溢出时,由硬件使TF0置1,直到CPU响应中断由硬件复位
	TF0 = 0;
}

你可能感兴趣的:(单片机)