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

📄 texiandclock.c

📁 采用直流电机测速单元模拟出租车速度
💻 C
字号:
#include<reg51.h>
#include <math.h>
#include <intrins.h>
#include <absacc.h>
#define uchar unsigned char
#define uint unsigned int
/* DS12887实时时钟时间地址设置 */
#define second XBYTE [0x6000]    /* 秒寄存器地址 */
#define sec_alarm XBYTE [0x6001]
#define minute XBYTE [0x6002]    /* 分寄存器地址 */
#define min_alarm XBYTE [0x6003]	
#define hour XBYTE [0x6004]	 /* 小时寄存器地址 */	
#define week XBYTE [0x6006]      /* 星期寄存器地址 */			
#define date XBYTE [0x6007]	 /* 日期寄存器地址 */		
#define month XBYTE [0x6008]     /* 月寄存器地址 */		
#define year XBYTE [0x6009]      /* 年寄存器地址 */	
#define rega XBYTE [0x600A]      /* A寄存器地址 */
#define regb XBYTE [0x600B]      /* B寄存器地址 */
#define regc XBYTE [0x600C]      /* C寄存器地址 */
#define regd XBYTE [0x600D]      /* D寄存器地址 */
/* RT12864HZ汉字图形点阵液晶地址设置 */
#define w_c_add XBYTE[0x2070]  /* 写命令字地址 */
#define w_d_add XBYTE[0x2071]  /* 写数据地址   */
#define r_s_add XBYTE[0x2072]  /* 读状态字地址 */ 
#define r_d_add XBYTE[0x2073]  /* 读数据地址   */
#define COM XBYTE[0x2021]      /*8279命令口    */
#define DAT XBYTE[0x2020]      /*8279数据口    */  
#define L      1               /*长度系数      */
#define TI     50            /*分度数*/
#define HN     30              /*孔个数        */  
#define LOW    30             /*最低速度      */
uchar xdata key;                /*键值          */
uint idata num=0;              /*计数值        */    
uint xdata a=1,b=0;
uint idata len,fa,m,n,o,p,q,r,s,t,COUT,CLO;
uint idata h1,h2,m1,m2,s1,s2;   /*时钟参数*/      
uint idata price=10,fate=00,length=0,leng;
uint idata state=0,clear=1,begin=0,pri,tim,tt=0,cc=0;nn=0;/*几个状态标志位*/
       /*设置,清除,开始计价,单价修改,时间修改,两位数监视,六位数监视,数字标志*/
unsigned char bdata status; /* lcd可位寻址片内数据存储器,允许位与字节混合访问 */
sbit busy=status^7;   /*lcd“忙”线的第7位*/
uchar bdata sta_8279;  /*8279*/
sbit du=sta_8279^7;    /* 8279方式设置命令字 */
unsigned char rflag;
unsigned char bdata sta_ds;
sbit uip=sta_ds^7;
uchar ds_h,ds_m,ds_s,ds_t;
unsigned char bdata ds_time;
unsigned char code NO[10]={0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9};
uchar code tab[16]={0x3f,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,
                            0x71,0x7C,0x39,0x73,0x31,0x71};/* 0~F的字型编码*/
uchar xdata hz2[16]={0xB5,0xA5,0xBC,0xDB,0xA3,0xBA,0x20,0x20,0x20,0x20,
	                 /* 单        价        :   空             空  */
	              0xA3,0xB0,0xA3,0xB0,0xD4,0xAA};
                     /*   N        N         元  */ 
uchar xdata hz3[16]={0xBE,0xE0,0xC0,0xEB,0xA3,0xBA,0xA3,0xB0,0xA3,0xB0,
	             /*     距         离        :       空          N  */
	                0xA3,0xB0,0xA3,0xB0,0x4B,0x4D};
                     /*     N         N       k   m   */
uchar xdata hz4[16]={0xBC,0xDB,0xC7,0xAE,0xA3,0xBA,0xA3,0xB0,0xA3,0xB0,
	                /* 价         格         :        N         N  */
	                0xA3,0xB0,0xA3,0xB0,0xD4,0xAA};
                    /*   N        N        元 */ 

