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

📄 sy0406.c

📁 实现单片机led和矩阵数字键盘的控制 但是您必须要有深圳赛伯公司的at89s52开发板
💻 C
📖 第 1 页 / 共 2 页
字号:
//*******************************************************************
//***此程序为调试通过的源程序
//***由南京赛博电子有限公司提供
//***filename:SY0406.C***//
//***是在sy0306的功能上增加了AT89S52的在线下载功能
//***IIC总线芯片改为24C01
//***串口功能:由89S51键盘P1口发送资料数据“123456B7890”,在数码管
//上显示的同时由再由板上的RS232口上传到PC机上,在荧光屏上显示通信
//***反之也可以由PC的键盘上输入数字下载在单板机上显示出来。
//***定时器0--设定数码管定时扫描。
//***定时器1--设定时钟显示计时。
//***定时器2--设定串行通讯波特率。
//*******************************************************************
#include"at89x52.h"
#include<intrins.h>
#define  uchar unsigned char 	
#define  uint  unsigned int
#define  nop  _nop_()         		/* 定义空操作指令 */
sbit SCL=P3^4;				/*24C01 CSL接脚=89C51 T0 P3.4*/
sbit SDA=P3^5;				/*24C01 SDA接脚=89C51 T1 P3.5*/
bit FLAG0=0;				/*设定位标号FLAG0=1键盘扫描回应*/
bit FLAG1=1;				/*设定位标号20H.1比较密码回应旗号*/
char m,ptr=0,ptr1=0;			/*PTR键盘扫描指标,ptr1显示器扫描指标*/
char a1=0,b1=100,stand=0,m=0;		/*宣告变数a1为TIMER0的中断次数,ptr为TIMER1扫描数码管指标*/
bit TSendAddress(uchar slaaddress,uchar subaddress,uchar * s,uchar no); /* 向有子地址器件写入6字节数据函数 */
bit TRcvAddress(uchar slaaddress,uchar subaddress,uchar * s,uchar no);  /* 向有子地址器件读取6字节数据函数 */
bit acknow;	         		/* 应答标志位 acknow=1 表示正常响应 acknow=0 表示未响应 */
static const char tab[16]={0x01,0x02,0x03,0x0c,	/*键盘码00,01,02,03,*/
                           0x04,0x05,0x06,0x0d,	/*键盘码04,05,06,07,*/
                           0x07,0x08,0x09,0x0e,	/*键盘码08,09,0a,0b,*/
                           0x0a,0x00,0x0b,0x0f};/*键盘码0c,0d,0e,0f*/
static const char tab1[6]={0x08,0x08,0x08,0x08,0x08,0x08};/*内定密码"888888"*/
char HOUR=12;MIN=0;SEC=0;		/*变量数,初始时间设定为12:00:00*/
char disple[8];				/*显示值存放阵列*/
char bufdata[9];	
char bufuart[6];			/*串口接收值存放阵列*/
void delay (unsigned int value)		/*延时副程式*/
 {
      while (value!=0) value--;		/*10US延时*/
 }
