藍橋杯省賽第十屆模擬題

2020-10-15 14:00:23




main.c

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

#define uchar  unsigned char
#define uint   unsigned int
uchar code duan[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff,0xc0,0x8c,0x86,0xc8,0xc6};
uchar disbuf[]={11,11,11,11,11,11,11,11};//10111111
uchar password[]={8,8,8,8,8,8,8};
uchar intword[]={8,8,8,8,8,8,8};
uchar keyvalue=20;
uchar word;
uchar wait_time=1;
uchar run=1;
bit output=0;
bit wait=1;
	uchar t1,t2;

void delay1ms(uchar q)//延時函數
{
	uchar m;	
	uchar i, j;
	for(m=0;m<q;m++)
	{


	_nop_();
	_nop_();
	_nop_();
	i = 11;
	j = 190;
	do
	{
		while (--j);
	} while (--i);
}
}
void display()//數碼管顯示
{
	 uchar i;
	 for(i=0;i<=7;i++)
	{

		
	 P2=(P2&0x1f)|0xc0;
	 P0=0x01<<i;
	 P2=P2&0x1f;
		
	 P2=(P2&0x1f)|0xe0;
	 P0=duan[disbuf[i]];
	 P2=P2&0x1f;
		
		delay1ms(1);
		
		P2=(P2&0x1f)|0xe0;
	 P0=0xff;
	 P2=P2&0x1f;
		
	
	}
	
}
void init0all()  //初始化函數
{
	 P2=(P2&0x1f)|0xa0;
	 P0=0x00;
	 P2=P2&0x1f;
	
 	 P2=(P2&0x1f)|0x80;
	 P0=0xff;
	 P2=P2&0x1f;
	
	disbuf[0]=11;
	disbuf[1]=11;
	disbuf[2]=11;
	disbuf[3]=11;
	disbuf[4]=11;
	disbuf[5]=11;
	disbuf[6]=11;
	disbuf[7]=11;
	display();
}
void key16()
{
	  keyvalue=20;
	 P3=0x0f,P42=0,P44=0;
	 while(wait_time==1)
	 {
	   ET0=1;
		 EA=1;
		 
		 if(P3!=0x0f)
		 {
			 wait=0;
			 ET0=0;
		   EA=0;
			 wait_time=0;
			 t1=0;
			 t2=0;
		 }
	 }
	 
			wait_time=1; 
	 
			 if(P3!=0x0f)
		 {
			 
			 if(P3==0x07)
			 {
				 keyvalue=4;
			 }
			 if(P3==0x0b)
			 {
				 keyvalue=5;
			 }
			 if(P3==0x0d)
			 { 
				  keyvalue=6;
			 }
			 if(P3==0x0e)
			 { 
				  keyvalue=7;
			 }
		 }
		 
	 P3=0xf0,P42=1,P44=1;
		 
	 if(P3!=0xf0||P42!=1||P44!=1)
	 {
			 if(P44==0)
			 {
				 keyvalue=keyvalue;
			 }
			 if(P42==0)
			 {
				 keyvalue=keyvalue+4;
			 }
			 if(P3==0xd0)
			 {
				 keyvalue=keyvalue+8;
			 }
			 if(P3==0xe0)
			 {
				 keyvalue=keyvalue+12;
			 }
		 
	 }
  while(P3!=0xf0||P42!=1||P44!=1);
}
uchar getword()
{
	 switch(keyvalue)
	 {
		 case 7:word=0;break;
		 case 11:word=1;break;
		 case 15:word=2;break;
		 case 19:word=3;break;
		 case 6:word=4;break;
		 case 10:word=5;break;
		 case 14:word=6;break;
		 case 18:word=7;break;
		 case 5:word=8;break;
		 case 9:word=9;break;
	 }
	 return word;
}
 void inputkey()
{
	 int i;
	 disbuf[0]=10;
	 disbuf[1]=11;
	 disbuf[2]=11;
	 display();
	 for(i=0;i<6;i++)
	{
		 if(i==5)
		 {
			 run=0;
			key16();
			 
			if(keyvalue==8)
		 {
			 disbuf[7]=11;
			 disbuf[6]=11;
			 disbuf[5]=11;
			 disbuf[4]=11;
			 disbuf[3]=11;
			 i=-1;
			 run=1;
		 }
		 
	    intword[5] =getword();
		 
		 }
		 
     if(run==1)
		 {
		key16();
		 if(i==1)
		 {
        disbuf[6]=disbuf[7];
		 }	
		  if(i==2)
		 {
			  disbuf[5]=disbuf[6];
        disbuf[6]=disbuf[7];
		 }	
		 	if(i==3)
		 {
			  disbuf[4]=disbuf[5];
        disbuf[5]=disbuf[6];
        disbuf[6]=disbuf[7];
		 }
		 	if(i==4)
		 {
			  disbuf[3]=disbuf[4];
        disbuf[4]=disbuf[5];
        disbuf[5]=disbuf[6];
			  disbuf[6]=disbuf[7];
		 }			 
		disbuf[7]=getword();
		intword[i]=getword();
		display();	 
				 
		 if(keyvalue==8)
		 {
			 i=-1;
			 disbuf[7]=11;
			 disbuf[6]=11;
			 disbuf[5]=11;
			 disbuf[4]=11;
			 disbuf[3]=11;
		 }
	  }
 }	 
	run=1;
}
void write_key()
{
	uchar i;
	for(i=0;i<6;i++)
	{
		 write_eeprom(0x02,password[i]);
	}
}
void changekey()
{
	uchar i;
	disbuf[0]=16;
  disbuf[1]=11;
  disbuf[2]=11;
	display();
	 for(i=0;i<6;i++)
	{
   if(i==5)
		 {
			run=0;
			key16();
			password[5]=getword();
			delay1ms(2);
		 }
		 
     if(run==1)
		 {
		key16();
		 if(i==1)
		 {
        disbuf[6]=disbuf[7];
		 }	
		  if(i==2)
		 {
			  disbuf[5]=disbuf[6];
        disbuf[6]=disbuf[7];
		 }	
		 	if(i==3)
		 {
			  disbuf[4]=disbuf[5];
        disbuf[5]=disbuf[6];
        disbuf[6]=disbuf[7];
		 }
		 	if(i==4)
		 {
			  disbuf[3]=disbuf[4];
        disbuf[4]=disbuf[5];
        disbuf[5]=disbuf[6];
			  disbuf[6]=disbuf[7];
		 }			 
		  disbuf[7]=getword();
		  password[i]=getword();
	  	display();
	   }
 }
run=1;
write_key(); 
}
void init_time0()
{
	AUXR |= 0x80;		//定時器時鐘1T模式
	TMOD &= 0xF0;		//設定定時器模式
	TL0 = 0xCD;		//設定定時初值
	TH0 = 0xD4;		//設定定時初值
	TF0 = 0;		//清除TF0標誌
	TR0 = 1;		//定時器0開始計時
	//ET0 = 1;
	//EA=1;
}
void do_time0() interrupt 1
{

	t1++;
	display();
	if(t1==50)
	{
		t1=0;
		t2++;
		if(t2==100)
	{
     t2=0;
		wait_time=0;
			ET0=0;
		   EA=0;
	}		
} 
}
void warn_delay()
{
	uchar i;
	for(i=0;i<50;i++)
	{
		delay1ms(100);
	}
}
void checkkey()
{
	uchar i;
	output=1;
	for(i=0;i<6;i++)
	{
		if(password[i] != intword[i])
		{
			output=0;
		}
	}
}
void read_key()
{
	uchar i;
	for(i=0;i<6;i++)
	{
		password[i]=read_eeprom(0x02);
		delay1ms(1);
	}
}
void main()
{
	init0all();
	init_time0();	
	//write_key();//初始化
	read_key();

	 while(1)
	 {
		 key16();
		 if(keyvalue==16)
		 {
			 inputkey();
			 checkkey();
			 if(output==1)
			 {
				 P2=(P2&0x1f)|0xa0;
	       P0=0x40;
	       P2=P2&0x1f;
				 
				 disbuf[7]=15;
         disbuf[6]=14;
         disbuf[5]=13;
				 disbuf[4]=12;
				 disbuf[3]=11;
				 disbuf[2]=11;
				 disbuf[1]=11;
				 disbuf[0]=12;
				 
				 display();
				 key16();				 
				 if(keyvalue==12)
				 {
         	 init0all();
            changekey();					 
				 }
				 init0all();
				 disbuf[0]=11;
				 disbuf[1]=11;
				 disbuf[2]=11;
				 disbuf[3]=11;
				 disbuf[4]=11;
				 disbuf[5]=11;
				 disbuf[6]=11;
				 disbuf[7]=11;
				 
			 }
			 
			 
			 if(output==0)
			 {
				P2=(P2&0x1f)|0x80;
	      P0=0xfe;
	      P2=P2&0x1f;
				 
        warn_delay();
				 
				P2=(P2&0x1f)|0x80;
	      P0=0xff;
	      P2=P2&0x1f;
				 
		    init0all();
				 
			 }
			 
		 }
	 }
}