uchar xdata hz5[16]={0x20,0x20,0xCA,0xE4,0xC8,0xEB,0xC1,0xBD,0xCE,0xBB,
	             /*   空      输         入        两        位  */
	                0xB5,0xA5,0xBC,0xDB,0x20,0x20};
                     /*     单        价        空 */
uchar xdata hz6[16]={0x20,0x20,0x20,0x20,0xA3,0xBA,0xA3,0xB0,0xA3,0xB0,
	            /*  空         空        :        N         N  */
	                0xD4,0xAA,0xA3,0xAF,0x4B,0x4D};
                    /*          元         /    k    m */ 
void initial (void);
void delay(void);
void check_lcd(void);
void show_lcd(uchar *,uchar *,uchar *);
void lcd_busy(void);  /*LCD忙状态检测函数 */
void compute(void);
void change_pri(void);
void change_time(void);
void clock(void);
void check_ds12887(void);
main()
{ 
  uint inf=0;
  initial();  
  show_lcd(hz2,hz3,hz4);
  while(1)
 { 
   clock();
   if(begin==1)
  	{ 
  	  if(inf==0)
  	    {
  	    	fate=20;
  	    	inf=1;
  	    }
 	  if(state==0)
       { 
  	     if(num>=LOW)
  	       {   
  	      	   COUT=0;
  	           price=a*10+b;
               len+=num*L/HN;
               if(len/TI>=0)
                  {
               	      leng=len/TI;
               	      len%=TI;
                  }
               fa=leng*price;      
               length+=leng;
               leng=0;
               fate+=fa;
  	        }  	     
  	      else 
  	         {
  	            if(COUT>=60)
     	         {
     	            length++;
     	            fate+=(10*a+b);
 	                COUT=0;
 	             }
  	          }
  	     compute();
  	   	 show_lcd(hz2,hz3,hz4);
  	   }
      else 
         { 
         	if(pri==1)
         	     change_pri();
             if(tim==1) 
                 change_time(); 
            
          }
     }
     
   if(clear==1)
     {   
     	 length=0;
     	 fate=0; 
     	 inf=0; 
     	// COM=0xd1; /* 清除显示*/
     	compute(); 
     	show_lcd(hz2,hz3,hz4);
     	if(pri==1)
         	     change_pri();
        if(tim==1) 
                 change_time();  	 
     }  
  
  }//while(1)
}//main  

/********************以下是程序(包括中断)********************************/
void keybord(void) interrupt 0  using 1
{
   uchar keyboard=0;
   EX0=0;                
   COM=0x50;
   keyboard=DAT; 
   keyboard &=0x0f; /* 保留低四位 */
   switch(keyboard)
     { case 0x0:  key=0; tt++;nn=1;cc++; break;
       case 0x1:  key=1; tt++;nn=1;cc++; break;
       case 0x2:  key=2; tt++;nn=1;cc++; break;
       case 0x3:  key=3; tt++;nn=1;cc++; break;
       case 0x4:  key=4; tt++;nn=1;cc++; break; 
       case 0x5:  key=5; tt++;nn=1;cc++; break;
       case 0x6:  key=6; tt++;nn=1;cc++; break; 
       case 0x7:  key=7; tt++;nn=1;cc++; break; 
       case 0x8:  key=8; tt++;nn=1;cc++; break;  
       case 0x9:  key=9; tt++;nn=1;cc++; break; 
       case 0x0B: key=11; begin=1;clear=0;nn=0;break;         /*B begin*/
       case 0x0C: key=12; clear=1;begin=0;nn=0;break;         /*C clear*/
       case 0X0D: key=13; state=1;pri=1;tim=0;nn=0;break;     /*D set price*/
       case 0x0E: key=14; state=1;tim=1;pri=0;nn=0;break;     /*E set time*/
       default:   key=15; nn=0;break;                         /*F finish*/ 
     }  
       keyboard=tab[keyboard];
       if(pri==1)
          if(nn==0)
             COM=0x80+8;
          else
             COM=0x80+4+tt;
      if(tim==1)
          if(nn==0)
             COM=0x80+8;
          else
             COM=0x80+1+cc; 
      DAT=keyboard;          
      EX0=1;
}

