第十一届 第一场 蓝桥杯单片机设计与开发项目 省赛

# 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熄灭			
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

魏丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值