第一次参加蓝桥杯,线上比赛,记录一下
比赛刚开始了十分钟才做上客观题,做上了之后才发现看一次题警告一次,当时就蚌埠住了,随便做了做就交了,手册也没怎么查(查一下直接给了3次黄牌,就没敢查了)其实老师10点的时候说这个没影响了,但是当时腾讯会议监考老师说话噪声很大,也没听清
最后开考40分钟才做完客观题(其实大部分都不会,都是蒙的,真想不到当时咋做半小时的),收到30个黄牌警告,刚才对答案好像就对了三四个选择,哎~
不过还好这次程序题占比大一点,写的也比较顺利,中间基本没有卡,花了近三小时写完的
客观题答案解析https://mp.weixin.qq.com/s/IAe9PAHb5-BMee2uIpdAeg
//代码是十三届蓝桥杯单片机组省赛比赛的时候写的,当时验证的要求都实现了,也许还有一些没发现的BUG,欢迎指出哦,比赛给的ONEWIRE函数要改一下时序和声名,DS1302直接不变
#include <STC15F2K60S2.H>
#include <DS1302.H>
#include <ONEWIRE.H>
bit flag=0,X1,Y1,X2,Y2,X3,Y3,X4,Y4,RELAY,RELAY1,MODE1=0,L1,L3;
unsigned char KEY,flag_k,MODE,VALUE=23,LED_COUNT;
unsigned int Temper,COUNT;
unsigned char code Nixie[23]={0xC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0XBF,0XFF
,0X40,0X79,0X24,0X30,0X19,0X12,0X02,0X78,0X00,0XBF,0XC1};
//数码管段码值,按顺序分别是0~9,分隔符,全灭,带小数点0~9,字母U
unsigned char Nixie_Buffer[8]={11,11,11,11,11,11,11,11};
//数码管显示值缓存数组,第0~8位对应数码管0~8位
unsigned char DS1302_Buffer[7]={0X30,0X25,0X23,0X09,0X04,0X06,0X22};
//DS1302时间值存储数组
void Delay500ms() //@12.000MHz
{
unsigned char i, j, k;
_nop_();
_nop_();
i = 23;
j = 205;
k = 120;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void HL138(unsigned char channel){
switch(channel){
case 4:P2=(P2&0X1F)|0X80;break;
case 5:P2=(P2&0X1F)|0XA0;break;
case 6:P2=(P2&0X1F)|0XC0;break;
case 7:P2=(P2&0X1F)|0XE0;break;
}
P2=P2&0X1F;
}//锁存器选择函数
void Nixie_change(unsigned char d1,d2,d3,d4,d5,d6,d7,d8){
Nixie_Buffer[0]=d1;
Nixie_Buffer[1]=d2;
Nixie_Buffer[2]=d3;
Nixie_Buffer[3]=d4;
Nixie_Buffer[4]=d5;
Nixie_Buffer[5]=d6;
Nixie_Buffer[6]=d7;
Nixie_Buffer[7]=d8;
}
//数码管缓存数组值改写函数
void Nixie_scan(){
unsigned char number;
P0=0XFF;HL138(7);
P0=0X01<<number;HL138(6);
P0=Nixie[Nixie_Buffer[number]];HL138(7);
if(++number==8)number=0;
//定时扫描数码管,读出数码管缓存数组对应的段码值
P0=0XFF;
//清空P0寄存器中的值
if(MODE1==0){
if(RELAY==1){
P0=P0&0X10;
}
else{
P0=P0&0X00;
}
RELAY1=0;
}
else{
if(RELAY1==1){
P0=P0&0X10;
}
else{
P0=P0&0X00;
}
}
//定时扫描继电器,和同样使用锁存器的数码管放在同一个函数中,防止数码管鬼影
if(P0==0X10){
L3=1;
}
else{
L3=0;
}
//判断继电器是否吸合,决定L3灯状态
HL138(5);
P0=0XFF;
if(MODE1==0){
P0=P0&0XFE;
}
if(L1==1){
P0=P0&0XFD;
}
else{
P0=P0|0X02;
}
if(L3==1){
LED_COUNT++;
LED_COUNT%=50;
if(LED_COUNT==25){
P0=P0&0XFB;
}
if(LED_COUNT==0){
P0=P0|0X40;
}
}
else{
LED_COUNT=0;
}
HL138(4);
//LED状态判断函数,定时扫描
}
void Key_scan(){
if(flag_k==9){
P34=1;P35=0;
P32=P33=1;
if(P32==0){X1=1,Y1=0;}
//如果第一次扫描为P32按下
if(P33==0){X2=1,Y2=0;}
if(P32==1){Y1=1;}
//如果20ms后再次进入p32松手
if(P33==1){Y2=1;}
if(X1==1&&Y1==1){KEY=13;X1=0;Y1=0;}
//判断是否是按键按下的松手动作
if(X2==1&&Y2==1){KEY=12;X2=0;Y2=0;}
//扫描S13,S12两个键
P34=0;P35=1;
P32=P33=1;
if(P32==0){X3=1,Y3=0;}
if(P33==0){X4=1,Y4=0;}
if(P32==1){Y3=1;}
if(P33==1){Y4=1;}
if(X3==1&&Y3==1){KEY=17;X3=0;Y3=0;}
if(X4==1&&Y4==1){KEY=16;X4=0;Y4=0;}
}
}
//按键扫描函数,20ms进入一次,通过20ms时间间隔代替消抖
void DS18B20_READ(){
unsigned char MSB,LSB;
init_ds18b20();
Write_DS18B20(0XCC);
Write_DS18B20(0X44);
init_ds18b20();
Write_DS18B20(0XCC);
Write_DS18B20(0XBE);
LSB=Read_DS18B20();
MSB=Read_DS18B20();
Temper=MSB;
Temper=(Temper<<8)|LSB;
Temper=(Temper/16.0)*10;
//除16.0是为了将数据右移四位并且转换为float类型数据运算(可保留小数位),乘以10是为了放大10倍保证转换成int变量后小数后一位不丢失,同理,乘以100可放大100倍相当于保留两位小数数据
}
//DS18B20的读取函数
void DS1302_W(){
unsigned char i,addr=0x80;
Write_Ds1302_Byte(0x8e,0x00);
for(i=0;i<7;i++){
Write_Ds1302_Byte(addr,DS1302_Buffer[i]);
addr+=2;
}
Write_Ds1302_Byte(0x8e,0x80);
}
//DS1302写函数
void DS1302_R(){
unsigned char i,addr=0x81;
for(i=0;i<7;i++){
DS1302_Buffer[i]=Read_Ds1302_Byte(addr);
addr+=2;
}
}
//DS1302读函数
void Timer0Init(void)
{
AUXR |= 0x80;
TMOD &= 0xF0;
TL0 = 0X40;
TH0 = 0XA2;
TF0 = 0;
TR0 = 1;
EA=1;
ET0=1;
}
//定时器配置,2ms溢出一次
void main(){
DS18B20_READ();
DS1302_W();
Delay500ms();
Timer0Init();
P0=0XFF;HL138(4);
P0=0X00;HL138(5);
P0=0XFF;HL138(6);
P0=0XFF;HL138(7);
//初始化
while(1){
if(KEY==12){
MODE++;
MODE%=3;
KEY=0;
}
//按下S12,切换显示界面
if(flag==1){
if(flag_k==9){
DS18B20_READ();
DS1302_R();
}
//每20ms读取一次温度和时间
if((DS1302_Buffer[0]==0)&&(DS1302_Buffer[1]==0)){
L1=1;
}
//整点时,L1灯标志位置1,上方的LED扫描函数中点亮L1的条件达成
if((DS1302_Buffer[0]/16==0)&&(DS1302_Buffer[0]%16==5)&&(DS1302_Buffer[1]==0))
{
L1=0;
}
//00分05秒时,熄灭L1
if(MODE==0){
Nixie_change(22,1,11,11,11,Temper/100,Temper%100/10+12,Temper%10);
}
//显示温度值的界面
if(MODE==1){
if(X3==1&&Y3==0){
Nixie_change(22,2,11,DS1302_Buffer[1]/16,DS1302_Buffer[1]&0X0F,21,DS1302_Buffer[0]/16,DS1302_Buffer[0]&0X0F);
while(X3==1&&Y3==0);
}
//界面2时,S17正在按下时,显示分秒
else {
if(KEY==17){
KEY=0;
if(VALUE==10){
VALUE=100;
}
VALUE--;
} Nixie_change(22,2,11,DS1302_Buffer[2]/16,DS1302_Buffer[2]&0X0F,21,DS1302_Buffer[1]/16,DS1302_Buffer[1]&0X0F);
//松开S17后,温度参数减一,显示时分界面
}
}
if(MODE==2){
if(KEY==16){
KEY=0;
if(VALUE==99){
VALUE=9;
}
VALUE++;
}
if(KEY==17){
KEY=0;
if(VALUE==10){
VALUE=100;
}
VALUE--;
}
Nixie_change(22,3,11,11,11,11,VALUE/10,VALUE%10);
//温度参数设置界面 }
if(KEY==13){
KEY=0;
MODE1=!MODE1;
}
//S13按键切换温度控制模式和时间控制模式
if(MODE1==0){
if(Temper/10>=VALUE){
RELAY=1;
}
else if(Temper/10<VALUE){
RELAY=0;
}
}
//温度控制模式
if(MODE1==1){
if((DS1302_Buffer[0]==0)&&(DS1302_Buffer[1]==0)){
RELAY1=1;
}
if((DS1302_Buffer[0]/16==0)&&(DS1302_Buffer[0]%16==5)&&(DS1302_Buffer[1]==0))
{
RELAY1=0;
}
}
//时间控制模式
flag=0;
}
}
}
void Timer0Init_service() interrupt 1{
Nixie_scan();
flag=1;
flag_k++;
flag_k%=10;
Key_scan();
}
//定时扫描函数,数码管2ms一次,按键20ms一次