蓝桥杯51单片机设计
目录
#与或运算(进阶)#
一.LED状态控制
state1:
state2:
state3:
LED灯代码升级
二.蜂鸣器与继电器代码升级
三.数码管代码升级
四.快速取数法
五.数码管自适应长度
方法一:
方法二: 从最高位一次取判断是否为0,为0熄灭
六.参数的边界值调节
环形:
直线型:
七:代码简化——提高可读性
①三目运算符(一般用于赋值)
②自加优化,取余操作(只限于取0)
③自加自减优化
#与或运算(进阶)#
与:& 1&1=1 1&0=0 0&0=0
或:| 1|1=1 1|0=1 0|0=0
任何数字和1与都不变,和0与都变零
任何数字和0或都不变,和1或都变1
应用一:
将某个二进制数第一位置1,其余不变
或运算符: x=x|0X01(0000 0001)
将某个二进制数第二位置1,其余不变
或运算符: x=x|0X02(0000 0010)
将某个二进制数第三位置1,其余不变
或运算符: x=x|0X04(0000 0100)
将某个二进制数第四位置1,其余不变
或运算符: x=x|0X08(0000 1000)
……
应用二:
将某个二进制数第一位置0,其余不变
用与运算符: x=x&0Xfe(1111 1110)
x=x&(~0x01)
将某个二进制数第二位置0,其余不变
用与运算符: x=x&(~0X02)
将某个二进制数第三位置0,其余不变
用与运算符: x=x&(~0X04)
……
注意:其中0x01 0x02 0x04 0x08都可以用十进制表示更简法
1 2 4 8
一.LED状态控制
亮 :置0 &0变0(其余都为1,&1不变) 不变:置1 |1变1(其余都为0,|0不变)
P0初始状态 : 1111 1111
注意:LED低电平点亮
state1:
1 L1亮
0 L1灭
if(state1==1)
{P0=P0&(~0x01);
}
else
{P0=P0|0x01;
}
state2:
1 L2 100ms闪烁
0 L2灭
if(state2==1)
{if(100ms%2);{P0=P0&(~0x02)
}else{P0=P0|0x02;
}
}
else
{P0=P0|0x02;
}
state3:
0 L3 L4 L5灭
1 L3亮 L4 L5灭
2 L4亮 L3 L5灭
3 L5亮 L3 L4灭
if(state3==0)
{P0=P0|0x1c;
}
if(state3==1)
{P0=P0&(~0x04);
}
else
{P0=P0|0x04;
}
if(state3==2)
{P0=P0&(~0x08);
}
else
{P0=P0|0x08;
}
if(state==3)
{P0=P0&(~0x10)
}
else
{P0=P0|0x10;
}
关键:每一个状态值控制一个LED,不影响其余LED灯,不满足条件一定要让对应LED灭
手动修改地址,进行运行
LED灯代码升级
void led(uchar *LED,uchar pos)
{static uchar temp=0xff;if(LED[pos]){temp &=~(0x01<<pos);}else{temp |=0x01<<pos;}P0=temp;hc573(4);
}
①不需要返回值,LED值都已储存在数组中
②控制某一个灯亮,用&(&1不变,所以要取反)
0000 0001 可以向左移位,控制灯的灭
如果控制某个灯亮,就是低电平,取反控制位选
二.蜂鸣器与继电器代码升级
//0100 0000
void beep(uchar f)
{uchar temp;if(f){temp |=0x40;}else{temp &=~0x40;}P0=temp;hc573(5);
}
//0001 0000
void realy(uchar j)
{uchar temp;if(j){temp |=0x10;}else{temp &=~0x10;}P0=temp;hc573(5);
}
三.数码管代码升级
code uchar segment[]={0xC0 ,0xF9 ,0xA4 ,0xB0 ,0x99 ,0x92 ,0x82 ,0xF8 ,0x80 ,0x90 ,0xff,0xbf};
void smg(uchar *SMG,uchar pos,uchar *dot)
{P0=0xff;hc573(7);P0=0x01<<pos;hc573(6);if(dot[pos]){P0=segment[SMG[pos]]&0x7f;}else{P0=segment[SMG[pos]];}hc573(7);
}
四.快速取数法
先取余数,将这一为放在最前面,再做除法
若数字23456
个位:23456%10=6
十位:23456%100/10=5
百位:23456/100%10=4
千位:23456/1000%10=3
万位:23456/10000=2
五.数码管自适应长度
非有效数字熄灭
eg.num=00100,数码管显示100
关键:有效数字前面的0熄灭,有效数字的后面的0不熄灭
方法一:
if num<9999 万位熄灭
if num<999 千位熄灭
if num<99 百位熄灭
if num<9 十位熄灭
方法二: 从最高位一次取判断是否为0,为0熄灭
只要有一位不为0就跳出来
只判断万~十位,个位不管
六.参数的边界值调节
题目:通过按键加减,调节参数大小,注意边界值
环形:
时间: 秒0~59 分0~59 时0~23
按键+:分,秒
time=time+1;
if(time==60) time=0;
或者
time=(time+1)%60;
小时
time=time+1;
if(time==24) time=0;
或者
time=(time+1)%24
按键减: 分,秒
time=time-1;
if(time==0) time=59
小时
time=time-1;
if(time==0) time=23
注意:uchar(0~255)和 uint(0~65535) 是环形类型
num=0 num=num-1,uchar的为255 uint的为65535
直线型:
参数:0~99
按键加:
num=num+1;
if(num==100) num=99;
按键减:
num=num-1;
if(num==255) num==0
或者
if(num!=0) num--;
七:代码简化——提高可读性
①三目运算符(一般用于赋值)
a?b:c(前真后假)
②自加优化,取余操作(只限于取0)
count++;
if(count==20) count=0;
转换为:
count=(count+1)%20
③自加自减优化
count++;
if(count==20) count=0;flag=1-flag
转换成:
if(++count==20) count=0 flag=1-flag