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

📄 sy0406.c

📁 实现单片机led和矩阵数字键盘的控制 但是您必须要有深圳赛伯公司的at89s52开发板
💻 C
📖 第 1 页 / 共 2 页
字号:
    nop;
    SDA=1;                /*8位发送完后释放数据线,准备接收应答位*/
    nop;
    nop;   
    SCL=1;
    nop;
    nop;
    nop;
    
    if(SDA==1)
      acknow=0;        /* 24c02无应答 */     
    else 
      acknow=1;        /* 发送数据正常 */
    SCL=0;
    nop;
    nop;
}
/*******************************************************************
                 2051从24c02读数据字节数据接收函数               
函数原型: uchar  RcvByte();
功能:  	  用来接收从器件传来的数据,并判断总线错误(不发应答信号),
          发完后请用应答函数应答从机。  
********************************************************************/	
uchar  RcvByte()
{
  uchar retc=0;
  uchar count;
  
   
  SDA=1;             		/*置数据线为输入方式*/
  for(count=0;count<8;count++)
      {
        nop;           
        SCL=0;                  /*置时钟线为低,准备接收数据位*/
        nop;
        nop;                 /*时钟低电平周期大于4.7us*/
        nop;
        nop;
        nop;
        SCL=1;                  /*置时钟线为高使数据线上数据有效*/
        nop;
        nop;
        retc=retc<<1;
        
        if(SDA==1)
        retc=retc+1;  /*读数据位,接收的数据位放入retc中 */
        nop;
        nop; 
      }
  SCL=0;    
  nop;
  nop;
  return(retc);
}
/********************************************************************
                     主机2051应答子函数
函数原型:  void Ack(bit a);
功能:      主控器进行应答信号(可以是应答或非应答信号,由位参数a决定)
********************************************************************/
void Ack(bit a)
{
  
  if(a==0)                   
     SDA=0;     	     /*在此发出应答或非应答信号 */
  else                       /* 应答 a=0  非应答 a=1 */ 
     SDA=1;
  
  nop;
  nop;
  nop;      
  SCL=1;
  nop;
  nop;                    /*时钟低电平周期大于4us*/
  nop;
  nop;
  nop;  
  SCL=0;                     /*清时钟线,钳住I2C总线以便继续接收*/
  nop;
  nop;    
}
/*******************************************************************
                 用户接口函数                                   
*******************************************************************/

/* 有无子地址表示是否向芯片的特定地址写数据  */
/*******************************************************************
                    向有子地址器件写入6字节数据函数  对应数据资料中的写模式             
函数原型: bit  TSendAddress(uchar slaaddress,uchar subaddress,uchar * s,uchar no);  
功能:     从启动总线到发送从地址,子地址,数据,结束总线的全过程,从器件
          地址slaaddress,子地址subaddress,发送内容是s指向的内容,no=字节数
          如果返回1表示操作成功,否则操作有误。
注意:    使用前必须已结束总线。
********************************************************************/
bit TSendAddress(uchar slaaddress,uchar subaddress,uchar * s,uchar no) /* 向有子地址器件写入6字节数据函数 */
{   
   uchar i;
   Start();               	/*启动总线*/
   SendByte(slaaddress);        /*发送器件地址*/
   if(acknow==0)
   return(0);
   SendByte(subaddress);        /*发送器件子地址*/
   if(acknow==0)
   return(0);
   for(i=0;i<no;i++)
   {
     SendByte(s[i]);   	        /*发送数据*/
     if(acknow==0)
     return(0);
 //   s++;
    }   
   Stop();  		        /*结束总线*/ 
   return(0);
}
/*******************************************************************
                    向有子地址器件读取4字节数据函数               
函数原型: bit  TRcvAddress(uchar slaaddress,uchar subaddress,uchar * s,uchar no);  
功能:     从启动总线到发送从地址,子地址,读数据,结束总线的全过程,从器件
          地址slaaddress,子地址subaddress,读出的内容放入s, no=字节数
           如果返回1表示操作成功,否则操作有误。
注意:    使用前必须已结束总线。
********************************************************************/
bit TRcvAddress(uchar slaaddress,uchar subaddress,uchar * s,uchar no)
{
   uchar i; 
  
   Start();                             /*启动总线*/
   SendByte(slaaddress);                /*发送器件从地址*/
   
   if(acknow==0)
   return(0);
   
   SendByte(subaddress);               /*发送器件子地址*/
   
   if(acknow==0)
   return(0);
   Stop();                   /*结束总线*/ 

   Start();			 /*重新启动总线*/
   SendByte(slaaddress+1);
   
   if(acknow==0)
   return(0);
   
   for(i=0;i<no;i++)
    {
     * s=RcvByte();               /*接收数据*/
     Ack(0);                     /*发送应答位*/
     s++;
    }                   
     * s=RcvByte();               /*接收数据*/
     Ack(1);
     Stop();                   /*结束总线*/ 
     return(1);
}


