?? wannianli.c
字號:
}
/**********************************************************************************************/
void Beep_key(void){//-揚聲器--按鍵音
uchar a;//定義變量用于發聲的長度設置
Led_EA = 1;//關列顯示驅動,防止屏幕出現亂碼
for(a=100;a>0;a--){//聲音的長度
Bell_Out = ~Bell_Out;
Delay(50);//音調設置延時
}
}
/**********************************************************************************************/
void clock_out(unsigned char dd){ //-1302驅動程序(底層協議)
ACC=dd;
clock_dat=a0; clock_clk=1; clock_clk=0;
clock_dat=a1; clock_clk=1; clock_clk=0;
clock_dat=a2; clock_clk=1; clock_clk=0;
clock_dat=a3; clock_clk=1; clock_clk=0;
clock_dat=a4; clock_clk=1; clock_clk=0;
clock_dat=a5; clock_clk=1; clock_clk=0;
clock_dat=a6; clock_clk=1; clock_clk=0;
clock_dat=a7; clock_clk=1; clock_clk=0;
}
/**********************************************************************************************/
unsigned char clock_in(void){ //-DS1302寫入字節(底層協議)
clock_dat=1;
a0=clock_dat;
clock_clk=1; clock_clk=0; a1=clock_dat;
clock_clk=1; clock_clk=0; a2=clock_dat;
clock_clk=1; clock_clk=0; a3=clock_dat;
clock_clk=1; clock_clk=0; a4=clock_dat;
clock_clk=1; clock_clk=0; a5=clock_dat;
clock_clk=1; clock_clk=0; a6=clock_dat;
clock_clk=1; clock_clk=0; a7=clock_dat;
return(ACC);
}
/**********************************************************************************************/
uchar read_clock(uchar ord){ //-DS1302讀數據(底層協議)
uchar dd=0;
clock_clk=0;
clock_Rst=0;
clock_Rst=1;
clock_out(ord);
dd=clock_in();
clock_Rst=0;
clock_clk=1;
return(dd);
}
/**********************************************************************************************/
void write_clock(uchar ord, uchar dd){ //-DS1302寫數據(底層協議)
clock_clk=0;
clock_Rst=0;
clock_Rst=1;
clock_out(ord);
clock_out(dd);
clock_Rst=0;
clock_clk=1;
}
/**********************************************************************************************/
void Set_time(unsigned char sel,unsigned char a){ //根據選擇調整的相應項目加1并寫入DS1302-調時用加1程序
signed char address,item;
signed char max,mini;
//if(sel==7) {address=0x80; max=0;mini=0;} //秒7
if(sel==6) {address=0x82; max=59;mini=0;} //分鐘6
if(sel==5) {address=0x84; max=23;mini=0;} //小時5
if(sel==3) {address=0x86; max=31;mini=1;} //日3
if(sel==2) {address=0x88; max=12;mini=1;} //月2
if(sel==1) {address=0x8c; max=99; mini=0;} //年1
if(sel==4) {address=0x8a; max=7;mini=1;} //星期4
if(sel==200) {address=0xc2+a*6; max=6;mini=0;} //MODE
if(sel==201) {address=0xc2+a*6+2; max=23;mini=0;} //星期4
if(sel==202) {address=0xc2+a*6+4; max=59;mini=0;} //星期4
//讀取1302某地址上的數值轉換成10進制賦給item
item=((read_clock(address+1))/16)*10 + (read_clock(address+1))%16;
if(Add_Key == 0){ key_off ();//等待鍵放開
item++;//數值加1
Beep_key();//調時提示音
}
if(Add2_Key == 0){ key_off ();//等待鍵放開
item--;//數值減1
Beep_key();//調時提示音
}
if(item>max) item=mini;//查看數值有效范圍
if(item<mini) item=max;
write_clock(0x8e,0x00);//允許寫操作
write_clock(address,(item/10)*16+item%10);//轉換成16進制寫入1302
if(sel == 6 && (Add_Key == 0 || Add2_Key == 0)){
write_clock(0x80,0x00);//秒值=0
}
write_clock(0x8e,0x80);//寫保護,禁止寫操作
}
/**********************************************************************************************/
void Init_1302(void){//-設置1302的初始時間(2007年1月1日00時00分00秒星期一)
uchar f;
if(read_clock(0xc1) != 0xaa){
write_clock(0x8e,0x00);//允許寫操作
write_clock(0x8c,0x07);//年
write_clock(0x8a,0x01);//星期
write_clock(0x88,0x01);//月
write_clock(0x86,0x01);//日
write_clock(0x84,0x00);//小時
write_clock(0x82,0x00);//分鐘
write_clock(0x80,0x00);//秒
write_clock(0x90,0xa5);//充電
write_clock(0xc0,0xaa);//寫入初始化標志RAM(第00個RAM位置)
for(f=0;f<60;f=f+2){//清除鬧鐘RAM位為0
write_clock(0xc2+f,0x00);
}
write_clock(0x8e,0x80);//禁止寫操作
}
}
/**********************************************************************************************/
void clearRAM (void){//寄存器清空函數-32個寄存器清空(0x00)
uchar a;//定義變量用于清空數據指針
for(a=0;a<32;a++){//指向32個寄存器
Ledplay[a] = 0;//將指向的寄存器清空
}
}
/**********************************************************************************************/
void putin (uchar u){//字符載入函數-將字符裝入顯示寄存器
uchar a = 0;//定義變量用于數據提取指針
do{
Ledplay[bn] = no[u][a];//將二維數組中的一組數據放入顯示緩沖區
a++;//換下一個提取字節
bn++;//換下一個顯示緩沖字節
}
while(no[u][a] != 0);//當顯示數據為0時結束循環
bn++;//換下一個顯示緩沖字節
Ledplay[bn] = 0;//顯示一列的空位,便于字符區分
}
/**********************************************************************************************/
void display (void){//點陣屏驅動函數-32*8點陣顯示驅動
uchar ac,aa=7;//定義兩個數據變量
for(ac=0x28;ac<0x30;ac++){//掃描后兩塊LED屏(由于P1.5接揚聲器所以高4位為2,旨在關聲音)
Led_E = ac;//用ac值驅動使能列信號
Led_24 = DL(Ledplay[aa+8]);//將顯示寄存器數據寫入2、4屏(嵌入DL匯編是為了翻轉字節數據,如果接線正確可省去)
Led_13 = Ledplay[aa];//將顯示寄存器數據寫入1、3屏
Delay(60);//延時1.2微秒
Led_13 = 0;//數據總線清空
Led_24 = 0;
aa--;//aa減1,換下一列顯示
}
aa = 23;//指定后16個數據的提取
for(ac=0x20;ac<0x28;ac++){//掃描前兩塊LED屏
Led_E = ac;//用ac值驅動使能列信號
Led_24 = DL(Ledplay[aa+8]);//將顯示寄存器數據寫入2、4屏
Led_13 = Ledplay[aa];//將顯示寄存器數據寫入1、3屏
Delay(60);//延時1.2微秒
Led_13 = 0;//數據總線清空
Led_24 = 0;
aa--;//aa減1,換下一列顯示
}
}
/**********************************************************************************************/
void search_time(void){//驗證鬧鐘時間到
uchar i;
write_clock(0x8e,0x00);//允許寫操作
for(i=1;i<9;i++){
if( read_clock(0xc3+i*6) != 0 && //不為0則表示這項已經設置
read_clock(0xc3+i*6+2) == read_clock(0x85) && //小時對比
read_clock(0xc3+i*6+4) == read_clock(0x83)&& //分值對比
read_clock(0x81) < 0x09 && //這里保證秒值小于8秒動作,防止再操作
v != read_clock(0x83))//按鍵停止防再響
{
switch (read_clock(0xc3+i*6)){//顯示設置項的說明
case 1://只響一次,之后自動關閉
BEEP_bit = 1;
write_clock(0xc2+i*6,0);
break;//
case 2://常開
BEEP_bit = 1;
break;//
case 3://周六、日除外
if(read_clock(0x8b) < 6){
BEEP_bit = 1;
}
break;//
case 4://周日除外
if(read_clock(0x8b) < 7){
BEEP_bit = 1;
}
break;//
case 5://周六、日響
if(read_clock(0x8b) > 5){
BEEP_bit = 1;
}
break;//
case 6://周日響
if(read_clock(0x8b) == 7){
BEEP_bit = 1;
}
break;//
}
v = read_clock(0x83);
}
}
write_clock(0x8e,0x80);//禁止寫操作
}
/**********************************************************************************************/
void Timer0_Init(void){//定時器0初始(主函數中被調用一次)
TMOD=0x01;//定時器方式設置(定時器工作方式1-16位定時)
TH0=(65535-50000)/256;//50MS
TL0=(65535-50000)%256;
EA=1;//開總中斷
ET0=1;//開定時器0中斷允許
TR0=1;//啟動定時器0
}
/**********************************************************************************************/
void Timer0(void) interrupt 1 using 0{//定時器中斷入口,使用第1工作組寄存器=定時器中斷函數(產生顯示切換)
uchar pp;//定義靜態小時更新用數據變量
TH0=(65535-50000)/256; //50ms定時(定時器工作方式1)
TL0=(65535-50000)%256;
timecount++;//軟件計數加1
if(timecount == 20){//軟件計數加到20時顯示日期(1S)
Led_EA = 1;//關列顯示驅動,防止屏幕出現亂碼
clearRAM();//清空顯示緩沖區數據
bn = 0;//顯示位累加寄存器清零(從頭開始寫入顯示緩沖區)
if(read_clock(0x89)/16 != 0){//為0時消隱
putin(read_clock(0x89)/16);//顯示月值(十位,為0時消隱)
}
putin(read_clock(0x89)%16);//顯示月值(個位)
putin(21);//顯示“月”
if(read_clock(0x87)/16 != 0){//為0時消隱
putin(read_clock(0x87)/16);//顯示日值(十位,為0時消隱)
}
putin(read_clock(0x87)%16);//顯示日值(個位)
putin(22);//顯示“日”
}
if(timecount == 40){//軟件計數加到40時顯示時間(2S)
Led_EA = 1;//關列顯示驅動,防止屏幕出現亂碼
clearRAM();//清空顯示緩沖區數據
bn = 0;//顯示位累加寄存器清零(從頭開始寫入顯示緩沖區)
if(read_clock(0x85) > read_clock(0xc3) && read_clock(0x85) < read_clock(0xc5)){//整點報時
if(pp != read_clock(0x85)){//當小時值更新時則啟動報時
pp = read_clock(0x85);//將新的小時值放入更新寄存器
Beep();//啟動正點報時
}
}
putin(read_clock(0x85)/16);//顯示小時值(十位,為0時消隱)
putin(read_clock(0x85)%16);//顯示小時值(個位)
putin(17);//顯示冒號“:”
putin(read_clock(0x83)/16);//顯示分鐘值(十位)
putin(read_clock(0x83)%16);//顯示分鐘值(個位)
search_time();//----------------------------------------------------檢測鬧鐘
}
if(timecount > 80){////軟件計數加到80時顯示時間(1S)
uchar ty = 0;//定義溫度寄存器變量
timecount = 0;//軟件計數清零
Led_EA = 1;//關列顯示驅動,防止屏幕出現亂碼
ty = printTemperature();//將DSS匯編程序取得的溫度值放入溫度寄存器變量
clearRAM();//清空顯示緩沖區數據
bn = 0;//顯示位累加寄存器清零(從頭開始寫入顯示緩沖區)
if(ty >60){//當溫度高于99度或未發現溫度傳感器(DS18B20)時顯示“--”
putin(18);//顯示“--”
putin(18);
}
else{//溫度小于99度并發現溫度傳感器(DS18B20)時,顯示溫度值
if(ty/10 != 0){//為0時消隱
putin(ty/10);//溫度值的十位
}
putin(ty%10);//溫度值的個位
}
putin(19);//顯示攝氏度符號“oC”
putin(read_clock(0x8b)+9);//顯示星期數據
}
}
/**********************************************************************************************/
void MENUadd1 (void){//主菜單加1或減1
if(Add_Key == 0 || Add2_Key == 0){
DelayM(20);//去抖
if(Add_Key == 0){
MENU++;
Beep_key();//調時提示音
if(MENU >11){
MENU = 1;
}
}
if(Add2_Key == 0){
MENU--;
Beep_key();//調時提示音
if(MENU <1){
MENU = 11;
}
}
key_off ();//等待鍵放開
}
}
/**********************************************************************************************/
void MENUexit (void){//退出菜單項 回到時鐘顯示
if(int_Key == 0){
DelayM(20);//去抖
if(int_Key == 0){
key_off ();//等待鍵放開
Beep_set();//調時提示音
clearRAM();//清空顯示緩沖區數據
timecount = 19;//將顯示切換值調到41,使開機畫面停留2秒
MENU = 0;
Timer0_Init();//定時器初始化
}
}
}
/**********************************************************************************************/
void main(void){ //主函數
uchar b,a = 0;//定義變量用于數據提取指針
Init_1302();//調用時間初始化函數
Beep();//啟動發出報時音(測試揚聲器)
do{//顯示開機畫面“DoYoung”
Ledplay[bn] = DoYoung[a];//將二維數組中的一組數據放入顯示緩沖區
a++;//換下一個提取字節
bn++;//換下一個顯示緩沖字節
}
while(DoYoung[a] != 0x99);//當顯示數據為0時結束循環
timecount = 41;//將顯示切換值調到41,使開機畫面停留2秒
Timer0_Init();//定時器初始化
MENU = 0;//顯示標志為0表示正常顯示
BEEP_bit = 0;
/**********************************************************************************************/
while(1){//主線程
/**********************************************************************************************/
if(BEEP_bit == 1 && read_clock(0xc7) == 1){
for(b=0;b<140;b++){//
ET0 = 0;//關定時器中斷(停止顯示切換)
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -