?? digitalclock.c
字號:
/*調整功能顯示時間*/
void asjust_time()
{
uchar save[2];
display_cnasc(0x8a,1,"時");
display_cnasc(0x8c,1,"分");
display_cnasc(0x8e,1,"秒");
save[0]=char_num[now.hour>>4];
save[1]=char_num[now.hour&0x0f];
display_cnasc(0x89,1,save);
save[0]=char_num[now.minute>>4];
save[1]=char_num[now.minute&0x0f];
display_cnasc(0x8b,1,save);
save[0]=char_num[now.second>>4];
save[1]=char_num[now.second&0x0f];
display_cnasc(0x8d,1,save);
}
/*調整功能月天數比較*/
uchar monthday(uchar year,uchar month)
{
if(month==2&&year%4==0)
return(29);
else
{ year=month&0x0f;
month>>=4;
month=month*10+year;
return(dayofmonth[month-1]);}
}
/*星期推算*/
void weeks_day()
{
uchar d,buffer,day=4;
if(today.month>1)
{
buffer=(today.month>>4); // 將BCD碼轉為十進制
buffer=buffer*10;
buffer+=(today.month&0x0f);
for(d=0;d<buffer-1;d++)
{
today.week=(dayofmonth[d]>>4);
today.week=today.week*10;
today.week+=(dayofmonth[d]&0x0f);
day+=(today.week%7);
}
}
buffer=(today.year>>4);
buffer*=10;
buffer+=(today.year&0x0f);
if(today.year!=0)
{
day+=((buffer-1)/4)+buffer+1;
}
if(buffer%4==0&&today.month>2) day++;
buffer=today.day>>4;
buffer*=10;
buffer+=(today.day&0x0f);
today.week=(day+buffer)%7;
}
/*調整功能*/
void adjust_func(void)
{
uchar d,save,b=0;
dis_title_e();
display_cnasc(0x82,3,menu_cn_2[0]);
rds1302_date();
rds1302_time();
dis_date_mode2(0x90);
display_cnasc(0x9a,1," ");
asjust_time();
display_cnasc(0x9f,1,"→");
display_cnasc(0x90,1,"『");
display_cnasc(0x8f,1,"』");
d=0;save=0;
adju_si=0;
do
{
con_disp(0x00,0x00,index_a[d].lnum,index_a[d].rnum,1,13);
con_disp(0xff,0xff,index_a[save].lnum,index_a[save].rnum,1,13);
d=save;
while(1)
{
save=gotkey();
if(save>=0&&save<10)
{
switch(d)
{
case 0: if(adju_si) // adju_si==1時兩次輸入連成一個數
{
today.year<<=4;
today.year+=save;adju_si=0;
}
else
{
today.year=save;adju_si=1;
}
break;
case 1: if(adju_si)
{
today.month<<=4;today.month+=save;
if(today.month>0x12) today.month=save;
else adju_si=0;
}
else
{
today.month=save;adju_si=1;
}
break;
case 2: if(adju_si)
{
today.day<<=4;today.day+=save; // 月天數比較
if(today.year%4==0&&today.month==2&&today.day==29) ;
else if(today.day>monthday(today.year,today.month))
today.day=save;
else adju_si=0;
}
else {today.day=save;adju_si=1;}
break;
case 3: if(adju_si)
{
now.hour<<=4;now.hour+=save;
if(now.hour>0x23) now.hour=save;
else adju_si=0;
}
else {now.hour=save;adju_si=1;}
break;
case 4: if(adju_si)
{
now.minute<<=4;now.minute+=save;
if(now.minute>0x59) now.minute=save;
else adju_si=0;
}
else {now.minute=save;adju_si=1;}
break;
case 5: if(adju_si)
{
now.second<<=4;now.second+=save;
if(now.second>0x59) now.second=save;
else adju_si=0;
}
else {now.second=save;adju_si=1;}
break;
}
if(today.day>monthday(today.year,today.month)) today.day=1; // 更改月份時判斷天數
if(today.month==0) today.month=1;
if(today.day==0) today.day=1;
if(d<3) dis_date_mode2(0x90); // 更新顯示
else asjust_time();
display_cnasc(0x9a,1," "); // 消去星期顯示
}
if(save==11){save=d+1;adju_si=0;break;}
if(save==10&&d!=0){save=d-1;adju_si=0;break;}
}
if(save==7&d==6) break;
}while(1);
weeks_day(); // 計算星期
save_y_or_n(); // 需要保存時oth_run設為1
if(oth_run) wds1302_time_date();
}
/*=====================================================================================
函數名稱:計算器功能
功能描述:10位帶符號數的加減乘除運算
全局變量:opera resu i j
參數說明:見函數
返回說明:無
設 計 人:LIJH
版 本:1.0
說 明:
======================================================================================*/
/*清寄存器 參數格式:m=2時結果寄存器,當m=1時操作數1,當m=0時操作數0(1),
n=1時,只清寄存器不清顯示, 0兩清*/
void removal_data(uchar m,uchar n)
{
uchar l; // 當n=1時,只清寄存器不清顯示, 0兩清
if(m==2) // 當m=2時結果寄存器
{ // 當m=1時操作數1
if(n==0) // 當m=0時操作數0 ,1
for(l=0;l<6;l++)
display_cnasc(0x98+l,1," ");
for(l=0;l<12;l++)
resu[l]=0;
}
while(m<2)
{
if(n==0)
{
if(m==0)
{
for(l=0;l<6;l++)
display_cnasc(0x90+l,1," ");
display_cnasc(0x95,1," 0");
}
else
for(l=0;l<6;l++)
display_cnasc(0x88+l,1," ");
}
for(l=0;l<12;l++)
opera[m][l]=0;
m++;
}
}
/*顯示數值 參數格式:顯示首地址*/
void dis_cdata(uchar ass)
{
uchar p,d,save[2];
if(i==0&&opera[0][0]==1) // 顯示符號
{
if(cal_run) display_cnasc(0x98,1,"=-");
else display_cnasc(0x90,1," -");
}
d=opera[i][11]; // 計算位數
if(opera[i][10]!=0&&opera[i][10]!=opera[i][11]+1) d++;
save[0]=d/2;ass=ass-save[0]+5; // 計算顯示的開始位置
p=1;
cal_del=0; // 顯示點標記 (0為沒有顯示)
if(d%2==1) // 對位數位奇數先處理首位
{
save[0]=' ';
save[1]=char_num[opera[i][1]];
display_cnasc(ass,1,save);
p++;
}
ass++; // 顯示地址加一
while(p<=opera[i][11])
{
if(opera[i][10]==p&&(!cal_del)) { // 顯示點且作標記
save[0]='.';cal_del=1;}
else {
save[0]=char_num[opera[i][p]]; p++;}
if(opera[i][10]==p&&(!cal_del)) {
save[1]='.';cal_del=1;}
else{
save[1]=char_num[opera[i][p]];p++;}
display_cnasc(ass,1,save);
ass++;
}
}
/*從鍵盤中寫入數據*/
char input_data()
{
uchar save=20,c;
for(;i<2;i++)
{
while(1)
{
pp: save=gotkey(); // 讀鍵盤
if(save==20) continue;
if(save==11) // 按鍵為確定時,選擇計算或刪除
{
c=save=0;
while(1) // 反色選擇
{
con_disp (0x00,0x00,index_cal[save].lnum,index_cal[save].rnum,2,16);
con_disp (0xff,0xff,index_cal[c].lnum,index_cal[c].rnum,2,16);
save=gotkey();
if(save==10)
{
save=c;
if(++c==3) c=0;
}
else if(save==11)
{
if(c==0) save=11;
else if(c==1) save=16;
else return 0;
break;
}
else break;
}
con_disp (0x00,0x00,index_cal[c].lnum,index_cal[c].rnum,2,16);
}
if(save>=0&&save<=9&&j<10)
{
if(i==1&&opera[1][0]==15&&j>8) goto pp;
if(j==2&&opera[i][1]==0&&opera[i][10]==0)
opera[i][1]=save; // 防止小數位不在時首位為零
else{
opera[i][j]=save;opera[i][11]=j;j++;}
if(i==0) // 顯示
dis_cdata(0x90);
else
dis_cdata(0x88);
}
else if(save==10&&j<10)
{
if(opera[i][10]==0) // 小數點空時保存
{
if(opera[i][11]==0) {opera[i][10]=2;j++;}
else opera[i][10]=j;
}
}
else if(save==16)
{ // 刪除數據
removal_data(i,0);j=1;
if(i!=0){i--;j=10;}
}
else if(i==1&&opera[1][11]!=0&&save>11&&save<16)
{ save1=save;break; } // 連續計算時保存運算符
else if(save==11&&opera[1][11]==0) continue;// 操作數1為0時不理會
else if(save==11&&opera[1][11]!=0) break;
else if((i==0||i==1&&j==1)&&save>11&&save<16){i=0; break;}
// 當操作數0由運算符結束輸入,再按符號鍵更改
else continue;
}
if(opera[i][10]>opera[i][11]||opera[i][10]==0)
opera[i][10]=opera[i][11]+1; // 整數時小數位保存到最后
while(opera[i][11]>=opera[i][10]&&opera[i][opera[i][11]]==0)
opera[i][11]--; // 去除小數點后多余的0
if(i==0)
{
opera[1][0]=save; // 保存運算符并顯示
display_cnasc(0x88,1,tool_cal[save-12]);
}
if(opera[0][11]==0) display_cnasc(0x95,1," 0");
j=1;
while(j<=opera[i][11]&&opera[i][j]==0) j++;//判斷是否操作數是否全為0
j--;
if(j==opera[i][11]) opera[i][11]=0;
j=1;
}
return 1;
}
/****************************************************************************************
功能: 乘法運算
描述: 結果由右到左保存
參數: i , j , opera[i][j],p,q,r,k,save1
返回值:1(成功),0(結果位0),-1(溢出)
/****************************************************************************************/
char multiplication()
{
uchar p,q,r,k,save1=0; // p指向操作數0 ,q指向操作數1,r指向結果
if(opera[0][11]==0||opera[1][11]==0) return 0;
resu[10]=opera[0][11]+opera[1][11]-opera[0][10]-opera[1][10]+2; // RESU記錄小數點后的位數
q=opera[1][11]; // 記錄操1的位數
r=9;
opera[1][11]=1;
k=1;
while(opera[1][k]==0) {opera[1][11]=opera[1][11]+1;k++;} // 去除前端的0
k=1;
while(opera[0][k]==0) k++; // 去除前端的0
resu[11]=9;
for(resu[0]=9;q>=opera[1][11];q--,resu[0]--)
{
if(opera[1][q]==0) continue; // 操1此位數為0時直接比較
for(p=opera[0][11],r=resu[0];p>=k;p--)
{
save1=opera[0][p]*opera[1][q]; // 將相乘后的數保存
resu[r]+=(save1%10);//將緩存中的數取余后加到結果中R指向的位
save1/=10;
save1=save1+(resu[r]/10); // 保存進位的數
resu[r]%=10; // 重新寫入
if(r==1) //結果有溢出時移位
{
if(save1==0&&p==k) break; // 計算到最后位且沒進位跳出
else if(resu[10]>0) // 要求有小數存在
{
for(r=9;r>1;r--) resu[r]=resu[r-1];
r=1;
resu[r]=save1;
resu[11]=1;
resu[10]--;
resu[0]++;
}
else return -1; // 否則溢出
}
if(r>1&&(r-1)<resu[11]) // 保存結果位的最高位
{
if(save1!=0) resu[11]=r-1;
else resu[11]=r;
}
if(r>1){ r--;resu[r]+=save1;}// 當R為1時只需要移位記錄結果
}
}
while(resu[resu[11]]==0) resu[11]++; // 去除前端的0
resu[0]=opera[0][0]; // 保存符號位
removal_data(0,1); // 清數據不清顯示
if(resu[10]>8) //如果小數點后的數有9 位或以上時,需后移到使小數點放到2的位置
{
save1=resu[10]-10+resu[11]; // 記錄后移位數
if(save1>7) return 0; //當后移的數大于有效數字的位數時結果為0
else // 否則按需移位
{
for(p=save1+2,r=resu[11];p<10;p++,r++) opera[0][p]=resu[r];
opera[0][10]=2;opera[0][11]=9;opera[0][0]=resu[0];
} // 因有效數小于小數點后的數,所以首位為0
}
else //如果小數點后的數在8位以內時分兩種情況
{
opera[0][0]=resu[0];
save1=10-resu[11]; // 記錄有效位數
if(resu[10]>=save1) // 小數的在有效數字的左邊
{
for(p=resu[10]+1,r=9;r>=resu[11];p--,r--)
opera[0][p]=resu[r]; // 從小數點的最后一位開始
opera[0][10]=2;opera[0][11]=resu[10]+1;
}
else // 小數點在有效數字內
{
for(p=1,r=resu[11];r<10;p++,r++) opera[0][p]=resu[r];
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -