蓝桥杯国赛 多功能测量表

1.题目

在这里插入图片描述
在这里插入图片描述在这里插入图片描述

2.重点代码

eeprom的写
由于eeprom连续写有延迟问题,所以需要加大约5ms的间隔,这里我使用了4ms
另外存放的数据过大的话,需要分开,例如频率要拆开分为高8位和低8位

if(flag_keep == 1)
{
		if(flag_4ms)
		{
				flag_4ms = 0;
				switch(index)
				{
						case 0:write_eeprom(H_volt,0x00);break;
						case 1:write_eeprom(H_temper>>8,0x01);break;
						case 2:write_eeprom(H_temper&0xff,0x02);break;
						case 3:write_eeprom(H_fre>>8,0x03);break;
						case 4:write_eeprom(H_fre&0xff,0x04);break;
				}
				index++;
				if(index == 5) 
				{
						index = 0; 
						flag_keep = 0;	
				}
		}					
}

eeprom的读
因为写入的数据是分开的,所以读出时记得整合起来,(转为无符号整形)高8位或运算低8位

void Read_Data()
{
		H_volt = Read_eeprom(0x00);
		H_temper = (uint)(Read_eeprom(0x01)<<8)|(Read_eeprom(0x02));
		H_fre = (uint)(Read_eeprom(0x03)<<8)|(Read_eeprom(0x04));
}

长按键
长按键事件在中断里判断
首先判断按下时间是否超过0.8s,超过时进入长按时间,每隔200ms,增加一个阈值
否则计数清零,标志位置零

if(flag_s3_press == 1)
{
			t3++;
			if(t3 >= 400)
			{
					t3 = 0;
					flag_long_press = 1;
			}
			if(flag_long_press == 1)
			{
					if(t3 >= 100)
					{
							t3 = 0;
							valve++;
							if(valve >= 50) valve = 1;
					}
			}
	}
	else
	{
			t3 = 0;
			flag_long_press = 0;
	}

3.代码

main.c

******************************************************************************
* 文件名:多功能测量仪表
* 描  述:
* 作  者:思索与猫
* 日  期:  19/5/18 
* 备  注: 
*         
******************************************************************************
#include<stc15f2k60s2.h>
#include<sys.h>

unsigned char volt;
unsigned int fre,temper;
bit flag_keep,flag_warning;
void main()
{
		static uchar index = 0;
		CloseFucker();
		Timer1Init();      //定时器配置
		Timer0Init();      //计数器配置
		pcf859_init();
		valve = Read_eeprom(0x05);        //读取阈值
		while(1)
		{
				KeyDriver();
				ShowNumber();
						
				if(flag_ad == 1)         //读取AD
				{
						flag_ad = 0;
						volt = read_adc();
						volt = volt*50/255;
						
						if(volt >= valve)       //判断是否超过阈值
						{
								flag_warning = 1;
						}
						else
						{
								flag_warning = 0;
						}
				}
				
				if(flag_fre == 1)        //测量频率
				{
						flag_fre = 0;
						TR0 = 0;
						fre = TH0*256+TL0;
						fre = fre*2;
						TH0 = 0;
						TL0 = 0;
						TR0 = 1;
				}
				
				if(flag_temp == 1)     //测量温度(带小数)
				{
						flag_temp = 0;
						temper = (uint)100*ReadTemp();     //一共四位,两位整数,两位小数
				}
				
				if(flag_keep == 1)     //保存功能
				{
						if(flag_4ms)     //每隔4ms写入一次eeprom
						{
								flag_4ms = 0;
								switch(index)
								{
										case 0:write_eeprom(H_volt,0x00);break;               //电压值
										case 1:write_eeprom(H_temper>>8,0x01);break;   //温度高8位
										case 2:write_eeprom(H_temper&0xff,0x02);break; //温度低8位
										case 3:write_eeprom(H_fre>>8,0x03);break;         //频率高8位
										case 4:write_eeprom(H_fre&0xff,0x04);break;       //频率低8位
								}
								index++;
								if(index == 5) 
								{
										index = 0; 
										flag_keep = 0;	
								}
						}					
				}
		}
}

