栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

蓝桥杯十一届第一篇省赛 计数触发 数值跃迁判断

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

蓝桥杯十一届第一篇省赛 计数触发 数值跃迁判断

main.c 

#include "STC15F2K60S2.h"	 
#include "iic.h"
#define	u8	unsigned char
#define	u16	unsigned int

u8 code smg_du[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x3E,0x73,0x37}; //0-9 
u8 code smg_wei[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
void vEEPROM_init();
void  re_EEPROM();
#define KEY P3
#define NO_KEY		0xff	//无按键按下
#define KEY_STATE0  0   	//判断按键按下
#define KEY_STATE1  1  		//确认按键按下
#define KEY_STATE2  2  		//释放按键
	
unsigned char Key_Scan()
{
	static unsigned char key_state=KEY_STATE0; //定义为静态变量,用于保存每次按键的状态
	u8 key_value=0,key_temp;				   //key_val:返回的键值;key_temp:读取的IO状态
	u8 key1,key2;

	P30=0;P31=0;P32=0;P33=0;P34=1;P35=1;P42=1;P44=1;
	if(P44==0)	key1=0x70;
	if(P42==0)	key1=0xb0;
	if(P35==0)	key1=0xd0;
	if(P34==0)	key1=0xe0;
	if((P34==1)&&(P35==1)&&(P42==1)&&(P44==1))	key1=0xf0;

	P30=1;P31=1;P32=1;P33=1;P34=0;P35=0;P42=0;P44=0;
	if(P30==0)	key2=0x0e;
	if(P31==0)	key2=0x0d;
	if(P32==0)	key2=0x0b;
	if(P33==0)	key2=0x07;
	if((P30==1)&&(P31==1)&&(P32==1)&&(P33==1))	key2=0x0f;
	key_temp=key1|key2;

	switch(key_state)                             
	{
		case KEY_STATE0:				//判断按键按下
			if(key_temp!=NO_KEY)
			{
				key_state=KEY_STATE1; 	//有键按下,就转到状态1    
			}
			break;

		case KEY_STATE1:				//经过10ms,再次确认按键按下,用于消抖
			if(key_temp==NO_KEY)		
			{
				key_state=KEY_STATE0;	//如果是抖动,则回到状态0
			}
			else						//如果不是抖动,则返回对应的键值
			{
				switch(key_temp)                             
				{
					case 0x77: key_value=4;break;
					case 0x7b: key_value=5;break;
					case 0x7d: key_value=6;break;
					case 0x7e: key_value=7;break;

					case 0xb7: key_value=8;break;
					case 0xbb: key_value=9;break;
					case 0xbd: key_value=10;break;
					case 0xbe: key_value=11;break;

					case 0xd7: key_value=12;break;
					case 0xdb: key_value=13;break;
					case 0xdd: key_value=14;break;
					case 0xde: key_value=15;break;

					case 0xe7: key_value=16;break;
					case 0xeb: key_value=17;break;
					case 0xed: key_value=18;break;
					case 0xee: key_value=19;break;	
				}
				key_state=KEY_STATE2;
			}
			break;

		case KEY_STATE2:			//经过10ms,判断是否释放按键
			if(key_temp==NO_KEY)
			{
				key_state=KEY_STATE0;
			}
			break;
	}
	return key_value;
}

void Timer_Init(void)	//1ms定时器,用STC-ISP生成
{
	AUXR |= 0x80;		//1T的定时器
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0xCD;			//设置定时初值
	TH0 = 0xD4;			//设置定时初值
	TF0 = 0;			//清除TF0标志
	TR0 = 1;			//定时器0开始计时
	ET0 = 1;			//开启定时器0中断
	EA=1; 				//开启总中断
}
void Io_init()
{
	P2=0x80;P0=0xff;P2=0x00;
	P2=0xa0;P0=0x00;P2=0x00;
}



bit key_flag;			//按键标志位
u8 S12_num=0;
u8 V_data[8];
u8 P_data[8];
u8 N_data[8];
u8 adc_3;
u16 adc_v;
u16 adc_vnow;
u16 adc_data=0;
u8 N_num=0;
u8 S_null=0;
void main(void)
{
	u8 key_val=NO_KEY;
	Io_init(); //关闭蜂鸣器和继电器
	vEEPROM_init();
	
	V_data[0]=smg_du[10];
	V_data[1]=0x00;
	V_data[2]=0x00;
	V_data[3]=0x00;
	V_data[4]=0x00;
	P_data[0]=smg_du[11];
	P_data[1]=0x00;
	P_data[2]=0x00;
	P_data[3]=0x00;
	P_data[4]=0x00;
	N_data[0]=smg_du[12];
	N_data[1]=0x00;
	N_data[2]=0x00;
	N_data[3]=0x00;
	N_data[4]=0x00;
	N_data[5]=0x00;
	Timer_Init(); 			//1ms定时器
	while(1)
	{	if(S12_num==0)
		{
		V_data[5]=smg_du[adc_vnow/100]|0x80;
		V_data[6]=smg_du[adc_vnow/10%10];
		V_data[7]=smg_du[adc_vnow%10];	
		}
		if(S12_num==1)
		{
		P_data[5]=smg_du[adc_data/100]|0x80;
		P_data[6]=smg_du[adc_data/10%10];
		P_data[7]=smg_du[adc_data%10];	
		
		}
	
	if(S12_num==2)
		{
		N_data[6]=smg_du[N_num/10];
		N_data[7]=smg_du[N_num%10];	
		
		}
	
	
		
		
		
		if(key_flag) 		//10ms的轮询
		{
			key_flag=0;
			key_val=Key_Scan();
			switch(key_val)                       
			{                                              
				case 4:  break;
				case 5:  break;
				case 6:  break;
				case 7:  break;
				case 8:  break;
				case 9:  break;
				case 10: break;
				case 11: break;
				case 12: S12_num++;
									re_EEPROM();
									if(S12_num==3) S12_num=0;	break;
				case 13: 	if(S12_num==2) 
					{
							N_num=0;	
							S_null=0;
					}
					else{
						S_null++;
					}
					break;
				case 14:  S_null++; break;
				case 15:  S_null++;break;
				case 16:
							if(S12_num==1) 
							{
									adc_data+=50;
									S_null=0;
								if(adc_data>500)
								{
									adc_data=0;
								}
							}
							else
							{
							S_null++;
							}break;
				case 17: if(S12_num==1) 
							{  S_null=0;
								
								if(adc_data==0)
								{
									adc_data=550;}
									adc_data=adc_data-50;
								
							}
							else{S_null++;}break;
				case 18: break;
				case 19: break;
			} 
		}
	}
}

void vEEPROM_init()
{
	 adc_data=read_24c02(0x00)*10;
	 if((adc_data>500)||(adc_data%50!=0))
		 adc_data=300;

}

u8 ledCtrl=0xff;
u16 led_count=0;
void Led_process()
{
	if(adc_vnow=5000)
		{
			led_count=0;
			P0=ledCtrl&~0x01; P2=0x80;P2=0x00;
		}
	}
	else
	{led_count=0;
	P0=ledCtrl|0x01; P2=0x80;P2=0x00;
	
	}
	
	if(N_num%2==1)
	{
	P0=ledCtrl&~0x02; P2=0x80;P2=0x00;
	}
	else
	{
		P0=ledCtrl|0x02; P2=0x80;P2=0x00;
	}
	
	if(S_null>=3)
	{
		P0=ledCtrl&~0x04; P2=0x80;P2=0x00;
	}
	else
	{
	P0=ledCtrl|0x04; P2=0x80;P2=0x00;
	}
	



}
void  re_EEPROM()
{
	if(S12_num==2)
	{
	write_24c02(0x00,adc_data/10);
	}

 }


