# include "bsp_init.h"
# include "bsp_seg.h"
# include "timer.h"
# include "bsp_key.h"
# include "bsp_led.h"
#include "bsp_iic.h"
# include "stdio.h"
void Key_Proc(void);//按键处理,底层数据变更
void Seg_Proc(void);//显示处理,显示信息生成
void Led_Proc(void);//LED处理,LED状态信息表示
//数码管显示专用
unsigned char seg_buf[8];//放置字符串转换后的段码到数组
unsigned char seg_string[10];//放置字符串
unsigned char pos = 0;//中断显示专用
//LED显示专用
unsigned char ucLed;//记录LED的状态信息
//按键专用
unsigned char Key_Value;//读取按键的数值存储变量
unsigned char Key_Down, Key_Old;//读取按键的数值存储变量
//按键和显示函数减速专用
unsigned int Key_Slow_Down;//按键减速
unsigned int Seg_Slow_Down;//按键减速
//滴答定时专用
unsigned long ms_Tick=0;//上电之后会一直运行下去 ,49天才会产生溢出
unsigned char Interface_Mode = 0;//0-数据界面,1-参数界面,2-计数界面
unsigned char Interface_Mode_Old = 0;//记录上一次的Interface_Mode值
float Vp = 0;//参数
unsigned char VP_ten;//放大十倍往EEPROM中存储
unsigned int Count = 0;//计数值
float Voltage = 0;//读取的电压值
bit Higher = 0;
bit Lower = 0;
unsigned long Start_Time = 0;//为了定时5s专用
unsigned char Unbelieveable_Key = 0;//无效按键
void main()
{
Cls_Peripheral();//关闭外设
Timer1Init();//定时器1初始化,并且使能定时器1中断,1ms进入一次
EA = 1;//打开总中断
EEPROM_Read(&VP_ten, 0, 1);
Vp=(VP_ten/10)+(VP_ten%10)*0.1;
while(1)
{
Key_Proc();//按键处理,底层数据变更
Seg_Proc();//显示处理,显示信息生成
Led_Proc();//LED处理,LED状态信息表示
}
}
void tm1_isr() interrupt 3
{
ms_Tick++;//上电自动++,持续运行
if(++Key_Slow_Down == 10) Key_Slow_Down = 0;
if(++Seg_Slow_Down == 100) Seg_Slow_Down = 0;
Seg_Disp(seg_buf, pos);//数码管显示刷新
if( ++pos == 8 ) pos = 0;
Led_Disp(ucLed);//LED显示
}
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 12://屏幕切换
Interface_Mode_Old = Interface_Mode;
if(++Interface_Mode == 3) Interface_Mode=0;//基本操作,保证Interface_Mode在0-2之间变换。
if((Interface_Mode_Old == 1)&&(Interface_Mode == 2))//表示退出了设置界面
{
VP_ten = Vp*10;
EEPROM_Write(&VP_ten, 0, 1);
}
Unbelieveable_Key = 0;
break;
case 13://清零计数值
if(Interface_Mode == 2)//唯有计数界面有效
{
Count = 0;
Unbelieveable_Key = 0;
}
else
Unbelieveable_Key++;
break;
case 9://+
if(Interface_Mode == 1)//唯有参数设置界面有效
{
Vp+=0.5;
if(Vp>=5.5)//上限后回归到0
Vp = 0;
Unbelieveable_Key = 0;
}
else
Unbelieveable_Key++;
break;
case 8://-
if(Interface_Mode == 1)//唯有参数设置界面有效
{
Vp-=0.5;
if(Vp<0)//下限后回归到5
Vp = 5;
Unbelieveable_Key = 0;
}
else
Unbelieveable_Key++;
break;
case 0:
break;
default://其他按键按下,让该数值++
Unbelieveable_Key++;
break;
}
}
void Seg_Proc(void)//显示处理,显示信息生成
{
if(Seg_Slow_Down) return;
Seg_Slow_Down = 1;//减速程序
Voltage = (Pcf8591_Adc(Adj_Res_Channel)/51.0);//就采集一次电压值
if(Voltage > Vp) Higher = 1;
if(Higher ==1)
{
if(Voltage < Vp)
Lower = 1;
}
if((Higher ==1)&&(Lower == 1))
{
Count++;
Higher = 0;
Lower = 0;
}
//借用seg空间进行led显示
if((Voltage < Vp)&&(Start_Time == 0))
{
Start_Time = ms_Tick;//采集当前的数值
}
if((Voltage < Vp)&&((ms_Tick-Start_Time)>5000))
{
ucLed |= 0x01;//最低位置位,L1点亮
}
if(Voltage > Vp)
{
ucLed &= (~0x01);//最低位,L1熄灭
Start_Time = 0;
}
switch(Interface_Mode)//0-数据界面,1-参数界面,2-计数界面
{
case 0:
sprintf(seg_string,"U %3.2f",Voltage);
break;
case 1:
sprintf(seg_string,"P %3.2f",Vp);
break;
case 2:
sprintf(seg_string,"N%7d",(unsigned int)Count);
break;
}
Seg_Tran(seg_string, seg_buf);
}
void Led_Proc(void)//显示处理,显示信息生成
{
if((Count%2) == 1)//如果计数值为奇数的话,L2点亮,否则熄灭
ucLed |= 0x02;//L2点亮
else
ucLed &= (~0x02);//L2熄灭
if(Unbelieveable_Key >= 3)//连续三次无效按键按下
ucLed |= 0x04;//L3点亮
else
ucLed &= (~0x04);//L3熄灭
}
第十一届 第一场 蓝桥杯单片机设计与开发项目 省赛
最新推荐文章于 2024-04-10 10:51:42 发布