void int1serve() interrupt 2 using 2
{
	unsigned char temp2;
	COUT++;
        EX1=0;	
	rflag=1;
	sta_ds=rega;
	while(uip);
	ds_h=hour;
	ds_m=minute;
	ds_s=second;
	temp2=regc;
	rflag=0;
	EX1=1;
}

void timer(void) interrupt 3 using 3
{
   TR1=0;
   TR0=0;
   num=TH0*256+TL0;
   TH0=0;
   TL0=0;
   TH1=-(50000/256);
   TL1=-(50000%256);   
   CLO++;   
   TR1=1;
   TR0=1;     
}

void initial(void)
{
    COM=0xd1; /* 清除显示*/
    ACC=DAT;
    if(ACC^1);  /* P奇偶标志。若值为1的位数为奇数,则P置位,否则清除 */
    COM=0x00; /* 8字符显示左入口 */
    COM=0x34; /* 34次分频*/	
    TMOD=0X15;
    TH0=0;
    TL0=0;
    TH1=-(50000/256); 
    TL1=-(50000%256);
    TR0=1;
    TR1=1;
    EA=1;
    EX0=1;
    EX1=1;
    ET1=1;
    check_ds12887();
}

void delay(void)
{
  unsigned char i,j;
  for(i=0;i<100;i++)
  {
    for(j=0;j<150;j++)
    {
     ;
     ;
    }
  }
}

void check_lcd(void)
{   
	uint i;    
	lcd_busy();
	w_c_add=0x30;/* 功能设置:8位数据 */
	for(i=0;i<255;i++)
	lcd_busy();
	w_c_add=0x0c; /* 显示状态:整体显示,游标位置无效*/
	lcd_busy();
	w_c_add=0x01;/* 清除显示:将DDRAM填满“20H”,并且设定DDRAM的地址计数器到“00”*/
	lcd_busy();
	w_c_add=0x02;/* 地址归位:设定DDRAM的地址计数器到“00”,将游标移到开头原点位置 */
}

void show_lcd (uchar *b1,uchar *c1,uchar *d1)
{
	unsigned char add;
	unsigned char i;
    check_lcd();
  	lcd_busy();
	add=0x90;    /* 设置显示坐标,90H对应字符的第二行第一列 */
  	lcd_busy();
	w_c_add=add; /* 送命令 */
	for(i=0;i<8;i++)
	{
  	   lcd_busy();
       w_d_add=b1[2*i];
       lcd_busy();	
	   w_d_add=b1[2*i+1];
	}
    add=0x88;    /* 设置显示坐标,88H对应字符的第三行第一列 */
    lcd_busy();
	w_c_add=add; /* 送命令 */
	for(i=0;i<8;i++)
	{
       lcd_busy();
       w_d_add=c1[2*i];
       lcd_busy();	
       w_d_add=c1[2*i+1];
	}
    add=0x98;    /* 设置显示坐标,98H对应字符的第四行第一列 */
  	lcd_busy();
	w_c_add=add; /* 送命令 */
	for(i=0;i<8;i++)
	{
  	   lcd_busy();
       w_d_add=d1[2*i];
       lcd_busy();	
	   w_d_add=d1[2*i+1];
	}
    delay();
    clock();

}

void lcd_busy(void)   /*LCD忙状态检测函数 */
{
	do 
	{
  	  status=r_s_add;  /* 读状态字地址的第7位   */
	}	
	while(busy);
}

void compute(void)
{
	 uint f1,l1; 
	 f1=fate;
     l1=length;
     p=l1%10; /*数字位拆分**路程*/
     l1/=10;
     o=l1%10;
     l1/=10;
     n=l1%10;
     l1/=10;
     m=l1%10;
     t=f1%10; /*数字位拆分**价钱*/
     f1/=10;
     s=f1%10;
     f1/=10;
     r=f1%10; 
     f1/=10;
     q=f1%10;       
     hz2[11]=hz2[13]=0xB0;       /*清零*/
     hz3[9]=hz3[11]=hz3[13]=0xB0;       
     hz4[9]=hz4[11]=hz4[13]=0xB0;       
     hz2[11]+=a;                 /*赋值*/  
     hz2[13]+=b;
     hz3[7]+=m;
     hz3[9]+=n;
     hz3[11]+=o;
     hz3[13]+=p;
     hz4[7]+=q;
     hz4[9]+=r;
     hz4[11]+=s;
     hz4[13]+=t;
     if(COUT%500==0)
       {
          show_lcd(hz2,hz3,hz4);   /*显示*/ 	 
       }	
}