sys.c

#include<sys.h>
bit flag_ad = 1,flag_fre = 0,flag_temp = 0,flag_4ms = 0;
uchar led[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
bit flag_long_press;
void Timer0Init()  // 计数器
{
		TMOD = 0x04;
		TL0 = 0;
		TH0 = 0;
		TF0 = 0;
		TR0 = 1;	
}

void Timer1Init()		//2ms@12.000MHz
{
		AUXR |= 0x40;		 
		TMOD &= 0x0F;		 
		TL1 = 0x40;		 
		TH1 = 0xA2;		 
		TF1 = 0;		 
		TR1 = 1;
		ET1 = 1;
		EA = 1;
}

void Read_Data()        //读取数据
{
		H_volt = Read_eeprom(0x00);
		H_temper = (uint)(Read_eeprom(0x01)<<8)|(Read_eeprom(0x02));
		H_fre = (uint)(Read_eeprom(0x03)<<8)|(Read_eeprom(0x04));
}

void T1_time() interrupt 3
{
		static uint ad_count,fre_count,temp_count,count_4ms,count_200ms,t3;
		
		KeyScan();
		Display();
	
		if(++count_4ms >= 2)
		{				
				count_4ms = 0;
				flag_4ms = 1;
		}
		
		if(++ad_count >= 200)      //400ms读取一次ad
		{
				ad_count = 0;
				flag_ad = 1;
		}
		
		if(++fre_count >= 250)    //500ms读取一次频率
		{
				fre_count = 0;
				flag_fre = 1;
		}
		
		if(++temp_count >= 200)  //400ms读取一次温度
		{
				temp_count = 0;
				flag_temp = 1;
		}
		
		if(flag_warning == 1)    //L8闪烁
		{
				if(++count_200ms >= 100)
				{
						count_200ms = 0;
						ShowLed(led[7]|led[view]);
				}	
				else 
				{
						ShowLed(led[view]);
				}
		}
		else if(flag_warning == 0)
		{
				ShowLed(led[view]);
		}
		
		if(flag_s3_press == 1)     //长按键加阈值,长按1S加0.5
		{
				t3++;
				if(t3 >= 400)
				{
						t3 = 0;
						flag_long_press = 1;
				}
				if(flag_long_press == 1)
				{
						if(t3 >= 100)
						{
								t3 = 0;
								valve++;
								if(valve >= 50) valve = 1;
						}
				}
		}
		else
		{
				t3 = 0;
				flag_long_press = 0;
		}
		
}

void CloseFucker()
{
		P2 = P2&0x1f|0xa0;
		P0 = 0xaf;
		P2 = P2&0x1f;
}

sys.h

#ifndef __SYS_H_
#define __SYS_H_

#include<stc15f2k60s2.h>
#include<onewire.h>
#include<iic.h>

typedef unsigned char uchar;
typedef unsigned int uint;

void Timer0Init();
void Timer1Init();
void Read_Data();
void CloseFucker();

void Display();
void ShowNumber();
void ShowLed(uchar led_dat);

void KeyDriver();
void KeyAction(uchar key_value);
void KeyScan();

extern uchar view;
extern uchar valve;
extern uchar led[];
extern bit H_mode,mode;
extern uchar volt,H_volt;
extern uint fre,temper,H_fre,H_temper;
extern bit flag_ad,flag_fre,flag_temp,flag_keep,flag_4ms,flag_warning;
extern bit flag_s3_press;
#endif

display.c

#include<sys.h>
uchar code duan[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,  //整数
					 0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,  //小数
					 0x00, //20black
					 0x40,0x3E,0x71,0x39,0x76,0x73};// 21-,22U,23F,24C,25H,26P
uchar disbuf[8];
uchar view = 0;
										 
void Display()
{
		static uchar index = 0;
	
		P2 = P2&0x1f|0xe0;
		P0 = 0xff;
		P2 = P2&0x1f;
	
		P2 = P2&0x1f|0xc0;
		P0 = 1<<index;
		P2 = P2&0x1f;
	
		P2 = P2&0x1f|0xe0;
		P0 = ~duan[disbuf[index]];
		P2 = P2&0x1f;
	
		index++;
		index &= 0x07;
}

void ShowNumber()
{
		uint temp;
		if(mode == 0)
		{
				if(view == 0)     //电压显示界面
				{		
						if(H_mode == 1)
						{
								temp = H_volt;
								disbuf[0] = 25;
								disbuf[1] = 22;
						}
						else 
						{
								temp = volt;
								disbuf[0] = 22;
								disbuf[1] = 20;
						}
						
						disbuf[2] = 20;
						disbuf[3] = 20;
						disbuf[4] = 20;
						disbuf[5] = 20;
						disbuf[6] = temp/10+10;
						disbuf[7] = temp%10;
				}
				else if(view == 1)    //频率显示界面
				{
						if(H_mode == 1)
						{
								temp = H_fre;
								disbuf[0] = 25;
								disbuf[1] = 23;
						}
						else  
						{
								temp = fre;
								disbuf[0] = 23;
								disbuf[1] = 20;
						}								
						disbuf[2] = 20;					
						if(temp/10000 == 0)
						{
								disbuf[3] = 20;
						}
						else
						{
								disbuf[3] = temp/10000;
						}
						
						if(disbuf[3] == 20&&temp/1000%10 == 0)
						{
								disbuf[4] = 20;
						}
						else
						{
								disbuf[4] = temp/1000%10;
						}
						
						if(disbuf[4] == 20&&temp/100%10 == 0)
						{
								disbuf[5] = 20;
						}
						else
						{
								disbuf[5] = temp/100%10;
						}
						
						if(disbuf[5] == 20&&temp/10%10 == 0)
						{
								disbuf[6] = 20;
						}
						else
						{
								disbuf[6] = temp/10%10;
						}
						
						if(disbuf[6] == 20&&temp%10 == 0)
						{
								disbuf[7] = 20;
						}
						else
						{
								disbuf[7] = temp%10;
						}
				}
				else if(view == 2)   //温度显示界面
				{
						if(H_mode == 1)
						{
								temp = H_temper;
								disbuf[0] = 25;
								disbuf[1] = 24;
						}
						else  
						{
								temp = temper;
								disbuf[0] = 24;
								disbuf[1] = 20;
						}
						
						disbuf[2] = 20;
						disbuf[3] = 20;
						disbuf[4] = temp/1000;
						disbuf[5] = temp/100%10+10;
						disbuf[6] = temp/10%10;
						disbuf[7] = temp%10;
				}
		}
		else if(mode == 1)   //阈值显示界面
		{
				disbuf[0] = 26;
				disbuf[1] = 20;
				disbuf[2] = 20;
				disbuf[3] = 20;
				disbuf[4] = 20;
				disbuf[5] = 20;
				disbuf[6] = valve/10+10;
				disbuf[7] = valve%10;
		}
	
}

void ShowLed(uchar led_dat)
{
		P2 = P2&0x1f|0x80;
		P0 = ~led_dat;
		P2 = P2&0x1f;
}

key.c

#include<sys.h>

sbit Key_In_1 = P3^0;
sbit Key_In_2 = P3^1;
sbit Key_In_3 = P3^2;
sbit Key_In_4 = P3^3;

uchar KeySta[4] = {1, 1, 1, 1};
uchar KeyCodeMap[4] = {1, 2, 3, 4};
uchar H_volt;
uchar valve;
uint H_fre,H_temper;
bit H_mode = 0,mode = 0;
bit flag_s3_press;

void KeyDriver()
{
		static uchar KeyBack[4] = {1, 1, 1, 1};
		uchar i = 0;
		
		for(i=0; i<4; i++)
		{
				if(KeySta[i] != KeyBack[i])
				{
						if(KeySta[i] == 0)
						{
								KeyAction(KeyCodeMap[i]);
						}
						KeyBack[i] = KeySta[i];
				}
		}
}

void KeyAction(uchar key_value)
{
		if(key_value == 4)   //设置按钮
		{
				mode = ~mode;
				ShowLed(0x08);
		}
		if(mode == 0)
		{
				if(key_value == 1)   //切换按钮
				{
						view++;
						if(view >= 3) view = 0;
						ShowLed(led[view]);
				}
				if(key_value == 2)   //保存按钮
				{
						flag_keep = 1;
						H_volt = volt;
						H_fre = fre;
						H_temper = temper;
				}
				if(key_value == 3)  //回调按钮
				{
						Read_Data();
						H_mode = ~H_mode;			
				}
		}
		else if(mode == 1)  
		{
				if(key_value == 3)  //增加阈值按钮
				{
						flag_s3_press = 1;
						valve = valve+1;
						if(valve >= 50) valve = 1;
						write_eeprom(valve,0x05);
				}
		}
		
}

void KeyScan()
{
		static uchar KeyBuf[4] = {0xff, 0xff, 0xff, 0xff};
		uchar i = 0;
		
		KeyBuf[0] = KeyBuf[0]<<1|Key_In_1;
		KeyBuf[1] = KeyBuf[1]<<1|Key_In_2;
		KeyBuf[2] = KeyBuf[2]<<1|Key_In_3;
		KeyBuf[3] = KeyBuf[3]<<1|Key_In_4;
		
		for(i=0; i<3; i++)
		{
				if(KeyBuf[i] == 0xff)
				{
						KeySta[i] = 1;
				}
				else if(KeyBuf[i] == 0x00)
				{
						KeySta[i] = 0;
				}
				else
				{
						if(flag_s3_press)     //发生抖动,长按键取消
						{
								flag_s3_press = 0;
						}
				}
		}		
}

onewire.c

#include "onewire.h"

void Delay_OneWire(unsigned int t)
{
		t*=12;
	 while(t--);
}

bit Init_DS18B20(void)
{
	bit initflag = 0;
	DQ = 1;
	Delay_OneWire(12);
	DQ = 0;
	Delay_OneWire(80); 
	DQ = 1;
	Delay_OneWire(10); 
	initflag = DQ;    
	Delay_OneWire(5);
  
	return initflag;
}

void Write_DS18B20(unsigned char dat)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		DQ = 0;
		DQ = dat&0x01;
		Delay_OneWire(5);
		DQ = 1;
		dat >>= 1;
	}
	Delay_OneWire(5);
}

