C51——添加震动开盖功能,使用外部中断优化

本文探讨了如何通过优化外部中断处理,解决单片机中震动模块反馈不灵敏的问题,对比了按键与震动传感器操作的响应差异,并给出了使用外部中断来实时捕获震动信号的改进方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

void main()
{
	double dis;
	Timer1Init();
	Time0Init();
	SG90_Init();

	while(1){
		dis = get_dis();

	if(dis<10 || SW1 == 0||Vibrate == 0){
		OpenTheLed5();
		opengaizi(); // 
	}else{
		CloseTheLed5();
		closegaizi();
	}

	
	}
}

像这样只是简单的通过震动模块传给单片机一个让舵机转动,出来的现象使一卡一卡的,不是特别的灵敏,震动模块的反馈没有及时被捕获。

    if(dis<10 || SW1 == 0||Vibrate == 0){
        OpenTheLed5();
        opengaizi(); // 
    }else{
        CloseTheLed5();
        closegaizi();
    }

因为dis 大部分时间使大于0的,程序进行关盖的操作,并持续150ms后在进行下一步操作。

那为什么按键操作比震动模块操作的好呢?

因为按键的反馈的信号更加稳定持久。

持续的低电平更加容易钻到空子,而震动传感器发生震动的一瞬间 程序可能正在执行延迟。

因此 震动模块一但发生低电平,就触发中断,所以选用外部中断。

 

 外部中断一定要要接P3^2

 

 

要用外部中断 EX0 = 1 (打开外部中断),EA= 1 总开关也要打开

 中断的触发行为(这里我们用的使外部中断0)

 所以我们想要用外部中断

打开外部中断 

EX0 = 1;

触发中断

IT0 = 0; 

 

总体整合代码如下

#include "reg52.h"

sbit D5   = P3^7;//
sbit D6   = P3^6;//
sbit SW1  = P2^1;
sbit Trig = P1^5;
sbit Echo = P1^6;
sbit sg90_con = P1^1;
sbit Vibrate = P3^2;

	int cnt;
	int jd;
	double time;
	int mark_Vibrate = 0;
void Delay10us()		//@11.0592MHz
{
	unsigned char i;

	i = 2;
	while (--i);
}


void Timer1Init()		//100??@11.0592MHz
{
	
	TMOD &= 0x0F;		//ÉèÖö¨Ê±Æ÷ģʽ
	TMOD |= 0x10;		//ÉèÖö¨Ê±Æ÷ģʽ
	TL1 = 0;		//ÉèÖóõÖµ
	TH1 = 0;		//ÉèÖóõÖµ
}

void startHC()
{
	Trig = 0;
	Trig = 1;
	Delay10us();
	Trig = 0;
}
double get_dis()
{
	TL1 = 0;		//ÉèÖóõÖµ
	TH1 = 0;		//ÉèÖóõÖµ
 //1.¸øTrig ¶Ë¿ÚÖÁÉÙ10us µÄ¸ßµçƽ
	startHC();
	//2.EchoÐźţ¬ÓÉµÍµçÆ½±äΪ¸ßµçƽ¿ªÊ¼Ê±·¢ÐźÅ
	while(Echo == 0);
	  TR1 = 1;		//¿ªÊ¼¼ÆÊ±
	//3.EchoÐźţ¬ÓÐ¸ßµçÆ½±äΪµÍµçƽ½áÊø·¢ÐźÅ
	while(Echo == 1);
	 TR1 = 0;		//½áÊø¼ÆÊ±
	
	//4.¼ÆËãʱ¼ä
	time = (TH1*256 +TL1)*1.085 ;
	//5.¼ÆËã¾àÀë
	return (0.017* time);
}
void OpenTheLed5()
{
		D5 = 0;
		D6 = 1;
}
void CloseTheLed5()
{
		D5 = 1;
		D6 = 0;
}

void Delay150ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	//_nop_();
	i = 2;
	j = 13;
	k = 237;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}


void Time0Init()
{
		//ÅäÖö¨Ê±Æ÷0 ¹¤×÷ģʽΪ16λ¼ÆÊ±
	TMOD &= 0xF0;		//ÉèÖö¨Ê±Æ÷ģʽ
	TMOD |= 0x01;		//ÉèÖö¨Ê±Æ÷ģʽ 
	//¸ø³õÖµ£¬¶¨³öÒ»¸ö0.5msÀ´
		TL0 = 0x33;
		TH0 = 0xFE;
	//¿ªÊ¼¼ÆÊ±
	TR0 = 1;
	//Çå³ý±êʶλ
	TF0 =0;
	// ´ò¿ª¶¨Ê±Æ÷0 ÖжÏ
	ET0 = 1;
	//´ò¿ª×ÜÖÐ¶Ï EA
	EA = 1;
}
 void Delay2000ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	//_nop_();
	i = 15;
	j = 2;
	k = 235;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

void opengaizi()
{
		jd = 3;  //90¡ã
		cnt = 0;
		Delay2000ms();
}
void closegaizi()
{
		jd = 1; //  0¶È
		cnt = 0;
		Delay150ms();
}
void SG90_Init()
{
	jd = 1;     // ³õʼ½Ç¶ÈÊÇ 0 ¶È£¬0.5ms£¬Òç³ö1
	cnt = 0;
	sg90_con = 1; //Ò»¿ªÊ¼´Ó¸ßµçƽ¿ªÊ¼

}
void EX0_Init()
{
	//´ò¿ªÍⲿÖжÏ
	EX0 = 1;
	EA = 1;
	// ´¥·¢ÖжÏ
	IT0 = 0;
}
void main()
{
	double dis;
	Timer1Init();
	Time0Init();
	EX0_Init();
	SG90_Init();

	while(1){
		dis = get_dis();

	if(dis<10 || SW1 == 0||mark_Vibrate==1){
		OpenTheLed5();
		opengaizi(); // 
		mark_Vibrate=0;
	}else{
		CloseTheLed5();
		closegaizi();
	}

	
	}
}

void Time0ZD() interrupt 1  //±¬±íÖ®ºó£¬²»ÔÚÓÃÈí¼þÇåÁ㣬Õâ¸öÖжϽ«±êʶλTF0 
{
	cnt++;
	
	TL0 = 0x33;
	TH0 = 0xFE;
	// ¿ØÖÆPWM²¨
	if(cnt<jd){
		 sg90_con = 1;
	}else{
		sg90_con = 0;
	}
	if(cnt == 40){ // ËÄÊ®´Î±¬±í£¬¾­¹ýÁË20ms£¬Íê³ÉÁËÒ»¸öÖÜÆÚ£
		cnt = 0;
		sg90_con = 1;
	}
}
void EX0_ZD() interrupt 0
{
	mark_Vibrate =1;   // µ±´¥·¢ÖжϵÄʱºò ÈÃÕâ¸öÖÃ1£»
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值