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

📄 2.c

📁 万年历 megal128 iccavr开发平台
💻 C
字号:
//李伟于9月3号完成
#include<iom128v.h>
/*定义OCMJ4X8端口*/
//DATA_PORT=PORTA
#define data_port PORTA
//ASK=PORTE.6
#define ask (PINE&0x40)
//ANSWER=PORTE.7
#define set_answer asm("sbi 0x03,7")
#define clr_answer asm("cbi 0x03,7")
//RESTE=PORTC.3
#define set_reset asm("sbi 0x15,3")
#define clr_reset asm("cbi 0x15,3")
#define wait  asm("nop\n nop")
unsigned char second=0,minute=0,hour=0,day=4,days=11,month=8;
unsigned int year=2005;
unsigned char flag=0;
unsigned char lcd_buff[4]={0,0,0,0};//放小时,分钟
unsigned char lcd_buff1[9]={0,0,0,0,0,0,0,0,0};//相当与一个地址,存放月,日
const unsigned char biao1[]={50,22,40,43,46,33,40,48,38,36,52,40};
const unsigned char biao2[]={27,94,93,36,69,89,53,39,58,74,34,53};
const unsigned char table[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46};
void delay(unsigned int x)
{
  unsigned int k;
  for(k=0;k<x;k++)
  ;
}
void ocmj_init(void)
{
 MCUCR=0;
 DDRA=0xff;
 PORTA=0xff;
 DDRE=0b10000000;
 PORTE=0xff;
 clr_reset;//LCD复位
 delay(10);
 set_reset;
 clr_answer;
 delay(2);
}
/**********************************************/
	 /* 写数据到LCD  */
/**********************************************/
void ocmj_write(unsigned char data)
{
 while(ask!=0)
  ;
 data_port=data;
 wait;
 set_answer;
 wait;
 while(ask==0)
  ;		
 clr_answer;
}
/**********************************************/
	 /* 写ASCII码初始化  */
/**********************************************/
void write_ASCII(unsigned type,unsigned xx,unsigned yy,unsigned data)
{
    ocmj_write(type);
    ocmj_write(xx);
    ocmj_write(yy);
    ocmj_write(data);
}
/**********************************************/
	 /* 写汉字初始化  */
/**********************************************/
void write_hazi(unsigned xx,unsigned yy,unsigned data1,unsigned data2)
{
    ocmj_write(0xf0);
    ocmj_write(xx);
    ocmj_write(yy);
    ocmj_write(data1);
	ocmj_write(data2);
}
/**********************************************/
	 /* 键盘子程序  */
/**********************************************/
unsigned char scan_key(void)
{
 unsigned char i,temp;
 DDRB=0x0f;	
 PORTB=0xff;	
 for(i=0;i<4;i++)
  {
   PORTB=~(1<<i); //键盘线扫描
   delay(30);   //等待低电平稳定
   temp=PINB&0xf0;//读取键盘扫描信号,屏蔽低四位
   if (temp!=0xf0)//如果有键按下,延时10ms消抖
    {              //本程序用display代替10ms延时,
     delay(3000); //可消除显示抖动
     temp=PINB&0xf0;//再读键盘
     if (temp!=0xf0)
      {
        temp&=0xf0;
        switch(temp) //计算键值
         {
		  case 0x70:temp=15-(3-i)*4;break;
          case 0xb0:temp=14-(3-i)*4;break;
          case 0xd0:temp=13-(3-i)*4;break;
          case 0xe0:temp=12-(3-i)*4;break;
          default:break;				
          }
		 return temp;
		}
	  }
    }
   return 0x00;//无键按下
}	
/**********************************************/
	 /* LCD显示小时分钟秒*/
