目录
[1. 底层头文件](#1. 底层头文件)
做下来感觉,主观题第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
cpp
#ifndef __IIC_H__
#define __IIC_H__
void I2CStart(void);
void I2CStop(void);
void I2CSendByte(unsigned char byt);
unsigned char I2CWaitAck(void);
#endif
ds1302.h
cpp
#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
cpp
#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
cpp
/* # 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
cpp
/* # 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
cpp
#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.主函数文件
cpp
#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 ();
}
}