⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 better.c

📁 基于IAP12C5A62s2的led显示
💻 C
字号:
#define uint unsigned int//  // 定义新类型,方便下次使用
#define uchar unsigned char
#include"STC12C5A.h"
#include <intrins.h> 
#define WaitTime 0x01
#define ENABLE_IAP 0x82
#define address 0x2800	 
#define CMD_IDLE 0//        //定义时钟频率     
#define CMD_READ 1//        //读命令
#define CMD_PROGRAM 2//     //写命令
#define CMD_ERASE 3//      //擦除命令,一般需要几个毫秒
sbit shang=P2^0;//          //行列式键盘行线的定义
sbit xia=P2^1;
sbit  a =P4^6;// 		      // 数码管段码和单片机I/O口的对应关系
sbit  b =P4^5; 
sbit dp =P2^4;
sbit  d =P2^6;
sbit  e =P2^7;
sbit  g =P0^6;
sbit  f =P0^7;
sbit  c =P2^5;
sbit P44=P4^4;//		      //74hc244片选信号
sbit  SMG_1=P0^1;//	      //数码管位选信号
sbit  SMG_2=P0^2;
sbit  SMG_3=P0^3;
sbit  SMG_4=P0^4;
sbit  SMG_5=P0^5;
sbit  SMG_6=P0^0;
sbit  P3_6=P3^6;//	      //键盘列线的定义
sbit  P3_7=P3^7;
sbit  P2_3=P2^3;
sbit  P2_2=P2^2;
void display(uint cha);	
void start(); 
void delay(uint time);
void disable();
void enable();
void IapIdle();
uint IapReadByte(uint addr);
void IapProgramByte(uint addr, uchar dat);
void IapEraseSector(uint addr);
void INT0_init();
void INT0time() ;
void systeminit();
static uint cha;
static long int yichu;// 	 //时间计数,一旦达到设定值,关闭数码管 
static bit state;
void main(void)
{ 
  uchar t;
  shang=0;xia=0;
  systeminit();//	          //系统初始化函数,stc12c5a62s2单片机的I/O口工作方式的设定
  start();//            	  //系统显示校验函数,这里会从9显示到0,最后显示上一次的数码管亮的值		  
  INT0_init();//			  //开启定时器0中断
  while(1){	//			  //死循环
  if(state==0 ){//		  //如果状态0,则执行判键及相应的显示函数
  if(P3_6==0)//			  //键盘1和5的判键
	  { delay(20);
	    if(P3_6==0)
	    { shang=1;
	      if(P3_6==1)
		    cha=1;
	      else
		   cha=5;
	      shang=0;
	     }
	    }
	 if(P3_7==0)//		  //键盘2和6的判键
	{ delay(20);
	  if(P3_7==0)
      { shang=1;  
		if(P3_7==1)
	       cha=2;
	    else
	       cha=6;
	    shang=0;
	   }
	  }
	if(P2_3==0)//			  //键盘3和7的判键
	{ delay(20);
      if(P2_3==0)
	   { shang=1;
	     if(P2_3==1)
	       cha=3;
	     else
	       cha=7;
	     shang=0;
		}
	}
	 if(P2_2==0)              //键盘4的判键
	  { delay(20); 
	    if(P2_2==0)
		  cha=4; }
   }
  if(!(P2_2==1&&P2_3==1&&P3_6==1&&P3_7==1))      //按键按下判定语句
{	 yichu=0;              //如果有按键按下,重新设置溢出值,使达到关状态的时间相同
     if(state==1){         //如果为关闭状态
     delay(500);           //延时20ms
	 if(!(P2_2==1&&P2_3==1&&P3_6==1&&P3_7==1))        //如果有按键按下,状态清零,开始判键程序
      state=0;}
   }
  if(yichu>=80000)           //达到数码管关闭时间
	  { do{disable();}while(P2_2==1&&P2_3==1&&P3_6==1&&P3_7==1);        //若无按键按下,则执行关闭语句
        yichu=0;        //重设溢出值
	    enable();       //点亮数码管
		state=1;        //状态设1,为关闭后点亮状态
      }
    if(t!=cha)          //如果有不同的键按下
	{ IapEraseSector(address);           //eeprom擦除
	  IapProgramByte(address,cha);       //eeprom写
	  t=cha;            //保存目前的按键值,和下一次做比较,看是否要进行写操作
	  }
  }

}
void systeminit()
{ P4SW=0x7F;		 
  P0M1=0x00;
  P0M0=0xff;
  P2M1=0x00;
  P2M0=0xff;
  P3M1=0x00;
  P3M0=0xff;
  P4M1=0x00;
  P4M0=0xff;
  P44=0;
  }
