📄 main.c
字号:
/*-----------------------------------------------------*
*工 程 名:
*硬件连接:
*程序描述: SD-HC08 模板生成
*/
/*[头文件]*/
#include "GP32C.h" //映像寄存器地址头文件
#include "clock.h"
unsigned char ch[]={"please set time!Epress 'B'E"};
unsigned char c[]={"time out!EGet up!E"};
unsigned char init[]={"0000-00-00E00:00:00E"};
unsigned char show[32]={' '};
unsigned char timer[2];
unsigned char time[3];
unsigned int date[3];
unsigned char out;
unsigned char timertem[4];
unsigned char timetem[4];
unsigned char datetem[8];
unsigned char showtime;
unsigned char istimer;
unsigned char issettime;
/*[主函数]*/
void main(void){
asm("SEI");
showtime=0x01;istimer=0x00;issettime=0;//模式初始化
DDRD=0x01;out=1; //闹钟接口初始化
timer[0]=0;timer[1]=0; //闹钟\时间初始化
time[0]=0;time[1]=0;time[2]=0;
date[0]=0;date[1]=0;date[2]=0;
LcdInit(); //LCD显示初始化
KB_Init(); //键盘初始化
INTKBSCR&= ~(1<<IntBit); //开放键盘中断(IMASKk=1)
PTD=0;
Timer1init(); //定时器初始化
asm("CLI");
while(1){
if(timer[0]==time[0]&&timer[1]==time[1]&&istimer==0x01){//闹钟启动//开始响铃60秒
showtime=0; //关闭时间显示
lcdshow((unsigned char *)c);
beep(2);
showtime=1; //开时间表显示
}
}
}
unsigned char isadddate1(void){//每月天数不一,判断对应月加1
unsigned char in=0x00;
if((date[1]==1||date[1]==3||date[1]==5||date[1]==7||date[1]==8||date[1]==10||date[1]==12)&&date[2]>=32)
in=0x01;
else if((date[1]==4||date[1]==6||date[1]==9||date[1]==11)&&date[2]>=31)
in=0x01;
else if((date[1]==2&&date[0]%4==0)&&date[2]==29)in=0x01;
else if((date[1]==2&&date[0]%4!=0)&&date[2]==28)in=0x01;
return in;
}
void addtime(void){ //日期,时间累加函数
unsigned char in;
time[2]++; //秒数加1
if (time[2]>=60){ //秒数未增加到60,转
time[2]=0; time[1]++; //秒数增加到60,清0,分钟数加1
}
if (time[1]>=60){ //分钟数未增到60,转
time[1]=0; time[0]++; //分钟数增加到60,清0,小时数加1
beep(1);
}
if (time[0]>=24){ //小时数未增到24,转
time[0]=0; //时数增加到24,清0
date[2]++;
}
in=isadddate1();
if(in==0x01){ //满足月份加1
date[1]++; //月份加1
date[2]=1; //天回1
}
if(date[1]>=13){ //月大于12
date[0]++; //年加1,月回1
date[1]=1;
}
}
void displaytime(void){ //显示时间处理
if(showtime==0x01){ //可显示时才处理
unsigned char i=0,j,c[4];
int temp=date[0];
for(j=0;j<4;j++){ //年中的四位处理,放临时变量
c[j]=(char)(temp%10);
temp/=10;
}
for(j=0;j<4;j++){ //年存到显示单元中
show[i]=c[3-j]+0x30;i++;
}
show[i]='-';i++;
for(j=0;j<2;j++){ //月日存到显示单元中
show[i]=(char)date[j+1]/10+0x30;i++;
show[i]=(char)date[j+1]%10+0x30;i++;
if(j==0){show[i]='-';i++;}
}
show[i]='E';i++; //换行
for(j=0;j<3;j++){ //时,分,秒存到显示单元中
show[i]=0x30+(time[j]/10);i++;
show[i]=0x30+(time[j]%10);i++;
if(j==2)break;
show[i]=':';i++;
}
show[i]='E';
lcdshow((unsigned char *)show); //显示日期时间
if(istimer==0x01)lcdshow1('*',0x4C); //闹钟开关标志
}
}
void shilfL(void){ //在设置状态下光标左移
if(showtime==0x00){
unsigned char data;
LcdCtrl&=~(1<<LcdRS); //RS、R/W=01,读指令
LcdCtrl|=(1<<LcdRW);
LcdCtrl|=(1<<LcdE); //E=1
data=LcdData;
data&=0b01111111;
data--;
if(data==0x04||data==0x07||data==0x42||data==0x45)data--;
if(data==0x3f)data=0x09;
if(data==0xff)data=0x47;
data|=0b10000000; //写AC地址指令
LcdCtrl&=~(1<<LcdRS); //RS、R/W=00,写指令
LcdCtrl&=~(1<<LcdRW);
Lcd_Command(data); //AC地址减1后写AC地址
}
}
void shilfR(void){ //在设置状态下光标右移
if(showtime==0x00){
unsigned char data;
LcdCtrl&=~(1<<LcdRS); //RS、R/W=01,读指令
LcdCtrl|=(1<<LcdRW);
LcdCtrl|=(1<<LcdE); //E=1
data=LcdData;
data&=0b01111111;
data++;
if(data==0x04||data==0x07||data==0x42||data==0x45)data++;
if(data==0x0A)data=0x40;
if(data==0x48)data=0x00;
data|=0b10000000; //写AC地址指令
LcdCtrl&=~(1<<LcdRS); //RS、R/W=00,写指令
LcdCtrl&=~(1<<LcdRW);
Lcd_Command(data); //AC地址减1后写AC地址
}
}
void settime(void){ //进入时间设置
unsigned char i;
for(i=0;i<8;i++)datetem[i]=0;
for(i=0;i<4;i++)timetem[i]=0;
issettime=0x01; //时间设置位置1
showtime=0x00; //时间显示位置0,不显示时间
lcdshow((unsigned char *)init);
LcdCtrl&=~(1<<LcdRS); //RS、R/W=00,写指令
LcdCtrl&=~(1<<LcdRW);
Lcd_Command(0b00001111); //开显示,开光标,闪烁
Lcd_Command(0b10000000); //后7位为DDRAM地址0x00
}
void sastimer(void){ //开始或关闭闹钟标志
unsigned char i;
for(i=0;i<4;i++)timertem[i]=0;
if(istimer==0x00){ //若关则开
istimer=0x01; //标志开
lcdshow1('*',0x4C); //显示'*'
}
else if(istimer==0x01){ //若开则关
istimer=0x00; //标志关
lcdshow1(' ',0x4C); //无显示
}
}
void settimer(void){ //进入闹钟设置
if(issettime==0){
unsigned char i=0,j;
showtime=0x00; //时间显示位置0,不显示时间
istimer=0x01; //开闹钟设置标志
lcdshow1('*',0x4C); //显示'*'
show[i]='E';i++; //第一行不显示
for(j=0;j<3;j++){
show[i]=0x30+(timer[j]/10);i++;
show[i]=0x30+(timer[j]%10);i++;
if(j==2)break;
show[i]=':';i++;
}
show[i]='E';
lcdshow((unsigned char *)show);//显示原设置的时间
LcdCtrl&=~(1<<LcdRS); //RS、R/W=00,写指令
LcdCtrl&=~(1<<LcdRW);
Lcd_Command(0b00001111); //开显示,开光标,闪烁
Lcd_Command(0b11000000); //后7位为DDRAM地址0x40
}
}
void ok(void){ //在设置模式下的确定,
unsigned char i;
if(showtime==0x00&&issettime==0x01){ //在时间设置模式下的确定,
T1SC|=(1<<TSTOPBit); //停止计数,进行时间修改
time[0]=0;time[1]=0;time[2]=0; //时间清零,键盘输入的临时时间写入时间
date[0]=0;date[1]=0;date[2]=0;
for(i=0;i<4;i++){
date[0]=(int)(date[0]*10+datetem[i]);
}
for(;i<6;i++){
date[1]=date[1]*10+datetem[i];
time[0]=time[0]*10+timetem[i-4];
}
for(;i<8;i++){
date[2]=date[2]*10+datetem[i];
time[1]=time[1]*10+timetem[i-4];
}
issettime=0x00;
T1SC&=~(1<<TSTOPBit); //开始计数
}
if(showtime==0x00&&issettime==0x00){ //在闹钟设置模式下的确定,
timer[0]=0;timer[1]=0;timer[2]=0; //时间清零,键盘输入的临时定时时间写入定时时间
for(i=0;i<2;i++){
timer[0]=timer[0]*10+timertem[i];
}
for(;i<4;i++){
timer[1]=timer[1]*10+timertem[i];
}
}
LcdCtrl&=~(1<<LcdRS); //RS、R/W=00,写指令
LcdCtrl&=~(1<<LcdRW);
Lcd_Command(0b00001100); //开显示,关光标显示,不闪烁
showtime=0x01; //开时间显示
}
void Delay_ms(unsigned char i)
{ unsigned char j;
unsigned char u;
for(j=0;j<i;j++)
for(u=0;u<=250;u++) ;
}
void beep(unsigned char p){ //锋鸣器启动,时间持续p秒
unsigned char j;
for(j=0;j<p;j++){//延时p秒
PTD=1;
Delay_ms(50);
PTD=0;
Delay_ms(200);
Delay_ms(200);
if(istimer==0)break; //如果关闹钟则退出延时
}
}
void input(KB_valve){ //数字输入
if(showtime==0x00){
unsigned char data;
if(issettime==0x01){ //若是时间设置
LcdCtrl&=~(1<<LcdRS); //RS、R/W=01,读指令
LcdCtrl|=(1<<LcdRW);
LcdCtrl|=(1<<LcdE); //E=1
data=LcdData; //获取AC的值
data&=0b01111111;
switch(data){ //按AC值不同分别赋给不同的时间临时单元
case 0x00:
datetem[0]=KB_valve-0x30;
lcdshow1(KB_valve,data);
break;
case 0x01:
datetem[1]=KB_valve-0x30;
lcdshow1(KB_valve,data);
break;
case 0x02:
datetem[2]=KB_valve-0x30;
lcdshow1(KB_valve,data);
break;
case 0x03:
datetem[3]=KB_valve-0x30;
lcdshow1(KB_valve,data);
break;
case 0x05:
if((KB_valve-0x30)<=1){
datetem[4]=KB_valve-0x30;
lcdshow1(KB_valve,data);}
break;
case 0x06:
if(datetem[4]==1&&(KB_valve-0x30)>2)break;
datetem[5]=KB_valve-0x30;
lcdshow1(KB_valve,data);
break;
case 0x08:
if(KB_valve-0x30<=3){
datetem[6]=KB_valve-0x30;
lcdshow1(KB_valve,data);}
break;
case 0x09:
if(datetem[6]==3&&(KB_valve-0x30)>1)break;
datetem[7]=KB_valve-0x30;
lcdshow1(KB_valve,data);
break;
case 0x40:
if((KB_valve-0x30)>2)break;
timetem[0]=KB_valve-0x30;
lcdshow1(KB_valve,data);
break;
case 0x41:
if(timetem[0]==2&&(KB_valve-0x30)>3)break;
timetem[1]=KB_valve-0x30;
lcdshow1(KB_valve,data);
break;
case 0x43:
if((KB_valve-0x30)>5)break;
timetem[2]=KB_valve-0x30;
lcdshow1(KB_valve,data);
break;
case 0x44:
timetem[3]=KB_valve-0x30;
lcdshow1(KB_valve,data);
default:break;
}
}
else { //不是时间设置则是闹钟设置
LcdCtrl&=~(1<<LcdRS); //RS、R/W=01,读指令
LcdCtrl|=(1<<LcdRW);
LcdCtrl|=(1<<LcdE); //E=1
data=LcdData; //获取AC的值
data&=0b01111111;//获取AC的值
switch(data){ //按AC值不同分别赋给不同的闹钟计时临时单元
case 0x40:
if((KB_valve-0x30)>2)break;
timertem[0]=KB_valve-0x30;
lcdshow1(KB_valve,data);
break;
case 0x41:
if(timertem[0]==2&&(KB_valve-0x30)>3)break;
timertem[1]=KB_valve-0x30;
lcdshow1(KB_valve,data);
break;
case 0x43:
if((KB_valve-0x30)>5)break;
timertem[2]=KB_valve-0x30;
lcdshow1(KB_valve,data);
break;
case 0x44:
timertem[3]=KB_valve-0x30;
lcdshow1(KB_valve,data);
default:break;
}
}
}
}
void cancel(void){ //取消设置
if(showtime==0){
showtime=1;issettime=0; //模式为显示时间,退出时间设置
LcdCtrl&=~(1<<LcdRS); //RS、R/W=00,写指令
LcdCtrl&=~(1<<LcdRW);
Lcd_Command(0b00001100); //开显示,关光标显示,不闪烁
}
}
void reset(void){ //时钟复位,全部从零开始
asm("SEI");
showtime=0x01;istimer=0x00;issettime=0;//模式初始化
DDRD=0x01;out=1; //闹钟接口初始化
timer[0]=0;timer[1]=0; //闹钟\时间初始化
time[0]=0;time[1]=0;time[2]=0;
date[0]=0;date[1]=0;date[2]=0;
LcdInit(); //LCD显示初始化
lcdshow((unsigned char *)ch);
KB_Init(); //键盘初始化
INTKBSCR&= ~(1<<IntBit); //开放键盘中断(IMASKk=1)
Timer1init(); //定时器初始化
asm("CLI"); //复位
}
void set(unsigned char KB_valve){ //按键功能选择
switch(KB_valve){
case 'A':shilfL(); //A:设置模式下的光标左移
break;
case 'B':shilfR();//B:设置模式下的光标右移
break;
case 'C':sastimer(); //C:闹钟开关
break;
case 'D':settimer();//D:进入闹钟设置
break;
case '#':ok(); //#:确定并退出设置
break;
case '*':cancel();//*:取消并退出设置
break;
case '0':if(showtime==1){settime();break;}//0:非设置模式下的进入时间设置
case '1':if(showtime==1){reset();break;}//1:非设置模式下的复位
default:input(KB_valve);//设置模式下的数字输入
break;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -