蓝桥杯单片机冲刺精华帖之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;即可;