目录
0.比赛题目回忆
1. 底层头文件
2.底层文件
3.主函数文件
做下来感觉,主观题第15届比14届稍微简单一些,但是出其不意考了DAC
本届客观题有点难,做选择感觉把握性不大,多选比较多
万幸比赛前一天做出了第14届的题,今年的题和去年的题比较接近(可参考本专栏上一篇文章)
如果有幸进入国赛,将继续更新国赛之路专栏
0.比赛题目回忆
(请以官方的文档为准,可能回忆有误):
配置为IO模式,矩阵键盘操作S4589,短接P34和SIGNAL,
除了ds1302的时间显示界面,其余界面数值高位为0时,直接熄灭
采集555定时计数器频率,与频率参数相加后成为最终频率值,并将其中500~pf之间的频率映射到1~5V的DAC输出。(pf为超限频率)
当频率超出pf时,led2间隔0.2s闪烁。当频率为负数时,led2常亮
共有6个数码管显示界面,分别为:
- F频率采集界面,F__频率数值。该状态下led1间隔0.2s闪烁。当采集到的频率为负时,显示LL
- P1超限频率pf设置界面,默认参数2000,按下S9减少1000,按下S8增加1000,范围为1000~9000
- P2频率参数设置界面,默认参数0,按下S9减少100,按下S8增加100,范围为-900~900。其中负数时要有符号显示,为0时只显示最后一位0和提示符P2,其他位熄灭
- 时间显示界面,显示格式:时时-分分-秒秒
- HF频率回显,显示采集到的最大频率数值
- HA时间回显,显示采集到最大频率时的时间,格式为:HA时时分分秒秒
按键切换逻辑为:
按下S4,切换逻辑为:1 - 23 - 4 - 56 -1
按下S5,切换逻辑为:2 - 3 或 5 - 6
比赛结束后复现代码如下:
1. 底层头文件
iic.h
#ifndef __IIC_H__
#define __IIC_H__void I2CStart(void);
void I2CStop(void);
void I2CSendByte(unsigned char byt);
unsigned char I2CWaitAck(void);#endif
ds1302.h
#ifndef __DS1302_H__
#define __DS1302_H__void Write_Ds1302(unsigned char temp) ;
void Write_Ds1302_Byte( unsigned char address,unsigned char dat ) ;
unsigned char Read_Ds1302_Byte ( unsigned char address );#endif
basecode.h
#ifndef __BASECODE_H__
#define __BASECODE_H__void select_HC573 ( unsigned char channal );
void state_SMG ( unsigned char pos_SMG , unsigned char value_SMG );
void state_SMG_all ( unsigned char value_SMG_all );
void state_led ( unsigned char value_led );
void init_sys ();#endif
2.底层文件
iic.c
/* # I2C代码片段说明1. 本文件夹中提供的驱动代码供参赛选手完成程序设计参考。2. 参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题中对单片机时钟频率的要求,进行代码调试和修改。
*/#include <reg52.h>
#include <intrins.h>sbit sda = P2^1;
sbit scl = P2^0;#define DELAY_TIME 5//
static void I2C_Delay(unsigned char n)
{do{_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); }while(n--);
}//
void I2CStart(void)
{sda = 1;scl = 1;I2C_Delay(DELAY_TIME);sda = 0;I2C_Delay(DELAY_TIME);scl = 0;
}//
void I2CStop(void)
{sda = 0;scl = 1;I2C_Delay(DELAY_TIME);sda = 1;I2C_Delay(DELAY_TIME);
}//
void I2CSendByte(unsigned char byt)
{unsigned char i;for(i=0; i<8; i++){scl = 0;I2C_Delay(DELAY_TIME);if(byt & 0x80){sda = 1;}else{sda = 0;}I2C_Delay(DELAY_TIME);scl = 1;byt <<= 1;I2C_Delay(DELAY_TIME);}scl = 0;
}/*
unsigned char I2CReceiveByte(void)
{unsigned char da;unsigned char i;for(i=0;i<8;i++){ scl = 1;I2C_Delay(DELAY_TIME);da <<= 1;if(sda) da |= 0x01;scl = 0;I2C_Delay(DELAY_TIME);}return da;
}*/
unsigned char I2CWaitAck(void)
{unsigned char ackbit;scl = 1;I2C_Delay(DELAY_TIME);ackbit = sda; scl = 0;I2C_Delay(DELAY_TIME);return ackbit;
}/*/
void I2CSendAck(unsigned char ackbit)
{scl = 0;sda = ackbit; I2C_Delay(DELAY_TIME);scl = 1;I2C_Delay(DELAY_TIME);scl = 0; sda = 1;I2C_Delay(DELAY_TIME);
}
*/
ds1302.c
/* # DS1302代码片段说明1. 本文件夹中提供的驱动代码供参赛选手完成程序设计参考。2. 参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题中对单片机时钟频率的要求,进行代码调试和修改。
*/ //
#include <reg52.h>
#include <intrins.h>sbit SCK = P1^7;
sbit SDA = P2^3;
sbit RST = P1^3;void Write_Ds1302(unsigned char temp)
{unsigned char i;for (i=0;i<8;i++) { SCK = 0;SDA = temp&0x01;temp>>=1; SCK=1;}
} //
void Write_Ds1302_Byte( unsigned char address,unsigned char dat )
{RST=0; _nop_();SCK=0; _nop_();RST=1; _nop_(); Write_Ds1302(address); Write_Ds1302(dat); RST=0;
}//
unsigned char Read_Ds1302_Byte ( unsigned char address )
{unsigned char i,temp=0x00;RST=0; _nop_();SCK=0; _nop_();RST=1; _nop_();Write_Ds1302(address);for (i=0;i<8;i++) { SCK=0;temp>>=1; if(SDA)temp|=0x80; SCK=1;} RST=0; _nop_();SCK=0; _nop_();SCK=1; _nop_();SDA=0; _nop_();SDA=1; _nop_();return (temp);
}
basecode.c
#include <reg52.h>
#include <intrins.h>void select_HC573 ( unsigned char channal )
{switch ( channal ){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;case 0:P2 = ( P2 & 0x1f ) | 0x00;break;}
}void state_SMG ( unsigned char pos_SMG , unsigned char value_SMG )
{select_HC573 ( 0 );P0 = 0x01 << pos_SMG; select_HC573( 6 );select_HC573 ( 0 );P0 = value_SMG;select_HC573( 7 );select_HC573 ( 0 );
}void state_SMG_all ( unsigned char value_SMG_all )
{select_HC573 ( 0 );P0 = 0xff; select_HC573( 6 );select_HC573 ( 0 );P0 = value_SMG_all;select_HC573( 7 );select_HC573 ( 0 );
} void state_led ( unsigned char value_led )
{select_HC573 ( 0 );P0 = 0xff;select_HC573 ( 4 );P0 = value_led;select_HC573 ( 4 ); select_HC573 ( 0 );
}void init_sys ()
{select_HC573 ( 0 );P0 = 0xff; select_HC573 ( 4 );select_HC573 ( 0 );P0 = 0x00;select_HC573 ( 5 );select_HC573 ( 0 );}
3.主函数文件
#include <reg52.h>
#include <intrins.h>
#include "iic.h"
#include "ds1302.h"
#include "basecode.h"sfr AUXR = 0x8e;
sbit C1 = P4^4;
sbit C2 = P4^2;
sbit H1 = P3^3;
sbit H2 = P3^2;unsigned char code duanma[20] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xc0,0x86,0x8e,0xbf,0xc7,0x89,0x8c};
unsigned char code Write_address [7] = { 0x80 , 0x82 , 0x84 , 0x86 , 0x88 , 0x8a , 0x8c};
unsigned char code Read_address [7] = { 0x81 , 0x83 , 0x85 , 0x87 , 0x89 , 0x8b , 0x8d };//2022year 3month 31day 5 23 59 50
unsigned char date_ds1302 [7] = { 0x05 , 0x03 , 0x13 , 0x13 , 0x02 , 0x06 , 0x24 };unsigned int max_fre = 0;
int set_fre = 0;
int pf = 2000;
unsigned int value_dac = 0;
unsigned char max_fre_time_hour = 0x00;
unsigned char max_fre_time_min = 0x00;
unsigned char max_fre_time_second = 0x00;
unsigned char SMG_flag = 1;
unsigned char value_led = 0xff;
bit flash_dac = 0;void flash_SMG ();
void flash_date ();
void valuerunning ();
void keyrunning ();void dacrunning ( unsigned char value_dac )
{if ( flash_dac == 1 ){I2CStart();I2CSendByte( 0x90 );I2CWaitAck();I2CSendByte( 0x43 );I2CWaitAck();I2CSendByte( value_dac );I2CWaitAck();I2CStop();}
}void init_ds1302 ()
{unsigned char i;Write_Ds1302_Byte ( 0x8e , 0x00 );for ( i=0 ; i<7 ; i++ ){Write_Ds1302_Byte ( Write_address[i] , date_ds1302[i] );}Write_Ds1302_Byte ( 0x8e , 0x80 );}bit flash_ds1302 = 0;
void flash_date()
{if ( flash_ds1302 == 1 ){unsigned char i;for ( i=0 ; i<7 ; i++ ){date_ds1302[i] = Read_Ds1302_Byte ( Read_address[i] );}flash_ds1302 = 0;}
}//==============================================================================
void init_timer01 ()
{AUXR &= 0xBF; //定时器时钟12T模式TMOD = 0x06; //设置定时器模式TL1 = 0xCE; //设置定时初值TH1 = 0xFF; //设置定时初值TF1 = 0; //清除TF1标志TR1 = 1; //定时器1开始计时TL0 = 0xFF; //设置定时初值TH0 = 0xFF; //设置定时初值TF0 = 0; //清除TF0标志TR0 = 1; //定时器0开始计时EA = 1;ET0 = 1;ET1 = 1;
}unsigned int count_timer0 = 0;
void timer0_service () interrupt 1
{ count_timer0 ++;
}
//=============================================================================bit flag_200ms = 0;
int count_fre = 0;
unsigned char count_50us = 0;
unsigned char count_5ms = 0;
unsigned char flash_count = 0;
unsigned char date_hour;
unsigned char date_min;
unsigned char date_second;
void timer1_service () interrupt 3
{if ( ++count_50us == 200 ){count_50us = 0;}if ( count_50us % 40 == 0 ) {if ( SMG_flag == 1 )//窗口1{if ( ++flash_count > 6 ){flash_count = 0;}}else if ( SMG_flag == 2 )//窗口2{if ( ++flash_count > 6 ){flash_count = 0;}}else if ( SMG_flag == 3 )//窗口3{if ( ++flash_count == 9 ){flash_count = 0;}}else if ( SMG_flag == 4 )//窗口4{if ( ++flash_count > 7 ){flash_count = 0;}}else if ( SMG_flag == 5 )//窗口5{if ( ++flash_count == 9 ){flash_count = 0;}}else if ( SMG_flag == 6 )//窗口6{if ( ++flash_count > 7 ){flash_count = 0;}}else if ( SMG_flag == 7 )//测试窗口7{if ( ++flash_count > 7 ){flash_count = 0;}}flash_SMG (); }if ( count_50us % 100 == 0 ){count_5ms++;flash_dac = 1; if ( count_5ms == 200 ){count_5ms = 0;count_fre = count_timer0 + set_fre;count_timer0 = 0;date_hour = date_ds1302[2]; date_min = date_ds1302[1];date_second = date_ds1302[0]; }if ( count_5ms % 40 == 0 ){flag_200ms = ~flag_200ms;} }if ( count_50us % 40 == 0 ){state_led ( value_led );flash_ds1302 = 1;}}void valuerunning ()
{unsigned int tmp_value_dac = 0;float pf_sub = pf - 500;if ( count_fre > max_fre && count_fre > 0 ){max_fre = count_fre;max_fre_time_hour = date_ds1302[2];max_fre_time_min = date_ds1302[1];max_fre_time_second = date_ds1302[0];}if ( count_fre < 0 ){tmp_value_dac = 0;value_led &= 0xfd;}else{value_led |= 0x02;if ( count_fre < 500 ){tmp_value_dac = 52;}else if ( count_fre < pf ){pf_sub = 204.0/pf_sub;tmp_value_dac = count_fre*pf_sub;if ( tmp_value_dac >= 255 )//5V{tmp_value_dac = 255;}else if ( tmp_value_dac < 50 && tmp_value_dac != 0 )//1V{tmp_value_dac = 52;} }else{ tmp_value_dac = 255;}}value_dac = tmp_value_dac;if ( flag_200ms == 0 && SMG_flag == 1 ){value_led &= 0xfe;}else{value_led |= 0x01; }if ( count_fre > pf ){if ( flag_200ms == 0 ){value_led &= 0xfd;}else{value_led |= 0x02;}}
}void Delay4ms() //@12.000MHz
{unsigned char i, j;i = 47;j = 174;do{while (--j);} while (--i);
}void keyrunning ()
{C1 = 0;C2 = H1 = H2 = 1;if ( H1 == 0 ){Delay4ms();if ( H1 == 0 )//S4{switch ( SMG_flag ){case 1:SMG_flag = 2;break;case 2:case 3:SMG_flag = 4;break;case 4:SMG_flag = 5;break;case 5:case 6:SMG_flag = 1;break;}while ( H1 == 0 );}}else if ( H2 == 0 ){Delay4ms();if ( H2 == 0 )//S5{switch ( SMG_flag ){case 2:SMG_flag = 3;break;case 3:SMG_flag = 2;break;case 5:SMG_flag = 6;break;case 6:SMG_flag = 5;break;} while ( H2 == 0 ); }}C2 = 0;C1 = H1 = H2 = 1;if ( H1 == 0 ){Delay4ms();if ( H1 == 0 )//S8{if ( SMG_flag == 2 ){pf += 1000;if ( pf == 10000 ){pf = 9000;}}else if ( SMG_flag == 3 ){set_fre += 100;if ( set_fre == 1000 ){set_fre = 900;}} while ( H1 == 0 );}}else if ( H2 == 0 ){Delay4ms();if ( H2 == 0 )//S9{if ( SMG_flag == 2 ){pf -= 1000;if ( pf == 0 ){pf = 1000;}}else if ( SMG_flag == 3 ){set_fre -= 100;if ( set_fre == -1000 ){set_fre = -900;}} while ( H2 == 0 ); }}
} void flash_SMG ()
{state_SMG_all ( 0xff );if ( SMG_flag == 1 ){switch ( flash_count ){case 0 : state_SMG ( 0 , duanma[15] );break;case 1 :if ( count_fre > 9999 ){state_SMG ( 3 , duanma[count_fre/10000] );}else{state_SMG ( 3 , 0xff );}break;case 2 :if ( count_fre > 999 ){ state_SMG ( 4 , duanma[count_fre/1000%10] );}else{state_SMG ( 4 , 0xff );}break;case 3 :if ( count_fre > 99 ){ state_SMG ( 5 , duanma[count_fre/100%10] );}else{state_SMG ( 5 , 0xff );}break;case 4 :if ( count_fre > 0 ){if ( count_fre > 9 ){state_SMG ( 6 , duanma[count_fre/10%10] );}else{state_SMG ( 6 , 0xff );}}else{state_SMG ( 6 , duanma[17] );}break;case 5 :if ( count_fre > 0 ){state_SMG ( 7 , duanma[count_fre%10] );}else{state_SMG ( 7 , duanma[17] );}break;case 6 : state_SMG_all ( 0xff );break;}}else if ( SMG_flag == 2 ){switch ( flash_count ){case 0 : state_SMG ( 0 , duanma[19] );break;case 1 :state_SMG ( 1 , duanma[1] );break;case 2 : state_SMG ( 4 , duanma[pf/1000] );break;case 3 : state_SMG ( 5 , duanma[0] );break;case 4 :state_SMG ( 6 , duanma[0] );break;case 5 : state_SMG ( 7 , duanma[0] );break;case 6 : state_SMG_all ( 0xff );break;}} else if ( SMG_flag == 3 ){switch ( flash_count ){case 0 : state_SMG ( 0 , duanma[19] );break;case 1 :state_SMG ( 1 , duanma[2] );break;case 2 :if ( set_fre < 0 ){ state_SMG ( 4 , duanma[16] );}else{state_SMG ( 4 , 0xff );}break;case 3 :if ( set_fre != 0 ){if ( set_fre < 0 ){ state_SMG ( 5 , duanma[set_fre*-1/100] );}else{state_SMG ( 5 , duanma[set_fre/100] );}}else{state_SMG ( 5 , 0xff );}break;case 4 :if ( set_fre != 0 ){ state_SMG ( 6 , duanma[0] );}else{state_SMG ( 6 , 0xff );}break;case 5 : state_SMG ( 7 , duanma[0] );break;case 6 : state_SMG_all ( 0xff );break;}}else if ( SMG_flag == 4 ){switch ( flash_count ){case 0 : state_SMG ( 0 , duanma[date_hour/16] );break;case 1 : state_SMG ( 1 , duanma[date_hour%16] );break;case 2 : state_SMG ( 2 , duanma[16] );break;case 3 : state_SMG ( 3 , duanma[date_min/16] );break;case 4 : state_SMG ( 4 , duanma[date_min%16] );break;case 5 : state_SMG ( 5 , duanma[16] );break;case 6 : state_SMG ( 6 , duanma[date_second/16] );break;case 7 : state_SMG ( 7 , duanma[date_second%16] );break;case 8 : state_SMG_all ( 0xff );break;}}else if ( SMG_flag == 5 ){switch ( flash_count ){case 0 : state_SMG ( 0 , duanma[18] );break;case 1 :state_SMG ( 1 , duanma[15] );break;case 2 :if ( max_fre > 9999 ){ state_SMG ( 3 , duanma[max_fre/10000%10] );}else{state_SMG ( 3 , 0xff );}break;case 3 :if ( max_fre > 999 ){ state_SMG ( 4 , duanma[max_fre/1000%10] );}else{state_SMG ( 4 , 0xff );}break;case 4 :if ( max_fre > 99 ){ state_SMG ( 5 , duanma[max_fre/100%10] );}else{state_SMG ( 5 , 0xff );}break;case 5 :if ( max_fre > 9 ){ state_SMG ( 6 , duanma[max_fre/10%10] );}else{state_SMG ( 6 , 0xff );}break;case 6 : state_SMG ( 7 , duanma[max_fre%10] );break;case 7 : state_SMG_all ( 0xff );break;}}else if ( SMG_flag == 6 ){switch ( flash_count ){case 0 : state_SMG ( 0 , duanma[18] );break;case 1 :state_SMG ( 1 , duanma[10] );break;case 2 :state_SMG ( 2 , duanma[max_fre_time_hour/16] );break;case 3 :state_SMG ( 3 , duanma[max_fre_time_hour%16] );break;case 4 :state_SMG ( 4 , duanma[max_fre_time_min/16] );break;case 5 :state_SMG ( 5 , duanma[max_fre_time_min%16] );break;case 6 :state_SMG ( 6 , duanma[max_fre_time_second/16] );break;case 7 :state_SMG ( 7 , duanma[max_fre_time_second%16] );break; case 8 : state_SMG_all ( 0xff );break;}}else if ( SMG_flag == 7 ){switch ( flash_count ){case 0 : state_SMG ( 0 , duanma[count_fre/1000%10] );break;case 1 :state_SMG ( 1 , duanma[count_fre/100%10] );break;case 2 : state_SMG ( 2 , duanma[count_fre/10%10] );break;case 3 : state_SMG ( 3 , duanma[count_fre%10] );break;case 4 : state_SMG ( 5 , duanma[value_dac*100/51/100] );break;case 5 : state_SMG ( 6 , duanma[value_dac*100/551/10%10] );break;case 6 : state_SMG ( 7 , duanma[value_dac*100/51%10] );break;case 7 : state_SMG_all ( 0xff );break;}}
}void main ()
{init_sys();init_timer01 ();init_ds1302 ();while ( 1 ){ flash_date ();valuerunning ();dacrunning ( value_dac );keyrunning ();}
}