/*--------------------------------------*/
void open(void)				/*开门比较密码副程式*/
{
      char c;				/*宣告变数*/
      FLAG1=1;				/*设开门标号为1*/
      for(c=0;c<6;c++)			/*比较六个密码*/
      {
     	if (disple[c]!=bufdata[c])		/*按键值disple[]与密码TAB[]比较是否相等*/
        FLAG1=0;
        if (FLAG1==0)			/*FLAG1=0 表示不相等*/
               break;			/*跳出此循环*/
      }
      if(FLAG1==1)			/*如FLAG1=1 表示密码相等,令电锁P2.0置0动作*/
 {
       P2_0=0;				/*P2.0置1,使绿色指示灯亮(喇叭响)*/	
       delay(2000);			/*延时*/
	TMOD=0x11;
 	TR1=1;
       IE=0x8a;				/*8是允许中断,a是TIMER0,TIMER1中断致能位*/
        clear();			/*清除屏幕*/
       BCD();				/*呼叫BCD十进制转换副程式,转换起始内定时间*/
     while (1)
     {
	do
	scan ();     			/*呼叫键盘扫描副程式,有按时FLAG0会为1*/
        while (FLAG0!=1);		/*判断有按键输入否?无时返回scan()*/
        delay(1000);			/*按钮防抖动延时,抗机械反弹跳*/
        while(m==P1);			/*按钮放开否?*/
        switch(tab[ptr])		/*是则测试ptr键盘扫描计数器指标至TAB[]取到的键盘码*/
        {
          case 0x0c: SEC++;
 			BCD();		/*是否按"A",是则呼叫BCD码转换副程式*/
                     break;		/*跳出此循环*/
          case 0x0d: MIN++;
          		BCD();		/*是否按"B",是则呼叫BCD码转换副程式*/
                     break;		/*跳出此循环*/
          case 0x0e: HOUR++;
         		BCD();		/*是否按"C",是则呼叫BCD码转换副程式*/
      		default:break;		/*跳出此循环*/
        }				/*跳至WHILE(1)*/
     }	
 }
}

void speekclose(void)
{
	if(disple[0]==5)
	P2_0=1;				/*P2.0置1,使绿色指示灯灭(喇叭关闭)*/	
}

/*--------------------------------------*/
void disp(void)				/*显示密码副程式*/
{	char c;				/*宣告变数*/

       	read24c02();	                /*呼叫读取密码存放在DATE1[]副程式*/
	ptr=0xff;			
        for(c=0;c<6;c++)		/*将密码存放在阵列buft[]存入显示器存放阵列disple[]*/
      {
      	        disple[c]=bufdata[c];
      }
        while(m==P1);			/*判断按钮放开否,没有则在此等待*/
        clear();			/*有则呼叫清除显示器*/
}					
/*--------------------------------------*/
void scan(void)				/*扫描键盘副程式*/
 {
	char a1=0xf7,i;			/*A1=0XF7列扫描初值,I行*/
	speekclose();
        FLAG0=0;			/*设按键回应旗号为0,键盘扫描计数指标为0*/
        ptr=0;
        for(i=0;i<4;i++)		/*键盘4个扫描列*/
      {
      	        P1=a1;			/*列扫描输出,读入P1存入M,以便侦测行与侦测按键是否放开*/
                m=P1;
                switch(m&0xf0)		/*取行的高4位元,侦测那一行被按*/
            {
            	case 0x70: ptr=i*4;	/*第一行被按否?是则扫描指标=列X4*/
                           FLAG0=1;	/*是则设FLAG0=1表有按键输入*/
                           break;	/*跳出此循环*/
                case 0xb0: ptr=i*4+1;	/*第二行被按否?是则扫描指标=列X4+1*/
                           FLAG0=1;	/*是则设FLAG0=1表有按键输入*/
                           break;	/*跳出此循环*/	
                case 0xd0: ptr=i*4+2;	/*第三行被按否?是则扫描指标=列X4+2*/
                           FLAG0=1;	/*是则设FLAG0=1表有按键输入*/
                           break;	/*跳出此循环*/
                case 0xe0: ptr=i*4+3;	/*第四行被按否?是则扫描指标=列X4+3*/
                           FLAG0=1;	/*是则设FLAG0=1表有按键输入*/
                 default:  break;	/*跳出此循环*/
            }
         if(FLAG0==1)break;		/*不为1,则扫描列右移,扫描下一列*/
         a1=a1>>1|0x80;			/*高位补1,由于P1.7~P1.4未接+5V,而是由指令加载高电平*/
       }
 }					/*返回主程式*/
/*--------------------------------------*/
void service_int0 () interrupt 1 using 2   	/*设定每隔3000us中断扫描一次数码管*/
 {
        ptr1++;				/*扫描指标加1*/
        TH0=(65536-2000)/256;		/*每隔4000US扫描一次*/
        TL0=(65536-2000)%256;
        while (ptr1>5) ptr1=0;		/*ptr1>5表示6个数码管都已经扫描过*/
        P0=(ptr1<<4)|disple[ptr1];	/*将扫描值左移至高4位元再加上资料码*/
 }					/*返回主程式*/
/********************************************************/
void service_int1 () interrupt 3 using 3   	/*TIMER1中断副程式--秒计时器*/
 {
        TH1=(65536-9200)/256;		/*重设TIMER1计数值*/
        TL1=(65536-9200)%256;
        b1--;				/*中断次数减1*/
        if (b1==0)			/*中断次数完成否,是则表1秒到了*/
     {
        b1=200;				/*重设中断次数*/
        SEC++;				/*秒SEC加1*/
	tserial();			/*宣告串口serial发送副程式*/	
        BCD();				/*呼叫BCD码转换副程式*/
     }
 	TF1=0;
  }					/*返回主程式*/

/********************************************************/
void uartcom1_in1 () interrupt 4 using 1   	/*串行口中断副程式*/
 {	uchar v,i=0;
     while(RI!=1);			/*接收完成否*/	
      {	
 	RI=0;
	v=SBUF;				/*接收的数据存入C*/	
	disple[5]=disple[4];
	disple[4]=disple[3];
	disple[3]=disple[2];
	disple[2]=disple[1];
	disple[1]=disple[0];
	disple[0]=SBUF;

      }	

 }					/*返回主程式*/
/********************************************************/

⌨️ 快捷键说明

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