各位大神朋友给的一万年历代码,我用keill 与porteus编译都报错。哪位大神指点一下?代码如下:
- //DS1302写8位地址和数据
- 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读数据
- 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写保护
- 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
- }
复制代码
DS18B20驱动代码
- uint tmp;
- uchar tmp_sign;
- //DS18B20对时序有一定要求,有问题的话查一下延迟时序是否符合规格书要求
- //DS18B20初始化
- void tmp_init(void)
- {
- TMP_DQ=0;
- delay(80); //拉低480~960us
- TMP_DQ=1;
- delay(1);
- while(TMP_DQ); //等待应答
- while(!TMP_DQ); //应答结束后等待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_();
- }
- }
- //读取数据,先低后高
- 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); //温度转换
- tmp_init(); //再初始化
- tmp_write(0xcc); //跳过ROM
- tmp_write(0xbe); //请求数据读取
- tmpL=tmp_read(); //接收温度低位
- tmpH=tmp_read(); //接收温度低位
- tmp=tmpH; //高位和低位合并
- tmp=(tmp<<8)|tmpL;
- if(tmp<0x0fff) //判断是正温度
- {
- tmp_sign=10; //符号为空
- tmp=tmp*5/8; //数值*0.0625为温度值,留一位小数,为了方便数据处理,乘以10倍,转为整型
- } //这里用小数的话,代码长度刚好超2k了,一个方法是直接改成(*5/8),节省空间
- else //另一个方法是设置里,把ROM由small改为large
- {
- tmp_sign=11; //负温度显示负号“-”
- tmp=(~tmp+1)*5/8;
- }
- }
复制代码
LCD1602驱动代码
- 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写数据
- 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查忙,检查前面数据是否已处理完
- 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); //光标右移,文字不动
- LCD_wr_cmd(0x0c); //开显示,无光标,不闪烁
- LCD_wr_cmd(0x38); //8位总线,双行显示,5X7的点阵字符
- }
- //获取年月日,星期,时间数据
- 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;
- }
复制代码
按键设置
- 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;
- }
- }
- //按加减键设置时间
- 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); //显示调整的值
- LCD_wr_dat(num[temp/10]);
- LCD_wr_dat(num[temp%10]);
- delay10ms(20); //增加延时,调节增加的速度
- }
- }
- 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); //确定设置键是否按下,按下就跳出循环
- key=0; //按键值清零
- RTC_wcom(RTC_cmd,temp/10*16+temp%10); //最终值写入DS1302
- }
- //星期的计算
- void week_set(void)
- {
- uchar i;
- 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=(yyH*10+yyL)*365+(yyH*10+yyL)/4; //先按年的天数计算,加上闰年天数
- for(i=0;i<moH*10+moL-1;i++) //再加上月的天数
- {
- wk=wk+month_day[i];
- }
- wk=wk+ddH*10+ddL; //再加上天数
- if((yyH*10+yyL)/4==0) //如果当年是闰年
- {
- if(moH*10+moL<3) //且当月不到3月份
- wk=wk-1; //需减去1天
- }
- wk=(wk%7+5)%7+1; //总天数除以7取余,加上2000年1月1日补偿数5,可能超过7,再取余,避免出现0,再加1
- RTC_wcom(0x8a,wk); //写入寄存器
- }
- //时间设置
- void time_set(void)
- {
- key_scan();
- if(key==1) //设置键按下
- {
- key=0;
- LCD_wr_cmd(0x01); //清显示
- LCD_wr_cmd(0x0f); //开显示,有光标,闪烁
- 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); //设置年
- LCD_wr_dat('-');
- LCD_wr_dat('0');
- LCD_wr_dat('1');
- manual_set(1,12,0x05,0x88); //设置月
- LCD_wr_dat('-');
- LCD_wr_dat('0');
- LCD_wr_dat('1');
- manual_set(1,31,0x08,0x86); //设置日
- LCD_wr_cmd(0x40|0x80);
- LCD_wr_dat('0');
- LCD_wr_dat('0');
- manual_set(0,23,0x40,0x84); //设置小时
- LCD_wr_dat(':');
- LCD_wr_dat('0');
- LCD_wr_dat('0');
- manual_set(0,59,0x43,0x82); //设置分钟
- week_set();
- RTC_wcom(0x80,0x00); //开始计时
- LCD_wr_cmd(0x0c); //开显示,无光标,不闪烁
- }
- if(key==2) //复位键按下
- {
- key=0;
- RTC_init(); //DS1302恢复初始值
- }
- }
复制代码
主函数及显示部分:
- #include <reg51.h>
- sbit LCD_RS=P2^0; //LCD相关端口
- 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相关端口
- sbit RTC_CLK=P1^1;
- sbit RTC_RST=P1^2;
- sbit TMP_DQ=P3^7;
- #define LCD_DA P0 //LCD数据口
- 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; //取百位数作为十位数
- b=tmp/10%10; //取十位数作为个位数
- c=tmp%10; //取个位数作为小数点后一位数
- 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(); //时间设置
- }
- }
复制代码
报错如下:
"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
|