void timer0() interrupt 1       //定时器0的中断编号是1        
{
	static int key_count=0,smg_count=0,i=0,U_count=0;
	key_count++;
	smg_count++;
	U_count++;
	
	Led_process();
		if(U_count==10)
	{
		U_count=0;
		read_adc(0x03);
		adc_3=read_adc(0x03);
		adc_v=adc_vnow;
		adc_vnow=adc_3*100/51;
		
		if((adc_v>adc_data)&&(adc_data>adc_vnow)&&(adc_v>adc_vnow))
		{
			N_num++;
		}
		
		
	}
	
	
	if(key_count==10)					//10ms轮询
	{
		key_count=0;
		key_flag=1;
	}
	
	if(smg_count==3)					//3ms轮询
	{
		smg_count=0;
		P2=0xc0;P0=0;P2=0;			//数码管消影
	
			if(S12_num==0)
			{
				P2=0xe0;P0=~V_data[i];P2=0;
			}
			if(S12_num==1)
			{
				P2=0xe0;P0=~P_data[i];P2=0;
			}
			if(S12_num==2)
			{
				P2=0xe0;P0=~N_data[i];P2=0;
			}
																		
		P2=0xc0;P0=smg_wei[i];P2=0; 	//数码管位选赋值
		i++;
		if(i==8) i=0;
	}
}

