蓝桥杯第九届单片机国赛真题(CT107D——IAP15F2K61S2)

文章目录

  • 前言
  • 一、代码相关定义、声明
    • 1.头文件声明
    • 2.变量声明
    • 3.函数声明
  • 二、主要函数
    • 1.main函数
    • 2.按键扫描
    • 3.数码管显示
    • 4.LED指示功能
    • 5.定时器中断
    • 6.消除85°C显示


前言

相关说明:

开发板:CT107D (IAP15F2K61S2)
开发环境:Keil5
涉及题目:第九届蓝桥杯单片机国赛真题
在这里插入图片描述


主要函数代码及说明:

一、代码相关定义、声明

1.头文件声明

#include "stdio.h"
#include "Timer.h"
#include "bsp_init.h"
#include "bsp_key.h"
#include "bsp_seg.h"
#include "bsp_led.h"
#include "bsp_onewire.h"
#include "bsp_iic.h"
#include "bsp_555_PWM_Freq.h"

2.变量声明

//--定时器滴答变量
unsigned long ms_Tick = 0;

//--定时器滴答变量
xdata unsigned long ms_Tick = 0;
xdata unsigned long ms_Tick_LED_Liang = 0;
xdata unsigned long ms_Tick_LED_An = 0;

//--定时器减速变量
unsigned int Key_Slow_Down;
unsigned int Seg_Slow_Down;
unsigned int Led_Slow_Down;

//--按键专用变量
unsigned char Key_Value;
unsigned char Key_Old, Key_Down;

//--数码管专用变量
unsigned char seg_string[10];
unsigned char seg_buf[8] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
unsigned char pos;

//--LED专用变量
unsigned char ucLed = 0x00;
unsigned char Voltage_Shit;//电压的待处理原始数值
unsigned int Temp_Shit;//温度的待处理原始数值
unsigned int freq_Storage;
unsigned char Voltage_Shit_Storage;//电压的待处理原始数值
unsigned int Temp_Shit_Storage;//温度的待处理原始数值
unsigned char eeprom_string[5] = {0};
unsigned int freq;

bit state_flag = 0;//测试模板好坏需要用的一个变量

unsigned char Interface_Flag = 0;//界面标志,0-数据显示,1-数据回显,2-阈值界面
unsigned char UFC_Trans_Interface_Flag = 0;//界面标志,0-电压显示,1-频率回显,2-温度界面

unsigned char Compare_Value = 30;//阈值内容,数据实际是在0.1-5.0之间,我们存储为*10之后的数据,1-50之间。

3.函数声明

void Key_Proc(void);
void Seg_Proc(void);
void Led_Proc(void);
void Delay750ms();		//@12.000MHz

二、主要函数

1.main函数

void main(void)
{

	Cls_Peripheral();//关闭LED/继电器/蜂鸣器
	Timer1Init();//定时器1初始化
	EA = 1;//打开总中断
	EEPROM_Read(&Compare_Value, 5, 1);//更新阈值
	PWM_555_Freq_Timer0Init();	//配置成了计数器模式,不自动重装
	Pcf8591_Adc(Adj_Res_Channel);//直接读取的AD数值
	rd_temperature();
	Delay750ms();//用于消除上电显示85°C的影响
	while(1)
	{
		Key_Proc();
		Seg_Proc();
		Led_Proc();
	}
}

2.按键扫描

void	Key_Proc(void)
{
	if(Key_Slow_Down) return;
	Key_Slow_Down = 1;
	
	//三行代码
	Key_Value = Key_Read();
	Key_Down = Key_Value & (Key_Old ^ Key_Value);//下降沿,按得哪个按键,这个值就是几
	Key_Old = Key_Value;//检测电平,一直按着一直等于一个数

	switch(Key_Down)//这个结构很常见,判别是哪个按键按下去了,根据按键按下的情况,控制内部数据变量的变化
	{
		case 4://切换按键
				if((Interface_Flag == 0)||((Interface_Flag == 1)))//如果是数据显示界面/数据回显界面
				{
					if(++UFC_Trans_Interface_Flag == 3) UFC_Trans_Interface_Flag = 0;//完成0-2的转换
				}
				break;//这个break很重要
		
		
		case 5://存储按键	
				eeprom_string[0] = Voltage_Shit;//用于存储0-255的电压数值
				eeprom_string[1] = freq>>8;//用于存储频率原始数值,高8位
				eeprom_string[2] = freq&0x00ff;//用于存储频率原始数值,低8位
				eeprom_string[3] = Temp_Shit>>8;//用于存温度原始数值,高8位
				eeprom_string[4] = Temp_Shit&0x00ff;//用于存储温度原始数值,低8位
				EEPROM_Write(eeprom_string, 0, 5);	
				break;//这个break很重要		
		
		case 7://设置按键
					if(Interface_Flag != 2)//如果之前不是阈值界面
						Interface_Flag = 2;//强制进入阈值界面
					else//如果从阈值界面跳出 
					{
						Interface_Flag = 0;//强制进入数据显示界面		
						EEPROM_Write(&Compare_Value, 5, 1);						
					}						
				break;//这个break很重要	
	}
	
	
	if(Key_Down == 6)//表示6号按键已经按下去了
	{
		S6_Key_ms_Tick = ms_Tick;//记录当前的滴答值
	}
	
	if((ms_Tick - S6_Key_ms_Tick)< 800)//小于800ms,等待上升沿产生
	{
		if(Key_Up == 6)//如果产生上升沿,表示短按释放
		{
			if(Interface_Flag == 0)//如果当前是数据界面,强制进入回显界面	
			{
				Interface_Flag = 1;
				EEPROM_Read(eeprom_string, 0, 5);
				Voltage_Shit_Storage = eeprom_string[0];
				freq_Storage = (eeprom_string[1]<<8)|eeprom_string[2];
				Temp_Shit_Storage = (eeprom_string[3]<<8)|eeprom_string[4];	
			}
			else if(Interface_Flag == 2)//如果当前是阈值界面
			{
				Compare_Value++;
				if(Compare_Value == 51)
					Compare_Value = 1;
			}	
		}
	}
	else//如果时长大于800ms,并没有产生上升沿,表示长按了
	{
		if(Key_Old == 6)//表示还在按压着
		{
			Compare_Value++;
			if(Compare_Value == 51)
				Compare_Value = 1;
		}
	}
}