iic.c

/*
  程式說明: IIC匯流排驅動程式
  軟體環境: Keil uVision 4.10 
  硬體環境: CT107微控制器綜合實訓平臺 8051,12MHz
  日    期: 2011-8-9
*/

#include "reg52.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_();_nop_();_nop_();_nop_();
		   _nop_();_nop_();_nop_();_nop_();
		   _nop_();_nop_();_nop_();_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);
}



//等待應答
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;    
}
//eeprom讀
void write_eeprom(unsigned char add,unsigned char dat)
{
	 IIC_Start();
	 IIC_SendByte(0xa0);
	 IIC_WaitAck();
	 IIC_SendByte(add);
	 IIC_WaitAck();
	 IIC_SendByte(dat);
	 IIC_WaitAck();
   IIC_Stop();
}
//eeprom寫
unsigned char read_eeprom(unsigned char add)
{
	 unsigned char du; 
	 IIC_Start();
	 IIC_SendByte(0xa0);
	 IIC_WaitAck();
	 IIC_SendByte(add);
	 IIC_WaitAck();
	 
	 IIC_Start();
	 IIC_SendByte(0xa1);
	 IIC_WaitAck();
	 du=IIC_RecByte();
	 IIC_Stop();
	
	 return du;
}

iic.h

#ifndef _IIC_H
#define _IIC_H
void IIC_Start(void); 
void IIC_Stop(void);  
bit IIC_WaitAck(void);  
void IIC_SendByte(unsigned char byt); 
unsigned char IIC_RecByte(void); 
void write_eeprom(unsigned char add,unsigned char dat);
unsigned char read_eeprom(unsigned char add);
#endif

沒用解決無功能位在輸入密碼狀態下按下輸入為0的問題…
希望有大佬指導解決辦法