蓝桥杯单片机第12届

#include <STC15F2K60S2.H>
#include "iic.h"
#include "onewire.h"

typedef unsigned char u8;

typedef struct
{
	u8 b1:1;
	u8 b2:1;
	u8 b3:1;
	u8 b4:1;
	u8 b5:1;
	u8 b6:1;
	u8 b7:1;
	u8 b8:1;
}bits;

typedef union
{
	unsigned char Hex;
	bits B;
}HexToBit;

HexToBit led_ctrl;
	
u8 code smg_duanma[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
u8 smg[8];
u8 temp_num=25;//初始化温度参数为25


void vDevice_Process(u8 p2dat, u8 p0dat)
{
	P0 = p0dat;
	P2 = (P2&0x1f)|p2dat;
	P2 = P2&0x1f;
}

//定时器2
void Timer2Init(void)		//1毫秒@12.000MHz
{
	AUXR |= 0x04;		//定时器时钟1T模式
	T2L = 0x20;		//设置定时初值
	T2H = 0xD1;		//设置定时初值
	AUXR |= 0x10;		//定时器2开始计时
	EA=1;
	IE2 |= 0x04;
}


//读取温度
unsigned int temp;
void vRead_temp()
{
	temp = rd_temperature()*100;
}

//输出电压
unsigned int dac_dat=0;
bit mode_DAC=0;
void vDAC_out()
{
	if(mode_DAC==0)//模式1
	{
		if(temp<temp_num*100)
		{
			dac_dat=0;
			DAC_out(dac_dat);
		}
		else
		{
			dac_dat=255;//5V
			DAC_out(dac_dat);
		}
	}
	
	if(mode_DAC==1)//模式2
	{
		if(temp<2000)
		{
			dac_dat=102;
			DAC_out(dac_dat);
		}
		else if(temp<4000)
		{
			dac_dat=51+(0.15*(temp-2000)*51)/100;
			DAC_out(dac_dat);
		}
		else 
		{
			dac_dat=204;
			DAC_out(dac_dat);
		}
	}
}

//数码管操作函数
u8 mode_smg=0;//数码管显示模式,0温度 1参数 2DAC
void vSMG_Process()
{
	if(mode_smg==0)
	{
		smg[0] = 0xc6;
		smg[1] = 0xff;
		smg[2] = 0xff;
		smg[3] = 0xff;
		smg[4] = smg_duanma[temp/1000];
		smg[5] = smg_duanma[temp/100%10]+0x80;
		smg[6] = smg_duanma[temp/10%10];
		smg[7] = smg_duanma[temp%10];
	}
	
	if(mode_smg==1)
	{
		smg[0] = 0x8c;
		smg[1] = 0xff;
		smg[2] = 0xff;
		smg[3] = 0xff;
		smg[4] = 0xff;
		smg[5] = 0xff;
		smg[6] = smg_duanma[temp_num/10];
		smg[7] = smg_duanma[temp_num%10];
	}
	
	if(mode_smg==2)
	{
		smg[0] = 0x88;
		smg[1] = 0xff;
		smg[2] = 0xff;
		smg[3] = 0xff;
		smg[4] = 0xff;
		smg[5] = smg_duanma[dac_dat*100/51/100]+0x80;
		smg[6] = smg_duanma[dac_dat*100/51/10%10];
		smg[7] = smg_duanma[dac_dat*100/51%10];
	}
}

//数码管显示函数
void vSMG_Show()
{
	static u8 i;
	vDevice_Process(0xc0,0x00);
	vDevice_Process(0xe0,smg[i]);
	vDevice_Process(0xc0,0x01<<i);
	i=(i+1)%8;
}

//按键扫描
unsigned char vScan_Keys()
{
	unsigned char key_io=0;
	P3 = 0xf0; P4 = 0xff; // 扫描列
	if(P44==0) key_io=4;
	if(P42==0) key_io=8;
	if(P35==0) key_io=12;
	if(P34==0) key_io=16;
	
	P3 = 0x0f; P4 = 0x00; // 扫描行
	if(P30==0) key_io=key_io+3;
	if(P31==0) key_io=key_io+2;
	if(P32==0) key_io=key_io+1;
	if(P33==0) key_io=key_io+0;
	
	return key_io;
}

//按键状态机
#define KEY_NO 0 
#define KEY_DOWM 1
#define KEY_UP 2
unsigned char vKBD_Read_State()
{
	static unsigned char key_state=0;  //保存每次按键的状态
	unsigned char key_io=0,key_val=0;  //io是读取的io状态。val是返回的键值
	
	key_io = vScan_Keys();
	switch(key_state)
	{
		case KEY_NO:
			if(key_io) key_state=KEY_DOWM;
		break;
		
		case KEY_DOWM:
			if(key_io)
			{
				key_state=KEY_UP;
				key_val=key_io;        //判断完是否抖动。不是抖动才赋值给val返回
			}
			else
			{
				key_state=KEY_NO;     //如果是抖动 即key_io=0了,就返回KEY_NO状态
			}
		break;
			
		case KEY_UP:
			if(key_io==0) key_state=KEY_NO;
		break;
	}
	return key_val;
}

//按键处理
unsigned int cnt_key;
u8 key_val;
void vKey_Process()
{
	if(cnt_key>=10)
	{
		cnt_key=0;
		key_val = vKBD_Read_State();
		
		if(key_val==4)
		{
			mode_smg++;
			if(mode_smg==3)mode_smg=0;
		}
		if(key_val==8)
		{
			if(mode_smg==1) temp_num--;
		}
		if(key_val==9)
		{
			if(mode_smg==1) temp_num++;
		}
		if(key_val==5)
		{
			mode_DAC=~mode_DAC;
		}
	}
}


//系统初始化
void System_init()
{
	led_ctrl.Hex=0xff;
	vDevice_Process(0x80,0xff);
	vDevice_Process(0xa0,0x00);
}

void main()
{
	System_init();
	Timer2Init();
	while(1)
	{
		vSMG_Process();
		vRead_temp();
		vKey_Process();
	}
}

unsigned int cnt_dac;
void Timer2_service() interrupt 12
{
	cnt_dac++;
	cnt_key++;
	vSMG_Show();
	if(cnt_dac>=400)
	{
		cnt_dac=0;
		vDAC_out();
	}
	if(mode_DAC==0)
	{
		led_ctrl.B.b1=0;
	}
	else led_ctrl.B.b1=1;
	switch(mode_smg)
	{
		case 0:
			led_ctrl.B.b2=0;
			led_ctrl.B.b3=1;
			led_ctrl.B.b4=1;
		break;
		case 1:
			led_ctrl.B.b2=1;
			led_ctrl.B.b3=0;
			led_ctrl.B.b4=1;
		break;
		case 2:
			led_ctrl.B.b2=1;
			led_ctrl.B.b3=1;
			led_ctrl.B.b4=0;
		break;
	}
	vDevice_Process(0x80,led_ctrl.Hex);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值