3.数码管显示

void Seg_Proc(void)
{
	if(Seg_Slow_Down) return;
	Seg_Slow_Down = 1;
	
	Voltage_Shit = Pcf8591_Adc(Adj_Res_Channel);//直接读取的AD数值
	Temp_Shit = rd_temperature();//温度数据的原始数值
	
	switch(Interface_Flag)
	{
		case 0://0-数据显示
			switch(UFC_Trans_Interface_Flag)
			{
				case 0://0-电压显示
					sprintf(seg_string,"U     %3.1f",(Voltage_Shit/51.0));				
				break;				
				case 1://1-频率显示
					sprintf(seg_string,"F %6d",freq);	
				break;	
				case 2://2-温度显示
					sprintf(seg_string,"C   %5.2f",(Temp_Shit/16.0));
				break;	
			}					
		break;
	
		case 1://1-数据回显
			switch(UFC_Trans_Interface_Flag)
			{
				case 0://0-电压显示
					sprintf(seg_string,"HU    %3.1f",(Voltage_Shit_Storage/51.0));								
				break;				
				case 1://1-频率回显
					sprintf(seg_string,"HF%6d",freq_Storage);					
				break;	
				case 2://2-温度界面
					sprintf(seg_string,"HC  %5.2f",(Temp_Shit_Storage/16.0));				
				break;	
			}			
		break;	

		case 2://2-阈值界面
			sprintf(seg_string,"P     %3.1f",(Compare_Value*0.1));		
		break;
	}
	
	Seg_Tran(seg_string, seg_buf);
}

4.LED指示功能

void	Led_Proc(void)
{
	if(Led_Slow_Down) return;
	Led_Slow_Down = 1;
		
 	if(Interface_Flag == 0)//只有数据显示界面的时候
	{
		switch(UFC_Trans_Interface_Flag)
		{
			case 0://L3点亮
				ucLed &= (~0x07);
				ucLed |= (0x04);
			break;
			
			case 1://L2点亮
				ucLed &= (~0x07);
				ucLed |= (0x02);				
			break;
						
			case 2://L1点亮
				ucLed &= (~0x07);
				ucLed |= (0x01);					
			break;
		}
	}
	else//如果不是数据显示界面,低3位熄灭
	{
		ucLed &= (~0x07);
	}

	if((Voltage_Shit/51.0) > (Compare_Value*0.1))//让L8闪烁
	{
		if((ms_Tick - L8_ms_Tick)>=200)	
		{
			L8_ms_Tick = ms_Tick;
			ucLed ^= 0x80;
		}
	}
	else//如果采集的电压值,比阈值要小,熄灭
		ucLed &= (~0x80);				
}

5.定时器中断

void tm1_isr() interrupt 3
{
	ms_Tick++;//滴答定时器,能记录的数据长达29天

	if(++Key_Slow_Down == 10) Key_Slow_Down = 0;//减速变量区,控制子函数的刷新频率
	if(++Seg_Slow_Down == 500) Seg_Slow_Down = 0;	
	if(++Led_Slow_Down == 100) Led_Slow_Down = 0;	
	
	if((ms_Tick%1000) == 0)
	{
 		freq = ((TH0<<8)|TL0);
 		TH0 = 0;
 		TL0 = 0;
	}
	
    Seg_Disp(seg_buf, pos);//用于数码管显示
	if(++pos == 8) pos = 0;
	
	Led_Disp(ucLed);//用于LED显示
}

6.消除85°C显示

void Delay750ms()		//@12.000MHz  用来消除85°C显示
{
	unsigned char i, j, k;

	_nop_();
	_nop_();
	i = 35;
	j = 51;
	k = 182;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

你可能感兴趣的:(蓝桥杯真题,单片机,蓝桥杯,c语言,51单片机)