/**********************************************/
void time_display(void)
{
write_ASCII(0xf9,4,0,table[hour/10]);//小时高位
write_ASCII(0xf9,5,0,table[hour%10]);//小时地位
write_ASCII(0xf9,6,0,58); //:
write_ASCII(0xf9,7,0,table[minute/10]);//分钟高位
write_ASCII(0xf9,8,0,table[minute%10]);//分钟地位
write_ASCII(0xf9,9,0,58); //:	
write_ASCII(0xf9,10,0,table[second/10]);//秒钟高位	
write_ASCII(0xf9,11,0,table[second%10]);//秒钟地位
}
/**********************************************/
	 /* LCD显示星期年月日*/
/**********************************************/
void day_display(void)
{
   write_hazi(7,0,biao1[7],biao2[7]);//星
   write_hazi(8,0,biao1[8],biao2[8]);//期
   write_hazi(4,1,biao1[9],biao2[9]);//年
   write_hazi(6,1,biao1[10],biao2[10]);//月
   write_hazi(8,1,biao1[11],biao2[11]);//日
   write_hazi(9,0,biao1[day-1],biao2[day-1]);//一,二,三,四,五,六,日
   write_ASCII(0xf9,4,16,table[year/1000]);//年第四位
   write_ASCII(0xf9,5,16,table[year%1000/100]);//年第三位		
   write_ASCII(0xf9,6,16,table[year%1000%100/10]);//年第二位
   write_ASCII(0xf9,7,16,table[year%1000%100%10]);//年第一位
   write_ASCII(0xf9,10,16,table[month/10]);//月份高位
   write_ASCII(0xf9,11,16,table[month%10]);//月份低位
   write_ASCII(0xf9,14,16,table[days/10]);//日期高位
   write_ASCII(0xf9,15,16,table[days%10]);//日期低位
}
/**********************************************/
	 /* 确定天数*/
/**********************************************/
unsigned char get_days(unsigned char yue)
{
    unsigned char tian;
    switch(yue)
    {
      case 1:
      case 3:
      case 5:
      case 7:
      case 8:
      case 10:
      case 12:tian=31;break;
      case 4:
      case 6:
      case 9:
      case 11:tian=30;break;
      case 2: if((year%4==0&&year%100!=0)||(year%400==0))tian=29;else tian=28;break;
      default:break;
     }
     return  tian;
}
/**********************************************/
	 /* 定时器初始化 1秒*/
/**********************************************/
void timer0_init(void)
{
 TCCR0 = 0x00; //stop
 ASSR = 0x08; //set async mode
 TCNT0 = 0x00; //set count
 TCCR0 = 0x05; //start timer
}
/**********************************************/
	 /* 定时器中断服务程序*/
/**********************************************/
#pragma interrupt_handler timer0_ovf_isr:17
void timer0_ovf_isr(void)
{
 second=second+1;
 if(second==60)
 {
    second=0;
	minute=minute+1;
	if(minute==60)
	{
	   minute=0;
	   hour=hour+1;
	   if(hour==24)
	   {
		 hour=0;
		 day=day+1;
		 if(day>7)
		  day=1;
		  days=days+1;
		  if(days>get_days(month))
		   {
		    days=1;
		    month=month+1;
			if(month>12)
			 {
			  month=1;
			  year=year+1;
			 }
		   }
		
	   }
    }
  }
  time_display();//显示小时,分钟
  if(flag==0)     //与最后面相照应 //如果没有标志位就不能起缓冲作用,边化快
  {
  day_display();//显示年月日
  }			
}
/**********************************************/
	 /*写显示*/