void display(uint cha)             //显示函数,其中小数点一直关闭
{ 
    switch(cha){						 
	case 0: a=1;b=1;c=1;d=1;e=1;f=1;g=0;dp=0;break;         //显示数值0
	case 1: a=0;b=1;c=1;d=0;e=0;f=0;g=0;dp=0;break;  	    //显示数值1
	case 2: a=1;b=1;c=0;d=1;e=1;f=0;g=1;dp=0;break;         //显示数值2
	case 3: a=1;b=1;c=1;d=1;e=0;f=0;g=1;dp=0;break;         //显示数值3
	case 4: a=0;b=1;c=1;d=0;e=0;f=1;g=1;dp=0;break;         //显示数值4
	case 5: a=1;b=0;c=1;d=1;e=0;f=1;g=1;dp=0;break;         //显示数值5
	case 6: a=1;b=0;c=1;d=1;e=1;f=1;g=1;dp=0;break;         //显示数值6
	case 7: a=1;b=1;c=1;d=0;e=0;f=0;g=0;dp=0;break;         //显示数值7
	case 8: a=1;b=1;c=1;d=1;e=1;f=1;g=1;dp=0;break;         //显示数值8
	case 9: a=1;b=1;c=1;d=1;e=0;f=1;g=1;dp=0;break;         //显示数值9
	  }	
 }
void INT0_init()           //开启中断,每2000/12 us溢出一次
{ TMOD=0x18;
  TH0=(65536-2000)/256;
  TL0=(65536-2000)%256;
  TR0=1;
  ET0=1;
  EA=1;
  }
void start(void)          //系统初始显示函数
{ 
   uchar  time=100;
   char  i;
   shang=0;xia=0;			  
   enable();
   for(i=9;i>=0;i--)      //显示数字9-0
   { display(i);
     delay(3000);
	 }
   do{display(IapReadByte(address));yichu--;}while((P3_6&&P3_7&&P2_3&&P2_2==1));        //如无按键按下,则显示上一次保存的数值
   }
void delay(uint time )     //延时函数
{ 
	unsigned long int j=time*40;
	do{ 
	    ;  }while(j--);
 }	 
 void disable()           //数码管关闭
 {
	 SMG_1=0;
	 SMG_2=0;
	 SMG_3=0;
	 SMG_4=0;
	 SMG_5=0;
	 SMG_6=0; 
	 }
 void enable()             //数码管开启显示
 {
	 SMG_1=1;
	 SMG_2=1;
	 SMG_3=1;
	 SMG_4=1;
	 SMG_5=1;
	 SMG_6=1; 
	 }
 void INT0time() interrupt 1      //定时器中断0
 {   static uchar liangdu; 		 
	 TH0=(65536-2000)/256;
     TL0=(65536-2000)%256;
	 display(cha);
	 liangdu++;
	 if(liangdu<=2*cha)           //pwm控制程序,其中数字1亮度最小,占空比最小
	   P44=0;
	 else
	{
	  P44=1;
	  if(liangdu==15)
	    liangdu=0;
	 }	
	yichu++;                      //每溢出一次,溢出次数加一

	}

void IapIdle()                    //eeprom初始函数
{ IAP_CONTR = 0; 
  IAP_CMD   = 0; 
  IAP_TRIG  = 0; 
  IAP_ADDRH = 0x80; 
  IAP_ADDRL = 0; 
}
uint IapReadByte(uint addr)
{ uint dat;
  IAP_CONTR =ENABLE_IAP;
  IAP_CMD   = CMD_READ; 
  IAP_ADDRL = addr; 
  IAP_ADDRH = addr >> 8; 
  IAP_TRIG  = 0x5a;             //因为是IAP单片机,所以触发命令有所不同
  IAP_TRIG  = 0xa5; 
  _nop_(); 
  dat = IAP_DATA;
  IapIdle(); 
  return dat; 
}
void IapProgramByte(uint addr,uchar dat)    //eeprom写函数
{IAP_CONTR = ENABLE_IAP; 
IAP_CMD = CMD_PROGRAM; 
IAP_ADDRL = addr; 
IAP_ADDRH = addr >> 8; 
IAP_DATA = dat;
IAP_TRIG = 0x5a; 
IAP_TRIG = 0xa5; 
_nop_(); 
IapIdle();
}
void IapEraseSector(uint addr)        //eeprom扇区擦出函数
{IAP_CONTR = ENABLE_IAP; 
IAP_CMD = CMD_ERASE; 
IAP_ADDRH=addr>>8; 
IAP_ADDRL=addr;
IAP_TRIG = 0x5a; 
IAP_TRIG = 0xa5;
_nop_(); 
IapIdle();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -