记忆大师

本项目详细介绍了基于STC89C52单片机的最小系统设计,包括电路原理图、矩阵键盘、LED矩阵、蜂鸣器等模块的硬件连接与软件控制。通过具体代码示例,展示了延时函数、LED控制、数码管显示、定时器初始化及中断处理等功能实现。

本项目采用STC89C52为MCU,与89C52RC通用
XTAL选用12.000MHz
引脚定义如下:
#矩阵键盘 P1
LED矩阵
阳极P3.3-P3.6
阴极P2.0-P2.3
定义为
阳极LED1-LED4

按键定义为SW = P3.0
蜂鸣器定义为P3.2
数码管阳极定义为First-Forth=P2.4-P2.7
阴极定义为P0

其最小系统 的电路原理图如下:
在这里插入图片描述

其矩阵键盘原理图如下:
在这里插入图片描述
其LED点阵的原理图如下:
在这里插入图片描述
蜂鸣器原理图如下
在这里插入图片描述

#include<stdlib,h>
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
#define KEY_PORT  P1
uchar DisplayFlag = 0;
sbit SW = P3^0;
sbit SW1 = P3^1;
sbit BUZZ = P3^2;
sbit LED1 = P3^3;
sbit LED2 = P3^4;
sbit LED3 = P3^5;
sbit LED4 = P3^6;
sbit First = P2^7;
sbit Second = P2^6;
sbit Third = P2^5;
sbit Forth = P2^4;
uchar Counter = 0,TimeOut = 30,TimeFlag = 1,Level=1;
uchar rad[5]={0xFF,0xFF,0xFF,0xFF,0xFF};
uchar KeyCheck[5]={0xF0,0xF0,0xF0,0xF0,0xF0};
uchar GifCode[]={1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10,0};
void delay1s_x(void)   //误差 0us
{
    unsigned char a,b,c;
    for(c=5;c>0;c--)
        for(b=50;b>0;b--)
            for(a=130;a>0;a--);
}
void delay500us(void)   //误差 0us
{
    unsigned char a,b;
    for(b=71;b>0;b--)
        for(a=2;a>0;a--);
}
void LEDLight(uchar which)
{
 P2 = 0x0F;
 P3 = 0x83;
 switch(which)
 {
  case 1:
   P3 = 0xC3;
   P2 = 0x07;
   delay500us();
  break;
       
  case 2:
   P3 = 0xA3;
   P2 = 0x07;
   delay500us();
  break;
       
  case 3:
   P3 = 0x93;
   P2 = 0x07;
   delay500us();
  break;
       
  case 4:
   P3 = 0x89;
   P2 = 0x07;
   delay500us();
  break;
       
  case 5:
   P3 = 0xC3;
   P2 = 0x0B;
   delay500us();
  break;
       
  case 6:
   P3 = 0xA3;
   P2 = 0x0B;
   delay500us();
  break;
       
  case 7:
   P3 = 0x93;
   P2 = 0x0B;
   delay500us();
  break;
       
  case 8:
   P3 = 0x89;
   P2 = 0x0B;
   delay500us();
  break;
       
  case 9:
   P3 = 0xC3;
   P2 = 0x0D;
   delay500us();
  break;
       
  case 10:
   P3 = 0xA3;
   P2 = 0x0D;
   delay500us();
  break;
       
  case 11:
   P3 = 0x93;
   P2 = 0x0D;
   delay500us();
  break;
       
  case 12:
   P3 = 0x89;
   P2 = 0x0D;
   delay500us();
  break;
       
  case 13:
   P3 = 0xC3;
   P2 = 0x0E;
   delay500us();
  break;
       
  case 14:
   P3 = 0xA3;
   P2 = 0x0E;
   delay500us();
  break;
       
  case 15:
   P3 = 0x93;
   P2 = 0x0E;
   delay500us();
  break;
       
  case 16:
   P3 = 0x89;
   P2 = 0x0E;
   delay500us();
  break;      
 } 
}
void LedClear()
{
 P2=0x0F;
 P3=0x83;
}
void LEDGif(uchar x)
{
 LEDLight(x);
 delay1s_x();
 LedClear();
}
void InitTimer0(void)
{
    TMOD = 0x02;
    TH0 = 0x00;
    TL0 = 0x9C;
    EA = 1;
    ET0 = 1;
    TR0 = 1;
}
void InitTimer1(void)
{
    TMOD = 0x20;
    TH1 = 0x00;
    TL1 = 0x38;
    EA = 1;
    ET1 = 1;
    TR1 = 1;
}
void delay10ms(void)
{
    unsigned char a,b,c;
    for(c=1;c>0;c--)
        for(b=38;b>0;b--)
            for(a=130;a>0;a--);
}
void delay1ms(void)
{
    unsigned char a,b,c;
    for(b=71;b>0;b--)
        for(a=2;a>0;a--);
}
void DigiDisplay(uchar a,uchar b,uchar c,uchar d)
{
 	uchar DigiNum[11]={0x10,0xBE,0x4C,0x45,0x27,0x85,0x80,0x57,0x00,0x01,0xFF};
 	P2 |= 0x1F; 
 	P0 = DigiNum[a];
 	delay1ms();
	P2 &= 0x0F;
 	P0 = 0x00;
 	
 	P2 |= 0x2F;
 	P0 = DigiNum[b];
 	delay1ms();
 	P2 &= 0x0F;
 	P0 = 0x00;
 	
 	P2 |= 0x4F;
 	P0 = DigiNum[c];
 	delay1ms();
 	P2 &= 0x0F;
 	P0 = 0x00;
 
  	P2 |= 0x8F;
 	P0 = DigiNum[d];
 	delay1ms();
 	P2 &= 0x0F;
 	P0 = 0x00;
 }
 uchar KeyScan(void)
{
 uchar val = 0;
 
 KEY_PORT = 0x0f;
 if (KEY_PORT != 0x0f)
 {
  delay10ms();
  if (KEY_PORT != 0x0f)
  {
  	switch (KEY_PORT)
   {
    case 0x07 : val = 1;  break;
    case 0x0b : val = 2; break;
    case 0x0d : val = 3; break;
    case 0x0e : val = 4; break;
    default   :    break;
   }
      KEY_PORT = 0xf0;
   switch (KEY_PORT)
   {
    case 0x70: val = val + 0; break;
    case 0xb0: val = val + 4; break;
    case 0xd0:  val = val + 8; break;
    case 0xe0: val = val + 12; break;
   }
   return val; 
  }  
 }
 return 0; 
}
void Timer0Interrupt(void) interrupt 1
{
 TR0 = 0;
    TH0 = 0x00;
    TL0 = 0x9C;
 if(TimeOut == 0)
 {
  Counter=0;
  TimeFlag = 0;
  TR0 = 0;
  TH0 = 0x00;
  TL0 = 0x9C;
 }
    Counter++;
 if(Counter == 122)
 {
  TimeOut--;
  Counter = 0;
 }
 TR0 = 1;
}
void Timer1Interrupt(void) interrupt 3
{
    TH1 = 0x00;
    TL1 = 0x38;
}
void delay1s(void) 
{
    uchar a,b,c;
    for(c=13;c>0;c--)
        for(b=247;b>0;b--)
            for(a=142;a>0;a--);
}
void delay50ms(void)
{
    unsigned char a,b;
    for(b=173;b>0;b--)
        for(a=143;a>0;a--);
}
void main()
{
 uchar BitCho = 0,i=0;
 InitTimer0();
 InitTimer1();
 TR0 = 0;
    TH0 = 0x00;
    TL0 = 0x9C;
 while(GifCode[i]!=0)
 {
  LEDGif(GifCode[i]);
  i++;
 }
 while(1)
 {
  BUZZ = 0;
  srand(TL1+TH1);
  if(SW == 0)
  {
   delay10ms();
   if(SW == 0)
   {  
    uchar i; 
    for(i = 1;i<=4;i++)
    {
     rad[i]=rand()&0x0F;
     delay10ms();
    }
   }
  }
  if((rad[1]!=0xFF||rad[2]!=0xFF||rad[3]!=0xFF||rad[4]!=0xFF)&&DisplayFlag == 0)
  {
   unsigned char a,b,c;
   TR0 = 0;
      TH0 = 0x00;
      TL0 = 0x9C;
   for(c=5;c>0;c--)
    for(b=40;b>0;b--)
     for(a=500;a>0;a--)
     { 
      P0 = 0xFF;
      P2=rad[1]|0xF0;
      P3=0x83;
      LED1=1;
      P2=0xFF;
      P3=0x83;
      
      P2=rad[2]|0xF0;
      P3=0x83;
      LED2=1;
      P2=0xFF;
      P3=0x83;
      
      P2=rad[3]|0xF0;
      P3=0x83;
      LED3=1;
      P2=0xFF;
      P3=0x83;
      
      P2=rad[4]|0xF0;
      P3=0x83;
      LED4=1;
      P2=0xFF;
      P3=0x83;
      }
   DisplayFlag = 1;
   P2=0x0F;
   P3=0x83;
  }
  if(DisplayFlag == 1)
  {
   unsigned char a,b,c,Key,i;
   TR0 = 1;
   TimeOut=(10-Level)*2+3;
   while(TimeFlag == 1)
   {
    Key = KeyScan();
    switch(Key)
    {
     case 1:
      KeyCheck[4]=KeyCheck[4]|0x08;
      P3 = 0xC3;
      P2 = 0x07;
      delay1ms();
     break;
          case 2:
      KeyCheck[3]=KeyCheck[3]|0x08;
      P3 = 0xA3;
      P2 = 0x07;
      delay1ms();
     break;
          case 3:
      KeyCheck[2]=KeyCheck[2]|0x08;
      P3 = 0x93;
      P2 = 0x07;
      delay1ms();
     break;
       
     case 4:
      KeyCheck[1]=KeyCheck[1]|0x08;
      P3 = 0x89;
      P2 = 0x07;
      delay1ms();
     break;
          case 5:
      KeyCheck[4]=KeyCheck[4]|0x04;
      P3 = 0xC3;
      P2 = 0x0B;
      delay1ms();
     break;
       
     case 6:
      KeyCheck[3]=KeyCheck[3]|0x04;
      P3 = 0xA3;
      P2 = 0x0B;
      delay1ms();
     break;
          case 7:
      KeyCheck[2]=KeyCheck[2]|0x04;
      P3 = 0x93;
      P2 = 0x0B;
      delay1ms();
     break;
       
     case 8:
      KeyCheck[1]=KeyCheck[1]|0x04;
      P3 = 0x89;
      P2 = 0x0B;
      delay1ms();
     break;
       
     case 9:
      KeyCheck[4]=KeyCheck[4]|0x02;
      P3 = 0xC3;
      P2 = 0x0D;
      delay1ms();
     break;
       
     case 10:
      KeyCheck[3]=KeyCheck[3]|0x02;
      P3 = 0xA3;
      P2 = 0x0D;
      delay1ms();
     break;
          case 11:
      KeyCheck[2]=KeyCheck[2]|0x02;
      P3 = 0x93;
      P2 = 0x0D;
      delay1ms();
     break;
       
     case 12:
      KeyCheck[1]=KeyCheck[1]|0x02;
      P3 = 0x89;
      P2 = 0x0D;
      delay1ms();
     break;
       
     case 13:
      KeyCheck[4]=KeyCheck[4]|0x01;
      P3 = 0xC3;
      P2 = 0x0E;
      delay1ms();
     break;
       
     case 14:
      KeyCheck[3]=KeyCheck[3]|0x01;
      P3 = 0xA3;
      P2 = 0x0E;
      delay1ms();
     break;
          case 15:
      KeyCheck[2]=KeyCheck[2]|0x01;
      P3 = 0x93;
      P2 = 0x0E;
      delay1ms();
     break;
       
     case 16:
      KeyCheck[1]=KeyCheck[1]|0x01;
      P3 = 0x89;
      P2 = 0x0E;
      delay1ms();
     break;
     }
     P2 = 0x0F;
    P3 = 0x83;
    DigiDisplay(Level/10,Level%10,TimeOut/10,TimeOut%10);
   }
      TimeFlag = 1;
   DisplayFlag = 0;
   TR0 = 0;
      TH0 = 0x00;
      TL0 = 0x9C;
      if(rad[1]==~KeyCheck[1]&&rad[2]==~KeyCheck[2]&&rad[3]==~KeyCheck[3]&&rad[4]==~KeyCheck[4])
   {
    P2 = 0x00;
    P3 = 0xFF;
    delay1s();
    P2 = 0x0F;
    P3 = 0x83;
    Level++;
    if(Level == 9)
    {
     Level = 1;
     BUZZ = 1;
     delay1s();
     BUZZ = 0;
     delay1s();
    }
    for(i=1;i<=4;i++)
    {
     rad[i]=0xFF;
     KeyCheck[i]=0xF0;
    }
   }
  }
 }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值