unsigned char Read_DS18B20(void)
{
	unsigned char i;
	unsigned char dat;
  
	for(i=0;i<8;i++)
	{
		DQ = 0;
		dat >>= 1;
		DQ = 1;
		if(DQ)
		{
			dat |= 0x80;
		}	    
		Delay_OneWire(5);
	}
	return dat;
}

float ReadTemp()
{
		unsigned char low,high;
		unsigned int temp;
		float temper;
	
		Init_DS18B20();
		Write_DS18B20(0xcc);
		Write_DS18B20(0x44);
		Delay_OneWire(200);
	
		Init_DS18B20();
		Write_DS18B20(0xcc);
		Write_DS18B20(0xbe);
		Delay_OneWire(200);
	
		low = Read_DS18B20();
		high = Read_DS18B20();
	
		temp = high&0x0f;
		temp = temp<<8|low;
		temper = temp*0.0625;
	
		return temper;
}

onewire.h

#ifndef _ONEWIRE_H
#define _ONEWIRE_H

#include "stc15f2k60s2.h"

#define OW_SKIP_ROM 0xcc
#define DS18B20_CONVERT 0x44
#define DS18B20_READ 0xbe

sbit DQ = P1^4;

void Delay_OneWire(unsigned int t);
void Write_DS18B20(unsigned char dat);
bit Init_DS18B20(void);
unsigned char Read_DS18B20(void);
float ReadTemp();

