蓝桥杯-单片机组基础21——第15届省赛代码

embedded/2024/10/18 3:35:56/

目录

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个数码管显示界面,分别为:

  1. F频率采集界面,F__频率数值。该状态下led1间隔0.2s闪烁。当采集到的频率为负时,显示LL
  2. P1超限频率pf设置界面,默认参数2000,按下S9减少1000,按下S8增加1000,范围为1000~9000
  3. P2频率参数设置界面,默认参数0,按下S9减少100,按下S8增加100,范围为-900~900。其中负数时要有符号显示,为0时只显示最后一位0和提示符P2,其他位熄灭
  4. 时间显示界面,显示格式:时时-分分-秒秒
  5. HF频率回显,显示采集到的最大频率数值
  6. 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 ();}
}


http://www.ppmy.cn/embedded/4040.html

相关文章

03-JAVA设计模式-中介者模式

中介者模式 什么是中介者模式 中介者模式&#xff08;Mediator Pattern&#xff09;是一种行为设计模式&#xff0c;用于减少对象之间的直接依赖关系&#xff0c;降低它们之间的耦合度&#xff0c;并使得一个对象改变时&#xff0c;所有依赖于它的对象都得到通知并自动更新。…

设计模式:中介者模式代码案例

文章目录 示例1示例代码 示例2示例代码 示例1 一个智能家居控制系统。在这个系统中&#xff0c;我们有多个设备&#xff0c;如灯光、窗帘、空调等&#xff0c;它们之间需要相互协作以达到智能控制的目的。例如&#xff0c;当我们说“晚安”时&#xff0c;系统需要关闭灯光、拉…

Ubuntu的用户、组、权限(ACL)管理

目录 用户创建用户删除用户查看(非系统)用户 组查看所有组创建组删除组改变用户所在组从组中移除用户将用户追加到其他组 id查看用户以及所属组名字和id查看用户id查看所属组查看所属组id查看所属组名字 查看有效用户组(主组)查看有效用户组(主组)id查看有效用户组(主族)名字 权…

力扣HOT100 - 142. 环形链表 II

解题思路&#xff1a; public class Solution {public ListNode detectCycle(ListNode head) {Set<ListNode> set new HashSet<>();while (head ! null) {if (!set.add(head)) {return head;}head head.next;}return null;} }

安全特低电压 SELV(Safety Extra Low Voltage,缩写SELV) 是不接地系统的安全特低电压

SELV LED驱动器 市场上有很多LED灯是非隔离的&#xff0c;甚至还有灯条要100多伏特电压才能点亮的&#xff0c;安全吗&#xff1f; 国外多数LED驱动器标注了SELV&#xff0c;为什么&#xff1f; 安全特低电压 SELV(Safety Extra Low Voltage&#xff0c;缩写SELV) 是不接地系…

基于YOLOv5s的电动车入梯识别系统(数据集+权重+登录界面+GUI界面+mysql)

目录 1.UI界面 2.注册登录 3.算法准确率 4.数据集 1.UI界面 本人训练的yolov5s模型&#xff0c;准确率在98.6%左右&#xff0c;可准确完成电梯内检测电动车任务&#xff0c;并搭配了GUI检测界面&#xff0c;支持权重选择、图片检测、视频检测、摄像头检测、识别结果拍照…

基于springboot的工程教育认证的计算机课程管理平台源码数据库

基于springboot的工程教育认证的计算机课程管理平台源码数据库 摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了基于工程教育认证的计算机课程管理平台的开发全过程。通过分析基于工程教育认证的计算机课程管…

Dockeri不运行容器或容器启动不起来,但需要进入容器内执行命令或修改文件

废话不多说&#xff0c;看我这个文章就能解决问题&#xff1a; 1.先删除容器 2.执行命令 docker run --rm -it --entrypoint/bin/bash 镜像名称 例如&#xff1a;进入mysql镜像 docker run --rm -it --entrypoint/bin/bash mysql:last