qidao123.com技术社区-IT企服评测·应用市场
标题:
蓝桥杯积年省赛重难点
[打印本页]
作者:
立山
时间:
2025-5-9 03:51
标题:
蓝桥杯积年省赛重难点
文章后附8-15届省赛代码,模板为b站up柳离风大模板。
1.第八届省赛:电子钟
(1)如何举行时钟设置:
对BCD码举行加减运算(注意边界限制)。
//buf是需要加减调整的数组名,index为索引,sign为0表示加,1表示减
void translate_BCD(uchar *buf,uchar index,uchar sign) //*
{
buf[index]=(buf[index]/16)*10+buf[index]%16; //BCD码转十进制
if(sign==0) //加1
{
if(index==2) //小时
buf[index]=(buf[index]+1)%24;
else //秒
buf[index]=(buf[index]+1)%60;
}
else //减1
{
if(index==2) //小时
{
if(buf[index]==0) buf[index]=23; //先if等于0再else
else buf[index]=buf[index]-1;
}
else
{
if(buf[index]==0) buf[index]=59;
else buf[index]=buf[index]-1;
}
}
buf[index]=(buf[index]/10)*16+buf[index]%10; //十进制转BCD码
}
复制代码
要写一个时钟重新初始化函数:
void ds1302_write(uchar *temp) //重新初始化时钟
{
uchar i;
Write_Ds1302_Byte(0x8e,0x00);
for(i=0;i<3;i++)
{
Write_Ds1302_Byte(Write_addr[i],temp[i]);
}
Write_Ds1302_Byte(0x8e,0x80);
}
复制代码
界说 Time_set[3]来存储当前Time[3],在时钟设置时对Time_set[3]举行调整,退出时钟设置时调用该函数(ds1302_write(Time_set);),将时钟设置数组写入ds1302写地点,然后读时间就从设置的时钟开始读取。
//按键处理函数switch前
key=key_scan();
if(key>0 && flag_alarm==1)
{
flag_alarm=0;
return;
}
复制代码
2.第九届省赛:彩灯控制器
(1)LED流水灯模式控制:
(2)PWM流水灯:
//**main.c
void led_pro()
{
switch(led_mode)
{
case 1:
P0=~(0x01<<i);
break;
case 2:
P0=~(0x80>>i);
break;
case 3:
P0=~(0x01<<i | 0x80>>i);
break;
case 4:
P0=~(0x10<<i | 0x08>>i);
break;
}
hc573(4);
}
//**timer.c
if(++count1==12) //调节亮度
count1=0;
if(level*3>count1)
led_pro();
else
{
P0=0xff;
hc573(4);
}
if(systick_ms>=time_set[led_mode-1]) //调节流转间隔
{
if((led_mode==1||led_mode==2)&&on_off==1)
i=(++i)%8;
else if((led_mode==3||led_mode==4)&&on_off==1)
i=(++i)%4;
systick_ms=0;
}
复制代码
3.第十一届省赛1:
(1)
(2)
//state: 0:温度界面 1:参数界面
if(state==1) //判断参数设置是否正确
{
if(temp_max>=temp_min)
flag=1;
else
flag=0;
}
if(state==0)
{
if(temp_max>=temp_min)
{
temp_set[0]=temp_max;
temp_set[1]=temp_min;
}
else //参数不合理时恢复参数设置界面前的有效参设
{
state_L4=1;
temp_max=temp_set[0];
temp_min=temp_set[1];
}
}
//错误参数设置,直到下一次参数设置正确
if(state==0 && state_L4==1 && flag==1)
state_L4=0;
复制代码
4.第十一届省赛2
(1)
写法一:
if(ADC>ADC_set || flag1==1)//下降穿过Vp计数
{
flag1=1;
if(ADC<ADC_set)
{
flag2=1;
if(flag1==1 && flag2==1)
{
flag1=flag2=0;
count1++;
}
}
}
写法二:
if(ADC>ADC_set)
{
flag1=1;
flag2=1;
}
else
flag1=0;
if(flag2==1&&flag1==0) //前一个状态大于,现在状态小于
{
flag1=flag2=0;
count1++;
}
复制代码
(2)
switch(key)
{
case 1://s13
if(state==2)
{
count1=0;
error_count=0; //按键有效清零
}
else
error_count++; //按键无效计数
break;
case 2://s17
if(state==1)
{
error_count=0; //按键有效清零
ADC_set=ADC_set-50;
if(ADC_set==-50)
ADC_set=500;
}
else
error_count++; //按键无效计数
break;
case 3://s12
state=(state+1)%3;
error_count=0; //按键有效清零
break;
case 4://s16
if(state==1)
{
error_count=0; //按键有效清零
ADC_set=ADC_set+50;
if(ADC_set==550)
ADC_set=0;
}
else
error_count++; //按键无效计数
break;
}
LED[2]=(error_count>=3) ? 1 : 0;
复制代码
5.第十二届省赛1:
界说两个变量—temp_set,temp_set_display,在按键中对temp_set_display举行参数加减调整,同时数码管显示也是temp_set_display;退出参数界面时,将temp_set_display赋值给temp_set,举行比较时使用temp_set比较。
6.第十二届省赛2:
标题同时用到了通道1和通道3的电压,可能会引起通道庞杂。
原因分析:
PCF8591每读出一次,它启动一次转换转换的结果,在下次,才能读出。
PCF8591芯片在读取电压时,每次读取都会启动一次转换过程。如果在读取一个通道后立即读取另一个通道,由于转换过程需要时间,可能会导致读取到的数据仍旧是上一个通道的数据,从而导致电压值相反。具体来说,当下令传给PCF8591举行通道转换时,如果转换过程尚未完成就读取下一个通道,寄存器中的数据仍旧是上一个通道的值,从而导致读取错误。
问题解决:
多读一次并舍弃第一次的数据
:在读取每个通道时,先读取一次并舍弃该数据,然后再读取一次并保留该数据。如许可以确保读取的是当前通道的数据。
PCF8591_Read(0x01);
ADC_channel_1=PCF8591_Read(0x01)/51.0*100;
PCF8591_Read(0x03);
ADC_channel_3=PCF8591_Read(0x03)/51.0*100;
复制代码
7.第十四届省赛:
(1)频率映射:
最好使用化简后的表达式:
// shidu=(fre-200)*80/1800.0+10;
shidu=fre*0.044+1.11;
复制代码
(2)最大值(最小值)、均匀值:
//count0是数据个数
temp_max=(temp>temp_max) ? temp : temp_max;
shidu_max=(shidu>shidu_max) ? shidu : shidu_max;
temp_aver=(temp_aver*(count0-1)+temp*10)/count0;
shidu_aver=(shidu_aver*(count0-1)+shidu*10)/count0;
复制代码
(3)由亮变暗触发收罗
void display_pro(){ if(display_dly<50) return; display_dly=0; //LED功能区...... if(flag_wsd==1) //温湿度界面 { SMG[0]=16; SMG[1]=10; SMG[2]=10; SMG[3]=temp/10; SMG[4]=temp%10; SMG[5]=11; SMG[6]=(flag_right==0) ? 17 : shidu/10; //17表示A SMG[7]=(flag_right==0) ? 17 : shidu%10; dot[6]=0; return; } //数码管功能区......void collect_pro(){ if(collect_dly<200) return; collect_dly=0; ds1302_read(); //**收罗触发 ADC=PCF8591_Read(0x01); if(ADC>51) { light=1; flag=1; } else light=0; if(light==0 && flag==1) { flag=0; //确保只触发一次收罗 flag_wsd=1; //切换温湿度界面 temp_old=temp; temp=read_temperature(); //**湿度丈量 if(fre>=200&&fre<=2000) { flag_right=1; //湿度有效标志位 shidu_old=shidu;// shidu=(fre-200)*80/1800.0+10;
shidu=fre*0.044+1.11; } else flag_right=0; if(flag_right==1) //湿度有效 { count0++; temp_max=(temp>temp_max) ? temp : temp_max; shidu_max=(shidu>shidu_max) ? shidu : shidu_max; temp_aver=(temp_aver*(count0-1)+temp*10)/count0; shidu_aver=(shidu_aver*(count0-1)+shidu*10)/count0; Time_hour=Time[2]; //记载近来一次触发时间 Time_second=Time[1]; } }}
复制代码
通过网盘分享的文件:8-15届省赛代码.zip
链接: https://pan.baidu.com/s/1pfYRKwiz-LAzecD_adsc6g 提取码: q7qj
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
欢迎光临 qidao123.com技术社区-IT企服评测·应用市场 (https://dis.qidao123.com/)
Powered by Discuz! X3.4