#endif

iic.c

#include "iic.h"
void Delay5us()		//@12.000MHz
{
	unsigned char i;

	_nop_();
	_nop_();
	i = 12;
	while (--i);
}

void IIC_Start(void)
{
	SDA = 1;
	SCL = 1;
	somenop;
	SDA = 0;
	somenop;
	SCL = 0;	
}

void IIC_Stop(void)
{
	SDA = 0;
	SCL = 1;
	somenop;
	SDA = 1;
}

void IIC_Ack(unsigned char ackbit)
{
	if(ackbit) 
	{	
		SDA = 0;
	}
	else 
	{
		SDA = 1;
	}
	somenop;
	SCL = 1;
	somenop;
	SCL = 0;
	SDA = 1; 
	somenop;
}

bit IIC_WaitAck(void)
{
	SDA = 1;
	somenop;
	SCL = 1;
	somenop;
	if(SDA)    
	{   
		SCL = 0;
		IIC_Stop();
		return 0;
	}
	else  
	{ 
		SCL = 0;
		return 1;
	}
}

void IIC_SendByte(unsigned char byt)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{   
		if(byt&0x80) 
		{	
			SDA = 1;
		}
		else 
		{
			SDA = 0;
		}
		somenop;
		SCL = 1;
		byt <<= 1;
		somenop;
		SCL = 0;
	}
}