void BCD(void);				/*BCD码转换副程式*/
void scan(void);			/*键盘扫描副程式*/
void clear(void);			/*清除按键存放/显示器阵列disple[]副副程式*/
void open(void);			/*开门比较密码副程式*/	
void read24c02();  			/*读24c02的存储值*/
void write24c02();			/*写24c02的存储值*/
void IICSAVE(void);			/*设定密码并存入buft[]阵列副程式*/
void disp(void);			/*显示存放在disple[]阵列的密码副程式*/	
void tserial(void);			/*串口serial发送副程式*/	
void rserial(void);			/*串口serial接收副程式*/	
void temp(void);
void Start();                           /* 起动总线函数 */
void Stop();                            /* 结束总线函数 */
void SendByte(uchar c);                 /* 8951发数据或地址给8583 字节数据发送函数 */
uchar RcvByte();                        /* 8951从24C01读数据字节数据接收函数 */
void Ack(bit a);                        /* 主机8951应答子函数 */
void xch(void);				/*宣告按键存放/显示器阵列disple[]右键滚入副程式*/	
void speekclose(void);
/*********************************************************************/
main()					/*主程式*/
{
 	TMOD=0x21;			/*TIMER0工作在案MODE1,16位定时器*/
					/*TIMER1工作在MODE2,自动重新装载模式*/
       					/*方式寄存器TMOD___________________________*/
       					/*|    定时器1        |     定时器1       |*/
       					/*| GATE|C/T| M1 | M0 | GATE|C/T| M1 | M0 |*/
       					/*|___________________|___________________|*/
	TH1=256-(28800/9600);		/*设定传输波特率9600,晶体振荡器=11.059Mhz*/
					/*|波特率9600时|SMOD=0|C/T=0|模式=2|自动载入TH1=FD|*/		
					/*|波特率4800时|SMOD=0|C/T=0|模式=2|自动载入TH1=FA|*/
					/*|波特率2400时|SMOD=0|C/T=0|模式=2|自动载入TH1=F4|*/
					/*|波特率1200时|SMOD=0|C/T=0|模式=2|自动载入TH1=E8|*/
       TH0=(65536-3000)/256;		/*设定每隔3000us中断扫描一次数码管*/
       TL0=(65536-3000)%256;
       TR0=1;				/*启动TEMER0*/
//	T2MOD=0x02;			/*定时器2工作在输出模式*/
	T2CON=0x38;			/*定时器2工作控制寄存器T2CON_________________*/
       					/*| TF2|EXF2|RCLK|TCLK|EXEN2|TR2|C/T2|CP/RL2|*/
       					/*|___________________|_____________________|*/
	TL2=0xfd;			/*设定传输波特率9600,晶体振荡器=11.059Mhz*/
	TH2=0xff;			/*设定传输波特率9600,晶体振荡器=11.059Mhz*/
	RCAP2L=0xdc;			/*设定传输波特率9600,晶体振荡器=11.059Mhz*/
	RCAP2H=0xff;			/*设定传输波特率9600,晶体振荡器=11.059Mhz*/
	TH2=256-(28800/9600);		/*设定传输波特率9600,晶体振荡器=11.059Mhz*/
					/*|波特率9600时|SMOD=0|C/T=0|模式=2|自动载入TH1=FD|*/		
					/*|波特率4800时|SMOD=0|C/T=0|模式=2|自动载入TH1=FA|*/
					/*|波特率2400时|SMOD=0|C/T=0|模式=2|自动载入TH1=F4|*/
					/*|波特率1200时|SMOD=0|C/T=0|模式=2|自动载入TH1=E8|*/
        TR2=1;				/*启动TEMER2*/
	SCON=0x50;			/*设定UART工作在MODE3模式,可传送和接收数据 REN=1*/
					/*串列控制寄存器SCON_______________________*/
       					/*|  7    6    5    4 |  3    2    1    0 |*/
       					/*| SM0| SM1| SM2| REN| TB8| RB8| TI | RI |*/
       					/*|___________________|___________________|*/
        IE=0x9f;			/*8是允许中断,a是TIMER0,TIMER1中断致能位*/
					/*|  7    6    5    4 |  3    2    1    0 |*/
       					/*| EA |    | ET2| ES | ET1| EX1| ET0| EX0|*/
       					/*|___________________|___________________|*/
        IP=0x10;			/*中断优先级寄存器IP_______________________*/
       					/*|    |    | PT2| PS | PT1| PX1| PT0| PX0|*/
       					/*|___________________|___________________|*/
       read24c02();			/*呼叫读取密码存放在DATE1[]副程式*/
       clear();				/*清除数码管,显示为000000副程式*/
       P2_0=1;				/*关喇叭灭指示灯*/
  while(1)
	{
	scan();    	 		/*呼叫键盘扫描副程式有按FLAG0会为1*/
	if(FLAG0==1) temp();		/*判断有按键输入否?*/
	delay(300);
	nop;
	}
}
/***********************************************************************/
void temp(void)
{
	if(tab[ptr]==0x0e) disp();	/*如果是按“C”则呼叫显示密码DISP*/
		else			/*否则往下执行*/
        {
        switch(tab[ptr])		/*是则测试ptr键盘扫描计数器指标至TAB[]取到的键盘码*/
             {
          case 0x0a: 
          		write24c02();	/*是否按“*”是则呼叫设定密码SET*/
          		clear();	/*是否按“#”是则呼叫清除显示器CLEAR*/
                     break;		/*跳出此循环*/
          case 0x0b: 
          		clear();	/*是否按“#”是则呼叫清除显示器CLEAR*/
                     break;		/*跳出此循环*/
          case 0x0c:			/*是否按“A”,未规划键待用户自己定义*/
          	     break;		/*跳出此循环*/
          case 0x0d:			/*是否按“B”,未规划键待用户自己定义*/	
                     break;		/*跳出此循环*/
          case 0x0e:			/*是否按“C”,已侦测过*/	
                	read24c02();	/*呼叫读取密码存放在DATE1[]副程式*/
                     break;		/*跳出此循环*/                    
          case 0x0f: open();		/*是否按“D”,是则呼比较密码开门副程式*/
                     break;		/*跳出此循环*/
          default:   xch();		/*以上均不是则为数字键呼叫XCH作右键滚入*/
                     break;		/*跳出此循环*/
             }				/*跳出SWITCH*/
        delay(100);			/*按钮抗机械反弹跳*/
        while(m==P1);			/*按钮放开否?*/
        delay(100);
      	}				
 }  
