|
各位大神朋友給的一萬年歷代碼,我用keill 與porteus編譯都報錯。哪位大神指點一下?代碼如下:
- //DS1302寫8位地址和數(shù)據(jù)
- void RTC_wcom(char addr,char wdata)
- {
- char i,j;
- RTC_RST=0;
- RTC_CLK=1;
- RTC_RST=1;
- for(i=0;i<8;i++);
- {
- RTC_DAT=addr >> i & 0x01;
- RTC_CLK=0;
- RTC_CLK=1;
- }
- for(j=0;j<8;j++)
- {
- RTC_DAT=wdata >> j & 0x01;
- RTC_CLK=0;
- RTC_CLK=1
- }
- RTC_CLK=1;
- RTC_RST=0;
- }
- //DS1302讀數(shù)據(jù)
- uchar RTC_rcom(uchar addr)
- {
- uchar i,rdata=0;
- RTC_RST=1;
- for(i=0;i<8;i++)
- {
- RTC_CLK=0;
- RTC_DAT=addr>>i & 0x01;
- RTC_CLK=1;
- }
- for(i=0;i<8;i++)
- {
- RTC_CLK=1;
- RTC_CLK=0;
- if(RTC_DAT)
- rdata |= (0x01<<i);
- }
- RTC_DAT=0;
- RTC_CLK=1;
- RTC_RST=0;
- return rdata;
- }
- //DS1302初始化
- void RTC_init(void)
- {
- RTC_wcom(0x8e,0x00); //00允許寫,80寫保護(hù)
- RTC_wcom(0x8c,0x00); //年,00~99,初始00
- RTC_wcom(0x88,0x01); //月,01~12,初始01
- RTC_wcom(0x86,0x01); //日,01~31,初始01
- RTC_wcom(0x8a,0x06); //星期,1~7,初始6
- RTC_wcom(0x84,0x12); //時,00~23,初始12
- RTC_wcom(0x82,0x00); //分,00~59,初始00
- RTC_wcom(0x80,0x00); //秒,00~59,初始00
- }
復(fù)制代碼
DS18B20驅(qū)動代碼
- uint tmp;
- uchar tmp_sign;
- //DS18B20對時序有一定要求,有問題的話查一下延遲時序是否符合規(guī)格書要求
- //DS18B20初始化
- void tmp_init(void)
- {
- TMP_DQ=0;
- delay(80); //拉低480~960us
- TMP_DQ=1;
- delay(1);
- while(TMP_DQ); //等待應(yīng)答
- while(!TMP_DQ); //應(yīng)答結(jié)束后等待DS18B20釋放總線
- }
- //DS18B20寫命令
- void tmp_write(uchar cmd)
- {
- uchar i;
- for(i=0;i<8;i++)
- {
- TMP_DQ=0;
- _nop_();
- TMP_DQ=cmd & 0x01;
- cmd >>= 1;
- delay(5);
- TMP_DQ=1;
- _nop_();
- }
- }
- //讀取數(shù)據(jù),先低后高
- uchar tmp_read(void)
- {
- uchar i;
- uchar dat=0;
- for(i=0;i<8;i++)
- {
- TMP_DQ=0;
- _nop_();
- TMP_DQ=1;
- _nop_();
- dat >>= 1;
- if(TMP_DQ==1)
- dat |= 0x80;
- delay(5);
- TMP_DQ=1;
- _nop_();
- }
- return dat;
- }
- void get_tmp(void)
- {
- uchar tmpL,tmpH;
- tmp_init(); //初始化
- tmp_write(0xcc); //跳過ROM
- tmp_write(0x44); //溫度轉(zhuǎn)換
- tmp_init(); //再初始化
- tmp_write(0xcc); //跳過ROM
- tmp_write(0xbe); //請求數(shù)據(jù)讀取
- tmpL=tmp_read(); //接收溫度低位
- tmpH=tmp_read(); //接收溫度低位
- tmp=tmpH; //高位和低位合并
- tmp=(tmp<<8)|tmpL;
- if(tmp<0x0fff) //判斷是正溫度
- {
- tmp_sign=10; //符號為空
- tmp=tmp*5/8; //數(shù)值*0.0625為溫度值,留一位小數(shù),為了方便數(shù)據(jù)處理,乘以10倍,轉(zhuǎn)為整型
- } //這里用小數(shù)的話,代碼長度剛好超2k了,一個方法是直接改成(*5/8),節(jié)省空間
- else //另一個方法是設(shè)置里,把ROM由small改為large
- {
- tmp_sign=11; //負(fù)溫度顯示負(fù)號“-”
- tmp=(~tmp+1)*5/8;
- }
- }
復(fù)制代碼
LCD1602驅(qū)動代碼
- uchar code num[] = "0123456789 -";
- uchar code week[][3] = {"MON","TUE","WED","THU","FRI","SAT","SUN"};
- uchar yyH,yyL,moH,moL,ddH,ddL,hhH,hhL,miH,miL,ssH,ssL;
- uint wk;
- //LCD1602寫命令
- void LCD_wr_cmd(uchar cmd)
- {
- busy_check();
- LCD_RS=0;
- LCD_RW=0;
- LCD_CE=1;
- LCD_DA=cmd;
- delay(100);
- LCD_CE=0;
- }
- //LCD1602寫數(shù)據(jù)
- void LCD_wr_dat(uchar dat)
- {
- busy_check();
- LCD_RS=1;
- LCD_RW=0;
- LCD_CE=1;
- LCD_DA=dat;
- delay(100);
- LCD_CE=0;
- }
- //LCD1602查忙,檢查前面數(shù)據(jù)是否已處理完
- void busy_check(void)
- {
- uchar busy_flag;
- busy_flag = 0xff;
- LCD_RS=0;
- LCD_RW=1;
- do
- {
- LCD_CE=1;
- busy_flag=LCD_DA;
- delay(100);
- LCD_CE=0;
- }while(busy_flag & 0x80);
- }
- //LCD初始化
- void LCD_init(void)
- {
- LCD_wr_cmd(0x01); //清顯示
- LCD_wr_cmd(0x06); //光標(biāo)右移,文字不動
- LCD_wr_cmd(0x0c); //開顯示,無光標(biāo),不閃爍
- LCD_wr_cmd(0x38); //8位總線,雙行顯示,5X7的點陣字符
- }
- //獲取年月日,星期,時間數(shù)據(jù)
- void get_dat(void)
- {
- yyH=RTC_rcom(0x8d)/16;
- yyL=RTC_rcom(0x8d)%16;
- moH=RTC_rcom(0x89)/16;
- moL=RTC_rcom(0x89)%16;
- ddH=RTC_rcom(0x87)/16;
- ddL=RTC_rcom(0x87)%16;
- wk =RTC_rcom(0x8b);
- hhH=RTC_rcom(0x85)/16;
- hhL=RTC_rcom(0x85)%16;
- miH=RTC_rcom(0x83)/16;
- miL=RTC_rcom(0x83)%16;
- ssH=RTC_rcom(0x81)/16;
- ssL=RTC_rcom(0x81)%16;
- }
復(fù)制代碼
按鍵設(shè)置
- uchar key=0;
- uchar code month_day[]={31,28,31,30,31,30,31,31,30,31,30,31};
- //按鍵掃描
- void key_scan(void)
- {
- if(!t_set)
- {
- delay10ms(1);
- if(!t_set)
- while(!t_set);
- key=1;
- }
- if(!t_rst)
- {
- delay10ms(1);
- if(!t_rst)
- while(!t_rst);
- key=2;
- }
- }
- //按加減鍵設(shè)置時間
- void manual_set(uchar min,uchar max,uchar LCD_cmd,uchar RTC_cmd)
- {
- uchar temp=min;
- do
- {
- key_scan(); //按鍵掃描
- if(!t_add) //加按鍵按下,按住就一直增加
- {
- delay10ms(10);
- if(!t_add)
- {
- ++temp;
- if(temp==max+1)temp=min;
- LCD_wr_cmd(LCD_cmd|0x80); //顯示調(diào)整的值
- LCD_wr_dat(num[temp/10]);
- LCD_wr_dat(num[temp%10]);
- delay10ms(20); //增加延時,調(diào)節(jié)增加的速度
- }
- }
- if(!t_dec) //減按鍵按下,功能同上
- {
- delay10ms(10);
- if(!t_dec)
- {
- if(temp==min)temp=max+1;
- --temp;
- LCD_wr_cmd(LCD_cmd|0x80);
- LCD_wr_dat(num[temp/10]);
- LCD_wr_dat(num[temp%10]);
- delay10ms(20);
- }
- }
- }while(key!=1); //確定設(shè)置鍵是否按下,按下就跳出循環(huán)
- key=0; //按鍵值清零
- RTC_wcom(RTC_cmd,temp/10*16+temp%10); //最終值寫入DS1302
- }
- //星期的計算
- void week_set(void)
- {
- uchar i;
- yyH=RTC_rcom(0x8d)/16; //獲取年月日數(shù)據(jù)
- yyL=RTC_rcom(0x8d)%16;
- moH=RTC_rcom(0x89)/16;
- moL=RTC_rcom(0x89)%16;
- ddH=RTC_rcom(0x87)/16;
- ddL=RTC_rcom(0x87)%16;
- wk=(yyH*10+yyL)*365+(yyH*10+yyL)/4; //先按年的天數(shù)計算,加上閏年天數(shù)
- for(i=0;i<moH*10+moL-1;i++) //再加上月的天數(shù)
- {
- wk=wk+month_day[i];
- }
- wk=wk+ddH*10+ddL; //再加上天數(shù)
- if((yyH*10+yyL)/4==0) //如果當(dāng)年是閏年
- {
- if(moH*10+moL<3) //且當(dāng)月不到3月份
- wk=wk-1; //需減去1天
- }
- wk=(wk%7+5)%7+1; //總天數(shù)除以7取余,加上2000年1月1日補(bǔ)償數(shù)5,可能超過7,再取余,避免出現(xiàn)0,再加1
- RTC_wcom(0x8a,wk); //寫入寄存器
- }
- //時間設(shè)置
- void time_set(void)
- {
- key_scan();
- if(key==1) //設(shè)置鍵按下
- {
- key=0;
- LCD_wr_cmd(0x01); //清顯示
- LCD_wr_cmd(0x0f); //開顯示,有光標(biāo),閃爍
- LCD_wr_cmd(0x00|0x80);
- LCD_wr_dat('2');
- LCD_wr_dat('0');
- LCD_wr_dat('0');
- LCD_wr_dat('0');
- RTC_wcom(0x8e,0x00); //00允許寫
- RTC_wcom(0x80,0x80); //停止計時
- manual_set(0,99,0x02,0x8c); //設(shè)置年
- LCD_wr_dat('-');
- LCD_wr_dat('0');
- LCD_wr_dat('1');
- manual_set(1,12,0x05,0x88); //設(shè)置月
- LCD_wr_dat('-');
- LCD_wr_dat('0');
- LCD_wr_dat('1');
- manual_set(1,31,0x08,0x86); //設(shè)置日
- LCD_wr_cmd(0x40|0x80);
- LCD_wr_dat('0');
- LCD_wr_dat('0');
- manual_set(0,23,0x40,0x84); //設(shè)置小時
- LCD_wr_dat(':');
- LCD_wr_dat('0');
- LCD_wr_dat('0');
- manual_set(0,59,0x43,0x82); //設(shè)置分鐘
- week_set();
- RTC_wcom(0x80,0x00); //開始計時
- LCD_wr_cmd(0x0c); //開顯示,無光標(biāo),不閃爍
- }
- if(key==2) //復(fù)位鍵按下
- {
- key=0;
- RTC_init(); //DS1302恢復(fù)初始值
- }
- }
復(fù)制代碼
主函數(shù)及顯示部分:
- #include <reg51.h>
- sbit LCD_RS=P2^0; //LCD相關(guān)端口
- sbit LCD_RW=P2^1;
- sbit LCD_CE=P2^2;
- sbit t_set=P2^4; //按鍵
- sbit t_add=P2^5;
- sbit t_dec=P2^6;
- sbit t_rst=P2^7;
- sbit RTC_DAT=P1^0; //DS1302相關(guān)端口
- sbit RTC_CLK=P1^1;
- sbit RTC_RST=P1^2;
- sbit TMP_DQ=P3^7;
- #define LCD_DA P0 //LCD數(shù)據(jù)口
- typedef unsigned char uchar;
- typedef unsigned int uint;
- void display(void)
- {
- uchar i;
- uchar a,b,c;
- get_dat();
- //顯示日期
- LCD_wr_cmd(0x00|0x80); //從1行0列開始顯示
- LCD_wr_dat('2');
- LCD_wr_dat('0');
- LCD_wr_dat(num[yyH]);
- LCD_wr_dat(num[yyL]);
- LCD_wr_dat('-');
- LCD_wr_dat(num[moH]);
- LCD_wr_dat(num[moL]);
- LCD_wr_dat('-');
- LCD_wr_dat(num[ddH]);
- LCD_wr_dat(num[ddL]);
- //顯示星期
- LCD_wr_cmd(0x0c|0x80);
- for(i=0;i<3;i++)
- {
- LCD_wr_dat(week[wk-1][i]);
- }
- //顯示時間
- LCD_wr_cmd(0x40|0x80); //從2行0列開始顯示
- LCD_wr_dat(num[hhH]);
- LCD_wr_dat(num[hhL]);
- LCD_wr_dat(':');
- LCD_wr_dat(num[miH]);
- LCD_wr_dat(num[miL]);
- LCD_wr_dat(':');
- LCD_wr_dat(num[ssH]);
- LCD_wr_dat(num[ssL]);
- //顯示溫度
- get_tmp(); //獲取已乘10倍的溫度值
- a=tmp/100; //取百位數(shù)作為十位數(shù)
- b=tmp/10%10; //取十位數(shù)作為個位數(shù)
- c=tmp%10; //取個位數(shù)作為小數(shù)點后一位數(shù)
- LCD_wr_cmd(0x49|0x80); //從2行9列開始顯示
- LCD_wr_dat(num[tmp_sign]); //顯示溫度符號,正溫度顯示空格
- if(a!=0) //如果十位不是0,就顯示,否則跳過不顯示
- LCD_wr_dat(num[a]);
- LCD_wr_dat(num[b]);
- LCD_wr_dat('.');
- LCD_wr_dat(num[c]);
- LCD_wr_dat(0xdf); //角度符號,加上下面的大寫“C”,作為溫度符號
- LCD_wr_dat('C');
- LCD_wr_dat(num[10]); //末尾加一個空格,避免十位不顯示時,這里有殘留的“C”符號
- }
- void main(void)
- {
- RTC_init(); //DS1302初始化
- LCD_init(); //LCD1602初始化
- while (1)
- {
- display(); //顯示
- time_set(); //時間設(shè)置
- }
- }
復(fù)制代碼
報錯如下:
"D:\Program Files (x86)\Labcenter Electronics\Proteus 8 Professional\Tools\MAKE\RunTool.exe" --good-exits=0,1 --executable=C51.exe "..\main.c" ROM(D16M) BROWSE DEBUG CODE OBJECTEXTEND PREPRINT OBJECT("main.OBJ")
C51 COMPILER V9.56.0.0 - SN: K1DZC-CS53EC
COPYRIGHT Copyright (C) 2012 - 2016 ARM Ltd and ARM Germany GmbH. All rights reserved.
*** ERROR C202 IN LINE 5 OF ..\main.c: 'RTC_RST': undefined identifier
*** ERROR C202 IN LINE 6 OF ..\main.c: 'RTC_CLK': undefined identifier
*** ERROR C202 IN LINE 7 OF ..\main.c: 'RTC_RST': undefined identifier
*** ERROR C202 IN LINE 10 OF ..\main.c: 'RTC_DAT': undefined identifier
*** ERROR C202 IN LINE 11 OF ..\main.c: 'RTC_CLK': undefined identifier
*** ERROR C202 IN LINE 12 OF ..\main.c: 'RTC_CLK': undefined identifier
*** ERROR C202 IN LINE 16 OF ..\main.c: 'RTC_DAT': undefined identifier
*** ERROR C202 IN LINE 17 OF ..\main.c: 'RTC_CLK': undefined identifier
*** ERROR C202 IN LINE 18 OF ..\main.c: 'RTC_CLK': undefined identifier
make: *** [main.OBJ] Error 1
*** ERROR C141 IN LINE 19 OF ..\main.c: syntax error near '}'
*** ERROR C202 IN LINE 21 OF ..\main.c: 'RTC_RST': undefined identifier
*** ERROR C129 IN LINE 25 OF ..\main.c: missing ';' before 'RTC_rcom'
C51 COMPILATION COMPLETE. 0 WARNING(S), 12 ERROR(S)
錯誤代碼2
Firmware file missing from the project directory: 80C31_1/Debug/Debug.OMF
Firmware file missing from the project directory: 80C31_1/Debug/Debug.OMF
|
|