/**********************************************/
void lcd_time(void)
{
write_ASCII(0xf9,4,0,table[lcd_buff[0]]);//小时高位
write_ASCII(0xf9,5,0,table[lcd_buff[1]]);//小时地位
write_ASCII(0xf9,6,0,58); //:
write_ASCII(0xf9,7,0,table[lcd_buff[2]]);//分钟高位	
write_ASCII(0xf9,8,0,table[lcd_buff[3]]); //分钟地位
write_ASCII(0xf9,10,0,48);// 0
write_ASCII(0xf9,11,0,48);//0
}
void lcd_time1(void)
{
write_hazi(9,0,biao1[lcd_buff1[8]-1],biao2[lcd_buff1[8]-1]);//一,二,三,四,五,六,日
write_ASCII(0xf9,4,16,table[lcd_buff1[0]]);//年第四位
write_ASCII(0xf9,5,16,table[lcd_buff1[1]]);//年第三位		
write_ASCII(0xf9,6,16,table[lcd_buff1[2]]);//年第二位
write_ASCII(0xf9,7,16,table[lcd_buff1[3]]);//年第一位
write_ASCII(0xf9,10,16,table[lcd_buff1[4]]);//月份高位
write_ASCII(0xf9,11,16,table[lcd_buff1[5]]);//月份低位
write_ASCII(0xf9,14,16,table[lcd_buff1[6]]);//日期高位
write_ASCII(0xf9,15,16,table[lcd_buff1[7]]);//日期低位
}
/**********************************************/
	 /*查键盘*/
/**********************************************/	
unsigned char ks(void)
{
 unsigned char m,j;
 DDRB=0x0f;	
 PORTB=0xff;
 for(j=0;j<4;j++)
 {
 PORTB=~(1<<j);
 delay(50);
 m=PINB&0xf0;    //屏蔽低四位
 if(m!=0xf0)
  return 0xff;
 }
 return 0x00;
}
void main(void)
{
 unsigned char key,b=0,a=0;
 SREG=0x80;
 TIMSK=0x01;
 DDRA=0xff;
 PORTA=0xff;
 timer0_init();
 ocmj_init();//初始化	
 ocmj_write(0xf4);//清屏
 while(1)
 {
   while((ks()==0xff)&&(scan_key()==10))    //置时间,当有键按下,且键为10时,小时,分钟都置0
   {
     for(;;)
     {
      lcd_buff[0]=0;//小时
	  
	  lcd_buff[1]=0;
	  lcd_buff[2]=0;  //分钟
	  lcd_buff[3]=0;
	  lcd_time1();//显示小时,分钟
	  second=0;
      TCCR0=0x00;
	//**************************************  
	  delay(65000);                       //还不明白,有待继续考虑?????????
      if(ks()==0xff) break;      
	//*********************************  
     }
    while(1)
    {
	 if(ks()==0xff)
	 {
      key=scan_key();
      lcd_buff[b]=key;
      lcd_time();
      delay(65000);
      b++;
      if(b>3)//再怎么按也无效
	  {
	    hour=lcd_buff[0]*10+lcd_buff[1];
	    minute=lcd_buff[2]*10+lcd_buff[3];
	    TCCR0=0x05;//128分频
	    TCNT0=0x00;
        b=0;
	    break;
	  }
     }
    }
   }
   while((ks()==0xff)&&(scan_key()==11))     //置日历和星期//按下后,其显年,月,日,置0,星期置1
   {
	  flag=1;       
      for(;;)
      {
      lcd_buff1[0]=0; 
	  lcd_buff1[1]=0;
	  lcd_buff1[2]=0;
	  lcd_buff1[3]=0;
	  lcd_buff1[4]=0;
	  lcd_buff1[5]=0;
	  lcd_buff1[6]=0;
	  lcd_buff1[7]=0;
	  lcd_buff1[8]=1;
	  lcd_time1(); //显示年月,日,星期
	  delay(65000);
      if(ks()==0xff)//同上,有待考虑
      break;
      }
	  while(1)
	  {
	    if(ks()==0xff)  //有键按下
    {
         key=scan_key();
         lcd_buff1[a]=key;
	     lcd_time1();
         delay(65000);
         a++;
    	 if(a>8)    
	     {
  	       year=lcd_buff1[0]*1000+lcd_buff1[1]*100+lcd_buff1[2]*10+lcd_buff1[3];
	       month=lcd_buff1[4]*10+lcd_buff1[5];
	       days=lcd_buff1[6]*10+lcd_buff1[7];
	       day=lcd_buff1[8];
               a=0;
	       flag=0; //见显示部分
	       break;
	     }
        }
	  }
   }
 }	
}	

⌨️ 快捷键说明

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