void change_pri()
{
	 show_lcd(hz2,hz5,hz6);
     if(key==15)  //15  -> Finish
        {
        	COM=0xd1; /* 清除显示*/   
            pri=0;
            state=0;  
            tt=0;
            hz2[11]=hz6[7];
            hz2[13]=hz6[9];                        
            show_lcd(hz2,hz3,hz4);
         }  
     else 
        {   
           if(nn) 
             {                    	
           	    if(tt==1)  a=key;
           	    if(tt==2){b=key;tt=0;}  
           	    hz6[7]=0xB0;
                hz6[7]+=a;
                hz6[9]=0xB0;
                hz6[9]+=b;
              }
            show_lcd(hz2,hz5,hz6);                      
        }
}

void change_time(void)
{    
	uint hh,mm,ss,temper;
    if(key==15)
      {
         tim=0;
         state=0; 
         cc=0; 
         COM=0xd1; /* 清除显示*/         
       }
    else
        { if(nn) 
            {                    	
           	   if(cc==1)  h1=key;
           	   if(cc==2)  h2=key;
           	   if(cc==3)  m1=key;
           	   if(cc==4)  m2=key;
           	   if(cc==5)  s1=key;
           	   if(cc==6)  {s2=key;cc=0;} 
           	   temper=h1*16;
           	   hh=temper|h2;
           	   temper=m1*16;
           	   mm=temper|m2;
           	   temper=s1*16;
           	   ss=temper|s2;
           	   hour=hh;
	           minute=mm;	
        	   second=ss;           	                 
             }
          clock();
          show_lcd(hz2,hz3,hz4);    
       }
}

void clock()
{
        unsigned char temp1;
		if (rflag==0)
		{
		w_c_add=0x80;      /* 写命令字:设定DDRAM地址到地址计数器(AC) */
		delay();
		temp1=ds_h & 0xf0; /* 小时保留高四位 */ 
		ds_t=_cror_(temp1,4); /* 将变量temp1循环右移4位 */
		lcd_busy();
		w_d_add=0xA3;
		lcd_busy();
		w_d_add=NO[ds_t]; /* 写数据*/
		ds_t=ds_h & 0x0f;  /* 小时保留低四位 */ 
		lcd_busy();
		w_d_add=0xA3;
		lcd_busy();
		w_d_add=NO[ds_t]; /* 写数据**小时*/
		lcd_busy();
		w_d_add=0xA3;      /*  :  */
		lcd_busy();
		w_d_add=0xBA;
		temp1=ds_m & 0xf0;
		ds_t=_cror_(temp1,4);
		lcd_busy();         
		w_d_add=0xA3;
		lcd_busy(); 
		w_d_add=NO[ds_t];    /* 写数据**分*/
		ds_t=ds_m & 0x0f;
		lcd_busy();
		w_d_add=0xA3;
		lcd_busy(); 
		w_d_add=NO[ds_t];
		lcd_busy();
		w_d_add=0xA3;      /*  :  */
		lcd_busy();
		w_d_add=0xBA;
		temp1=ds_s & 0xf0;
		ds_t=_cror_(temp1,4);
		lcd_busy();
		w_d_add=0xA3;
		lcd_busy(); 
		w_d_add=NO[ds_t];     /* 写数据**秒*/
		ds_t=ds_s & 0x0f;
		lcd_busy();
		w_d_add=0xA3;
		lcd_busy(); 
		w_d_add=NO[ds_t];
		for(temp1=0;temp1<255;temp1++);
		delay();
		delay();
	}
    
}

void check_ds12887(void)
{
	unsigned char temp;
	rega=0x2f;  /* 开启震荡器,允许计时 */
	delay();
	regb=0x80;
	temp=regc;
	temp=regd;
	//write time
	second=0x00;
	minute=0x00;	
	hour=0x12;
	week=0x01;
	year=0x03;
	month=0x12;
	regb=0x42;
	//open ex1
	EX1=1;
}
/***********************以上是代码**************************/


⌨️ 快捷键说明

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