发布时间:2024-02-05 18:30
相关说明:
开发板:CT107D (IAP15F2K61S2)
开发环境:Keil5
涉及题目:第十一届蓝桥杯单片机国赛真题
主要函数代码及说明:
#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_ds1302.h\"
//--定时器滴答变量
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;
//00-数据界面时间显示;01-数据界面温度显示;02-数据界面亮暗状态显示;
//10-参数界面时间显示;11-参数界面温度显示;12-参数界面指示灯显示
unsigned char Disp_Flag = 0x00;
unsigned char Hour_P = 17;//小时参数,00-23
unsigned char Temp_P = 25;//温度参数,00-99
unsigned char LED_P = 4;//指示灯参数,4-8
unsigned char Hour_P_Ctrl = 17;//起作用-小时参数,00-23
unsigned char Temp_P_Ctrl = 25;//起作用-温度参数,00-99
unsigned char LED_P_Ctrl = 4;//起作用-指示灯参数,4-8
float Temp_Num;//测量的温度数据
float Photo_R_Voltage_Num;//光敏电阻电压数值
bit Liang_An_Flag;//0-亮,1-暗
bit Liang_An_Flag_Over_3_Sec;//亮暗超过3秒标志
bit Liang_First_Time;//是否第一次触发亮三秒标志
bit An_First_Time;//是否第一次触发暗三秒标志
void Key_Proc(void);
void Seg_Proc(void);
void Led_Proc(void);
void Delay750ms(); //@12.000MHz
void main(void)
{
Cls_Peripheral();//关闭LED/继电器/蜂鸣器
Timer1Init();//定时器1初始化
EA = 1;//打开总中断
rd_temperature();
Delay750ms();//用于消除上电显示85°C的影响
while(1)
{
Key_Proc();
Seg_Proc();
Led_Proc();
}
}
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((Disp_Flag>>4) == 0)
Disp_Flag = 0x10;
else if((Disp_Flag>>4) == 1)
{
Disp_Flag = 0x00;
Hour_P_Ctrl = Hour_P;
Temp_P_Ctrl = Temp_P;
LED_P_Ctrl = LED_P;
}
break;
case 5://子界面切换,数据界面和参数界面完成三个子界面切换
if((Disp_Flag>>4) == 0)
{
if(++Disp_Flag == 0x03)
Disp_Flag = 0x00;
}
else if((Disp_Flag>>4) == 1)
{
if(++Disp_Flag == 0x13)
Disp_Flag = 0x10;
}
break;
case 9://+
if(Disp_Flag == 0x10)
{if(++Hour_P == 24) Hour_P = 23;}
else if(Disp_Flag == 0x11)
{if(++Temp_P == 100) Temp_P = 99;}
else if(Disp_Flag == 0x12)
{if(++LED_P == 9) LED_P = 8;}
break;
case 8://-
if(Disp_Flag == 0x10)
{if(--Hour_P== 255) Hour_P = 0;}
else if(Disp_Flag == 0x11)
{if(--Temp_P == 255) Temp_P = 0;}
else if(Disp_Flag == 0x12)
{if(--LED_P == 3) LED_P = 4;}
break;
}
}
void Seg_Proc(void)
{
if(Seg_Slow_Down) return;
Seg_Slow_Down = 1;
Read_Rtc(Rtc);
Temp_Num = rd_temperature()/16.0;
Photo_R_Voltage_Num = Pcf8591_Adc(Photo_Res_Channel)/51.0;
if(Photo_R_Voltage_Num < 0.5)
{
Liang_An_Flag = 1;//暗
if(An_First_Time == 0)
{
ms_Tick_LED_An = ms_Tick;
An_First_Time = 1;
Liang_First_Time = 0;
}
if((ms_Tick - ms_Tick_LED_An)>=3000)
Liang_An_Flag_Over_3_Sec = 1;
}
else
{
Liang_An_Flag = 0;//亮
if(Liang_First_Time == 0)
{
ms_Tick_LED_Liang = ms_Tick;
Liang_First_Time = 1;
An_First_Time = 0;
}
if((ms_Tick - ms_Tick_LED_Liang)>=3000)
Liang_An_Flag_Over_3_Sec = 0;
}
switch(Disp_Flag)
{
case 0x00:
sprintf(seg_string,\"%02d-%02d-%02d\",(unsigned int)Rtc[0],(unsigned int)Rtc[1],(unsigned int)Rtc[2]);
break;
case 0x01:
sprintf(seg_string,\"C %4.1f\",Temp_Num);
break;
case 0x02:
sprintf(seg_string,\"E %4.2f %d\",Photo_R_Voltage_Num,(unsigned int)Liang_An_Flag);
break;
case 0x10:
sprintf(seg_string,\"P1 %02d\",(unsigned int)Hour_P);
break;
case 0x11:
sprintf(seg_string,\"P2 %02d\",(unsigned int)Temp_P);
break;
case 0x12:
sprintf(seg_string,\"P3 %1d\",(unsigned int)LED_P);
break;
}
Seg_Tran(seg_string, seg_buf);
}
void Led_Proc(void)
{
if(Led_Slow_Down) return;
Led_Slow_Down = 1;
if(Hour_P_Ctrl < 8)
{
if((Rtc[0] < 8)&&(Rtc[0] >= Hour_P_Ctrl))
ucLed |= 0x01;//L1点亮
else
ucLed &= (~0x01);//L1熄灭
}
else if(Hour_P_Ctrl >= 8)
{
if((Rtc[0] >= 8)&&(Rtc[0] < Hour_P_Ctrl))
ucLed &= (~0x01);//L1熄灭
else
ucLed |= 0x01;//L1点亮
}
if(Temp_Num < Temp_P_Ctrl)
ucLed |= 0x02;//L2点亮
else
ucLed &= (~0x02);//L2熄灭
if(Liang_An_Flag_Over_3_Sec == 1)
ucLed |= 0x04;//L3点亮
else
ucLed &= (~0x04);//L3熄灭
if(Liang_An_Flag == 1)//暗状态,点亮指定的LED灯
{
ucLed &= (~0xF8);//所有灯全部熄灭
switch (LED_P_Ctrl)
{
case 4:
ucLed |= 0x08;//L4点亮
break;
case 5:
ucLed |= 0x10;//L5点亮
break;
case 6:
ucLed |= 0x20;//L6点亮
break;
case 7:
ucLed |= 0x40;//L7点亮
break;
case 8:
ucLed |= 0x80;//L8点亮
break;
}
}
else
ucLed &= (~0xF8);//所有灯全部熄灭
}
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;
Seg_Disp(seg_buf, pos);//用于数码管显示
if(++pos == 8) pos = 0;
Led_Disp(ucLed);//用于LED显示
}
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);
}