/****************************************************/
void xch(void)				/*显示向右移动副程式*/
 {
     char c;				/*宣告变数*/
     for(c=5;c>0;c--)
     {
     	disple[c]=disple[c-1];		/*将显示器disple[]移位交换,disple[3]->disple[4]->disple[5]...*/
     }
     disple[0]=tab[ptr];		/*新的按键值存入disple[0]*/
 }					/*返回主程式*/
/******************************************************/
void clear(void)			/*清除显示器disple[]为00副程式*/
 {
     char c;				/*宣告变数*/
     for(c=0;c<6;c++)			/*将00存入显示阵列disple[]*/
     {
     	disple[c]=0x00;
     }					/*返回主程式*/
 }
/******************************************************/
void read24c02()			/*读24c02的存储值*/
{
   uchar i;
   
   TRcvAddress(0xa0,0,&bufdata[0],6);  
    
   for(i=0;i<6;i++)
    {
     disple[i]=bufdata[i];
    }
}
/******************************************************/
void write24c02()			/*写24c02的存储值*/
{
//   uchar i;
   TSendAddress(0xa0,0,disple,6);	 /* 向有子地址器件写入6字节数据函数 */

}
//**************************************************************
void tserial(void)			/*宣告串口serial发送副程式*/	
{
 uchar i=6;
     IE=0x8f;
     {while(i>0)
	{
	i--;
	SBUF=disple[i];		/*根据扫描指标到TAB中取ASCII码由SBUF发送出去*/
	while(TI!=1);			/*发送完成否?*/
	TI=0;				/*是,则清除发送完成旗标TI=0*/
 	delay(10);
	}
     }  
     IE=0x9f;
}

/*--------------------------------------*/
void BCD(void)				/*BCD码转换副程式*/
   {
    char c1;				/**/
    c1=SEC;				/*除60取余数为SEC秒*/
    SEC=c1%60;				/*除60取余数为SEC秒*/
    c1=MIN+c1/60;			/*"分"加上秒的进位*/
    MIN=c1%60;				/*除60取余数为MIN分*/
    HOUR=(HOUR+c1/60)%24;		/*"时"加上分的进位除24取余数为HOUR时*/
    disple[0]=(SEC%10);			/*取秒的个位数存入disple[0]*/
    disple[1]=(SEC/10);			/*取秒的十位数存入disple[1]*/
    disple[2]=(MIN%10);			/*取分的个位数存入disple[2]*/
    disple[3]=(MIN/10);			/*取分的十位数存入disple[3]*/
    disple[4]=(HOUR%10);		/*取时的个位数存入disple[4]*/
    disple[5]=(HOUR/10); 		/*取时的十位数存入disple[5]*/
    }
/*******************************************************************
                     起动总线函数               
函数原型: void  Start();  
功能:     启动总线,发送24c02启动条件.  
********************************************************************/
void Start()
{SDA=0;
nop;
nop;
   SCL=0;
   SDA=1;   	/*发送起始条件的数据信号*/
   nop;
   SCL=1;
   nop;    	/*起始条件建立时间大于4.7us,延时*/
   nop;
   nop;
   nop;
   nop;    
   SDA=0;   	/*发送起始信号*/
   nop;    	/* 起始条件锁定时间大于4us*/
   nop;
   nop;
   nop;
   nop;       
   SCL=0;   	/*钳住总线,准备发送或接收数据 */
   nop;
   nop;
   SDA=1;
}
/*******************************************************************
                      结束总线函数               
函数原型: void  Stop();  
功能:     结束总线,发送24c02结束条件.  
********************************************************************/
void Stop()
{
  SCL=0; 
  SDA=0;  	/*发送结束条件的数据信号*/
  nop;   	/*发送结束条件的时钟信号*/
  SCL=1;  	/*结束条件建立时间大于4us*/
  nop;
  nop;
  nop;
  nop;
  SDA=1;  	/*发送总线结束信号*/
  nop;
  nop;
  nop;
  nop;
  SCL=0;
}
/*******************************************************************
                 89C51发数据或地址给24c02 字节数据发送函数               
函数原型: void  SendByte(uchar c);
功能:     将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对
          此状态位进行操作.(不应答或非应答都使acknow=0)     
     	  发送数据正常,acknow=1; acknow=0表示被控器无应答或损坏。
********************************************************************/
void  SendByte(uchar c)
{
 uchar count;
 
 for(count=0;count<8;count++)  /*要传送的数据长度为8位*/
    {
      if((c<<count)&0x80)
         SDA=1;                /*判断发送位*/
      else  
         SDA=0;                
     
     nop;
     SCL=1;               /*置时钟线为高,通知被控器开始接收数据位*/
      nop; 
      nop;             /*保证时钟高电平周期大于4us*/
      nop;
      nop;
      nop;         
     SCL=0; 
    }
    
    nop;

⌨️ 快捷键说明

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