unsigned char IIC_RecByte(void)
{
	unsigned char da;
	unsigned char i;
	
	for(i=0;i<8;i++)
	{   
		SCL = 1;
		somenop;
		da <<= 1;
		if(SDA) 
		da |= 0x01;
		SCL = 0;
		somenop;
	}
	return da;
}

unsigned char Read_eeprom(unsigned char add)
{
		unsigned char dat;
		IIC_Start();
		IIC_SendByte(0xa0);
		IIC_WaitAck(); 
		IIC_SendByte(add);
		IIC_WaitAck(); 
	
		IIC_Start();
		IIC_SendByte(0xa1);
		IIC_WaitAck(); 
		dat = IIC_RecByte();
		IIC_WaitAck(); 
		IIC_Stop();
	
		return dat;	
}

void write_eeprom(unsigned char dat,unsigned char add)
{
		IIC_Start();
		IIC_SendByte(0xa0);
		IIC_WaitAck(); 
		IIC_SendByte(add);
		IIC_WaitAck(); 
		IIC_SendByte(dat);
		IIC_WaitAck(); 
		IIC_Stop();
}

void pcf859_init()
{
		IIC_Start();
		IIC_SendByte(0x90);
		IIC_WaitAck(); 
		IIC_SendByte(0x03);
		IIC_WaitAck(); 
		IIC_Stop();
}

unsigned char read_adc()
{
		unsigned char dat;
	
		IIC_Start();
		IIC_SendByte(0x91);
		IIC_WaitAck(); 
		dat = IIC_RecByte();
		IIC_WaitAck(); 
		IIC_Stop();
	
		return dat;	
}

iic.h

#ifndef _IIC_H
#define _IIC_H

#include "stc15f2k60s2.h"
#include "intrins.h"

#define somenop Delay5us()
#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1

sbit SDA = P2^1;  
sbit SCL = P2^0;  

void Delay5us();
void IIC_Start(void); 
void IIC_Stop(void);  
void IIC_Ack(unsigned char ackbit); 
void IIC_SendByte(unsigned char byt); 
bit IIC_WaitAck(void);  
unsigned char IIC_RecByte(void); 

unsigned char Read_eeprom(unsigned char add);
void write_eeprom(unsigned char dat,unsigned char add);
void pcf859_init();
unsigned char read_adc();

#endif
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值