iic.c


#include "reg52.h"
#include "iic.h"
#include "intrins.h"

#define DELAY_TIME 5

#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1

//总线引脚定义
sbit SDA = P2^1;  
sbit SCL = P2^0;  

void IIC_Delay(unsigned char i)
{
    do{_nop_();}
    while(i--);        
}
//总线启动条件
void IIC_Start(void)
{
    SDA = 1;
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    SDA = 0;
    IIC_Delay(DELAY_TIME);
    SCL = 0;	
}

//总线停止条件
void IIC_Stop(void)
{
    SDA = 0;
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    SDA = 1;
    IIC_Delay(DELAY_TIME);
}

//发送应答
void IIC_SendAck(bit ackbit)
{
    SCL = 0;
    SDA = ackbit;  					// 0:应答,1:非应答
    IIC_Delay(DELAY_TIME);
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    SCL = 0; 
    SDA = 1;
    IIC_Delay(DELAY_TIME);
}

//等待应答
bit IIC_WaitAck(void)
{
    bit ackbit;
	
    SCL  = 1;
    IIC_Delay(DELAY_TIME);
    ackbit = SDA;
    SCL = 0;
    IIC_Delay(DELAY_TIME);
    return ackbit;
}

//通过I2C总线发送数据
void IIC_SendByte(unsigned char byt)
{
    unsigned char i;

    for(i=0; i<8; i++)
    {
        SCL  = 0;
        IIC_Delay(DELAY_TIME);
        if(byt & 0x80) SDA  = 1;
        else SDA  = 0;
        IIC_Delay(DELAY_TIME);
        SCL = 1;
        byt <<= 1;
        IIC_Delay(DELAY_TIME);
    }
    SCL  = 0;  
}

//从I2C总线上接收数据
unsigned char IIC_RecByte(void)
{
    unsigned char i, da;
    for(i=0; i<8; i++)
    {   
    	SCL = 1;
	IIC_Delay(DELAY_TIME);
	da <<= 1;
	if(SDA) da |= 1;
	SCL = 0;
	IIC_Delay(DELAY_TIME);
    }
    return da;    
}


uchar read_24c02(uchar add)
{
	uchar temp;
	EA=0;
	IIC_Start();
	IIC_SendByte(0xa0);
	IIC_WaitAck();
	IIC_SendByte(add);
	IIC_WaitAck();
	IIC_Start();
	IIC_SendByte(0xa1);
	IIC_WaitAck();
	temp=IIC_RecByte();
	IIC_WaitAck();
	IIC_Stop();
	EA=1;
	return temp;
}

void write_24c02(uchar add,uchar date)
{
	EA=0;
	IIC_Start();
	IIC_SendByte(0xa0);
	IIC_WaitAck();
	IIC_SendByte(add);
	IIC_WaitAck();
	IIC_SendByte(date);
	IIC_WaitAck();
	IIC_Stop();
	EA=1;
}

uchar read_adc(uchar add)
{
	uchar temp; 
	EA=0;
	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(add);
	IIC_WaitAck();
	IIC_Start();
	IIC_SendByte(0x91);
	IIC_WaitAck();
	temp=IIC_RecByte();
	IIC_WaitAck();
	IIC_Stop();	
	EA=1;
	return temp;
}

void write_adc(uchar add)
{
	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(add);
	IIC_WaitAck();
	IIC_Stop();
}

总结主要一个 是 学习如何 判断 计数 触发条件编程 

if(U_count==10) //10毫秒 刷新 电压值
	{
		U_count=0;
		read_adc(0x03);
		adc_3=read_adc(0x03);
		adc_v=adc_vnow; // 获取前一次 电压值 
		adc_vnow=adc_3*100/51; // 此时的电压值
		
		if((adc_v>adc_data)&&(adc_data>adc_vnow)&&(adc_v>adc_vnow)) // 初始值大于参数值,参数值大于现在值,现在值小于初始值  则符合条件加一
		{
			N_num++;
		}
		
		
	}

 数值跃迁问题

 主要是  从EEPROM 中读取值的时候  判断是否读取错误

void vEEPROM_init()
{
	 adc_data=read_24c02(0x00)*10;
	 if((adc_data>500)||(adc_data%50!=0)) // 电压值不可能超过 5v 这里电压值是扩大100倍 方便数码管显示  2. 读取的电压值 也不可能 是 23 34 之类的  按键加减都是 50 所以 不被50 整除也是数值错误 给与一个 初始值3 v 
		 adc_data=300;

}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/779896.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号