蓝桥杯单片机P0口控制的外设互相冲突问题的解决

文章讲述了在蓝桥杯单片机竞赛中遇到的P0口控制多个外设的问题,包括与继电器冲突的解决过程。作者发现P0口数据可能被错误地传递给其他外设,通过增加状态变量和修改编程逻辑解决了这一问题,强调了硬件设计对软件的影响和逻辑严谨的重要性。
摘要由CSDN通过智能技术生成

蓝桥杯单片机冲刺精华帖之P0口你咋这么牛逼,可以同时控制4路外设!!!

13届省赛题目中smg与继电器冲突解决方案

问题发现:


void taskji()
{//
	if(mode==0)
	{
		if(temp>temp_pa*10)//!!!!!!!!!!!!!哎!!!!!!!!!!!!!!/10我是真没想到啊!!!!!!!!/10不可以,要是*10
		{
			select_hc(Y0);hc5|=0x10;P0=hc5;select_hc(Y5);
		}else{
			select_hc(Y0);hc5&=0xef;P0=hc5;select_hc(Y5);//bug 2
		}
	}
//-
	if(mode==1)
		{
			if((rtc->min==0)&&(rtc->sec==0))
			{
				ji_cnt=0;
				select_hc(Y0);hc5|=0x10;P0=hc5;;select_hc(Y5);
			}
			if(ji_cnt==4000){ji_cnt=4001;select_hc(Y0);hc5&=0xef;P0=hc5;select_hc(Y5);}
		}
}
void taskled()
{//
	if((rtc->min==0)&&(rtc->sec==0))
	{
		led_cnt=0;
		select_hc(Y0);hc4&=0xfe;P0=hc4;select_hc(Y4);
	}
	if(led_cnt==4000){led_cnt=4001;select_hc(Y0);hc4|=0x01;P0=hc4;select_hc(Y4);}
//-
	if(mode==0)
	{
		select_hc(Y0);hc4&=0xfd;P0=hc4;select_hc(Y4);//bug 1
	}else{select_hc(Y0);hc4|=0x02;P0=hc4;select_hc(Y4);}//bug 3
//	
	if((temp>temp_pa*10)||(ji_cnt<4000))//继电器闭合条件
	{
		if(led3_cnt==100)
		{
			led3_cnt=0;
			select_hc(Y0);
			if(on==0)
			{
				on=1;
				hc4&=0xfb;
				P0=hc4;//点亮L3
			}else{
				on=0;
				hc4|=0x04;
				P0=hc4;
			}
			select_hc(Y4);
			//!!!!!!!!!!!!!!
		}
	}else{
		select_hc(Y0);hc4|=0x04;P0=hc4;select_hc(Y4);
	}
}

!!!!!!!!smg与继电器相互影响!!!!!!!!!!!

1.206行 找到了led闪烁亮度暗的原因,试题1和2都是根据P0端口 读-改-写 ,但是,读到的大概率可能不是写进LED的hc573芯片中的数据,
//解决方法: 增加 bit on=0;//2024/3/15 上午
2.//晚上
smg,led,ji的P0占用问题没这么简单,需要重视,硬件结构设计复杂,必定带来软件上的消耗。
!!!!!!最终解决方法:!!!!!!!
问题出现位置:218 bug 1 -> bug 2 -> bug 3


问题解决:

!!!!!!!!!!2024/3/16 12:50分!!!!!!!!!!!
解决方案:
在public.c中添加 u8 hc4=0xff,hc5=0x00,hc6=0x00,hc7=0xff;//!!!硬件设计所带来的必要软件变量!**每个P0连接的外设创建一个状态值分别为hc4,hc5,hc6,hc7**

总结 :为smg,继电器,数码管两端口,都创建一个变量,根据4个外设hc573芯片的状态,改变P0口锁存器中的数据,从而保证每次操作用 **&** , **|**  P0口时不会误将应传送给其他外设的值带给下一个外设!!一共4个变量,软件服务硬件嘛,为了不出意外bug,逻辑严谨,4个变量的设置起到了四两拨千斤的效果!!!!!!!!!!

例:

u8 smg_code[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,  0xc1 ,0xbf};//10U 11-
void smg_display(u8 *smg_date)
{
	static u8 i=0;
	select_hc(Y0);hc7=0xff;P0=hc7;select_hc(Y7);
	select_hc(Y0);hc6=0x01<<i;P0=hc6;select_hc(Y6);
	select_hc(Y0);hc7=*(smg_date+i);P0=hc7;select_hc(Y7);
	select_hc(Y0);P0=0xff;
	i++;
	if(i==8)i=0;
}

每次欲改变外设(smg,继电器)的状态时,采用先向hc4,hc5,hc6,hc7中写值,再P0=hc6;即可;

  • 11
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值