📄 2.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 + -