我是靠谱客的博主 舒心小丸子,最近开发中收集的这篇文章主要介绍51单片机Proteus仿真+Keil工程-实验3-开启4个中断-频率计实验3-单片机定时器中断实验,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

实验3-单片机定时器中断实验

  之前做的一次实验,51单片机定时器中断实验。如有问题欢迎指正。

实验目标:

  通过定时1s(方式2)和5s(方式1),分别让对应的led灯闪烁一次。通过外部信号发生器,计数外部下降沿,并计算频率应用数码管显示,与信号发生器的频率进行比对。

实现效果:

在这里插入图片描述
在这里插入图片描述

Proteus原理图

在这里插入图片描述

选择元器件:

DEVICES说明
7SEG-MPX8-CC-BLUE八位共阴极数码管
AT89C51MCU
BUTTON按键
CAP普通电容
CAP-ELEC电解电容
CRYSTAL晶振
LED-BLUE蓝色LED灯
RES电阻
RESPACK-8排阻

  51单片机的P0口做IO口使用时是漏极开路输出,其引脚一般需要在片外接一定阻值的上拉电阻,此时端口不存在高阻抗的悬浮状态,因此它是一个准双向口。同时,P0口每一位的驱动能力是P1~P3口的两倍,每位可以驱动8个LSTTL(Low-power Schottky TTL,即低功耗肖特基TTL)输入,89C51等单片机任何一个端口想要获得较大的驱动能力,必须采用低电平输出。
  时钟晶体振荡频率为 f o s c = 12 M H Z f_{osc}=12MHZ fosc=12MHZ
  时钟周期相当于 T o s c = 1 f o s c ≈ 83.33 n s T_{osc}=frac{1}{f_{osc}} approx 83.33ns Tosc=fosc183.33ns
  复位电路的话通过给89C51等单片机的复位引脚RST加上大于2个机器周期的高电平(即24个时钟振荡周期)就可以使单片机复位。

KEIL工程:

  1.我按照要求,使用定时器t0的方式2去控制LED灯,间隔1秒闪烁;
  2.使用定时器t1的方式1,去控制LED灯,间隔5秒闪烁;
  3.为了计数频率,我使用外部中断0来计数下降沿,为了使计数准确,我设置外部中断0为高优先级。同时使用晶振12MHZ,计数下降沿需要2个机器周期,那么理论最高计数频率为,12M/24=50KHZ。考虑到LED定时精准,不影响t0和t1,计数频率我使用t2计时器。每隔200毫秒统计一次下降沿(精度:5HZ,可以调整),故理论最低计数频率为5HZ。
  4.考虑到使用了太多中断,当外部中断0频繁中断,即频率过高时,主函数的数码管显示会受影响。
注意:计数高频率时,数码管会闪烁,原因是中断太频繁。如果在定时器t0或者t1里面,每隔一段时间计数下降沿频率,会对LED闪烁时间有相当大的的影响。如果不对外部中断0设置高优先级,会导致计数丢失。
  BUG:当测频过高由于中断太多会闪屏,待改进。

  头文件宏定义等:

#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define Datadula  P0			/*数码管段码和位码端口*/
#define Datawela  P2
#define LedPort   P1
#define TIME 1000    		 	/*延时常量(ms)*/
#define T0_INIT_VALUE 256-250	/*定时器T0的方式2 初值250us=0.25ms*/
#define T1_INIT_VALUE 50000 	/*定时器T1的方式1 初值50000us=50ms*/
#define T2_INIT_VALUE 50000
#define SHAKING_TIME 10 		/*消抖时间(ms)*/
//#define Screen_Change 800		/*频率数值刷新0.25*800=200ms 即最低可测5HZ*/
sbit LED_1s=P1^0;
sbit LED_5s=P1^2;
uchar code Duanma[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};/*0123456789-*/
uchar code Weima []= {0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};			/*自左向右*/
uchar TempData[8];				/*存储显示值的全局变量*/
uint num1,num2,num3,ctemp=1;
unsigned long int Show_freq,count;

  主函数:

void main(void)
{
	Init();//定时器初始化
	while(1)
	{
		//先显示,防止断帧
		Display(0,8);
		if(num1==4000)
		{						  
			num1=0;
			LED_1s=~LED_1s;	//亮1s,灭1s
		}
		if(num2==100)		//亮5s,灭5s
		{
			num2=0;
			LED_5s=~LED_5s;
		}
	}
}

  显示函数:

void Display(uchar FirstBit,uchar Num)
{
	static uchar i=0;
	Datadula=0x00;//段码消隐
	Datawela=0xff;//位码消隐
	
	Datawela=Weima[i+FirstBit];//位码数据,从数码管从左到右的第一位开始对应
	Datadula=TempData[i];		//段码数据
	i++;
	if(i==Num)
		i=0;
}

  定时器初始化及中断子函数:

void Init()/*使用定时器T0的方式2定时1s,使用定时器T1的方式1定时5s*/
{
	TMOD=0x12;	/*使用定时器0的方式2,8位自动重载定时器定时器/计数器
				 和  定时器1的方式1,16位定时器/计数器,
				 或运算是为了在给相应位赋值时不会影响无关位      */
	CP_RL2=0;EXEN2=0;					//设置定时器T2为16位自动重装载定时器工作方式
	TH0=T0_INIT_VALUE;					//定时器T0的方式2装入初值(256-250),250us
	TL0=T0_INIT_VALUE;
	TH1=(65536-T1_INIT_VALUE)/256;	//定时器T1的方式1装入初值,50ms
	TL1=(65536-T1_INIT_VALUE)%256;	
	TH2=RCAP2H=(65536-T2_INIT_VALUE)/256;	//定时器T2的方式1装入初值,10ms
	TL2=RCAP2L=(65536-T2_INIT_VALUE)%256;
	PX0=1;	//设置外部中断为高优先级。关键!否则会在T2计数器装TempData[]显示值时漏检测下降沿
	//PT0=1;  //将定时器0中断设为高优先级
	//PT1=1;
	EA=1;	//开总中断
	ET0=1;	//开中断允许寄存器IE,允许定时器T0溢出中断
	ET1=1;	//开中断允许寄存器IE,允许定时器T1溢出中断
	ET2=1;	//开中断允许寄存器IE,允许定时器T2溢出中断
	
	TR2=1;	//启动定时器2-在后面
	TR0=1;	//启动定时器0
	TR1=1;	//启动定时器1
	
	EX0=1;  //外部中断0开
	IT0=1;  //边沿触发
	
	LedPort=0xff;
	TempData[0]=0x71;
	TempData[1]=0x48;/*固定字符F=*/
}
void T0_time()  interrupt 1      //定时器T0的方式2 基础0.25ms
{
    //相比方式0,这里不需要加入重装初值
    num1++;	
}
void T1_time()	interrupt 3		//定时器T1的方式1
{
	TH1=(65536-T1_INIT_VALUE)/256;	//定时器T1的方式1重装入初值,50ms
	TL1=(65536-T1_INIT_VALUE)%256;
	num2++;
} 
void T2_time(void) interrupt 5
{
	TF2=0;//用软件清溢出中断标志位T2
	num3++;
	if(num3==4)//200ms
	{
		Show_freq=5*count;
		count=0;
		num3=0;
		TempData[2]=Duanma[Show_freq /100000];  //十万
		TempData[3]=Duanma[Show_freq /10000%10];//万
		TempData[4]=Duanma[Show_freq /1000%10]; //千
		TempData[5]=Duanma[Show_freq /100%10]; 	//百
		TempData[6]=Duanma[Show_freq /10%10]; 	//十
		TempData[7]=Duanma[Show_freq %10]; 		//个
	}
	Display(0,8);	
}
void ISR_Key(void) interrupt 0 using 1
{
	count++;
	if(count==100000)
		count=0;
	//晶振12MHZ,理论最高计数频率为12M/24=50KHZ,即50 0000
}

参考文献
1.《单片机原理与接口技术》张毅刚
资源

返回目录

最后

以上就是舒心小丸子为你收集整理的51单片机Proteus仿真+Keil工程-实验3-开启4个中断-频率计实验3-单片机定时器中断实验的全部内容,希望文章能够帮你解决51单片机Proteus仿真+Keil工程-实验3-开启4个中断-频率计实验3-单片机定时器中断实验所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(54)

评论列表共有 0 条评论

立即
投稿
返回
顶部