找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1216|回复: 6
打印 上一主题 下一主题
收起左侧

51单片机*** ERROR C202 IN LINE 5 OF ..\main.c: 'RTC_RST': undefined identifier

[复制链接]
跳转到指定楼层
楼主
ID:607625 发表于 2023-9-5 14:17 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
     各位大神朋友给的一万年历代码,我用keill 与porteus编译都报错。哪位大神指点一下?代码如下:
  1. //DS1302写8位地址和数据
  2. void RTC_wcom(char addr,char wdata)
  3. {
  4.    char i,j;
  5.    RTC_RST=0;
  6.    RTC_CLK=1;
  7.    RTC_RST=1;
  8.    for(i=0;i<8;i++);
  9.    {
  10.       RTC_DAT=addr >> i & 0x01;
  11.       RTC_CLK=0;
  12.       RTC_CLK=1;
  13.    }
  14.    for(j=0;j<8;j++)
  15.    {
  16.       RTC_DAT=wdata >> j & 0x01;
  17.       RTC_CLK=0;
  18.       RTC_CLK=1
  19.    }
  20.    RTC_CLK=1;
  21.    RTC_RST=0;
  22. }

  23. //DS1302读数据
  24. uchar RTC_rcom(uchar addr)
  25. {
  26.    uchar i,rdata=0;
  27.    RTC_RST=1;
  28.    for(i=0;i<8;i++)
  29.    {
  30.       RTC_CLK=0;
  31.       RTC_DAT=addr>>i & 0x01;
  32.       RTC_CLK=1;
  33.    }
  34.    for(i=0;i<8;i++)
  35.    {
  36.       RTC_CLK=1;
  37.       RTC_CLK=0;
  38.       if(RTC_DAT)
  39.       rdata |= (0x01<<i);
  40.    }
  41.    RTC_DAT=0;
  42.    RTC_CLK=1;
  43.    RTC_RST=0;
  44.    return rdata;
  45. }

  46. //DS1302初始化
  47. void RTC_init(void)
  48. {
  49.    RTC_wcom(0x8e,0x00);        //00允许写,80写保护
  50.    RTC_wcom(0x8c,0x00);        //年,00~99,初始00
  51.    RTC_wcom(0x88,0x01);        //月,01~12,初始01   
  52.    RTC_wcom(0x86,0x01);        //日,01~31,初始01
  53.    RTC_wcom(0x8a,0x06);        //星期,1~7,初始6   
  54.    RTC_wcom(0x84,0x12);        //时,00~23,初始12
  55.    RTC_wcom(0x82,0x00);        //分,00~59,初始00
  56.    RTC_wcom(0x80,0x00);        //秒,00~59,初始00
  57. }
复制代码

DS18B20驱动代码

  1. uint tmp;
  2. uchar tmp_sign;
  3. //DS18B20对时序有一定要求,有问题的话查一下延迟时序是否符合规格书要求
  4. //DS18B20初始化
  5. void tmp_init(void)
  6. {
  7.    TMP_DQ=0;
  8.    delay(80);                //拉低480~960us
  9.    TMP_DQ=1;
  10.    delay(1);
  11.    while(TMP_DQ);        //等待应答
  12.    while(!TMP_DQ);        //应答结束后等待DS18B20释放总线
  13. }
  14. //DS18B20写命令
  15. void tmp_write(uchar cmd)
  16. {
  17.    uchar i;
  18.    for(i=0;i<8;i++)
  19.    {
  20.       TMP_DQ=0;
  21.       _nop_();
  22.       TMP_DQ=cmd & 0x01;
  23.       cmd >>= 1;
  24.       delay(5);
  25.       TMP_DQ=1;
  26.       _nop_();
  27.    }
  28. }
  29. //读取数据,先低后高
  30. uchar tmp_read(void)
  31. {
  32.    uchar i;
  33.    uchar dat=0;
  34.    for(i=0;i<8;i++)
  35.    {
  36.       TMP_DQ=0;
  37.       _nop_();
  38.       TMP_DQ=1;
  39.       _nop_();
  40.       dat >>= 1;
  41.       if(TMP_DQ==1)
  42.       dat |= 0x80;
  43.       delay(5);
  44.       TMP_DQ=1;
  45.       _nop_();
  46.    }
  47.    return dat;
  48. }

  49. void get_tmp(void)
  50. {
  51.    uchar tmpL,tmpH;
  52.    tmp_init();                //初始化
  53.    tmp_write(0xcc);        //跳过ROM
  54.    tmp_write(0x44);        //温度转换
  55.    tmp_init();                //再初始化
  56.    tmp_write(0xcc);        //跳过ROM
  57.    tmp_write(0xbe);        //请求数据读取
  58.    tmpL=tmp_read();        //接收温度低位
  59.    tmpH=tmp_read();        //接收温度低位
  60.    tmp=tmpH;                //高位和低位合并
  61.    tmp=(tmp<<8)|tmpL;
  62.    if(tmp<0x0fff)        //判断是正温度
  63.    {
  64.       tmp_sign=10;        //符号为空
  65.       tmp=tmp*5/8;        //数值*0.0625为温度值,留一位小数,为了方便数据处理,乘以10倍,转为整型
  66.    }                        //这里用小数的话,代码长度刚好超2k了,一个方法是直接改成(*5/8),节省空间
  67.    else                        //另一个方法是设置里,把ROM由small改为large
  68.    {
  69.       tmp_sign=11;        //负温度显示负号“-”
  70.       tmp=(~tmp+1)*5/8;
  71.    }
  72. }
复制代码

LCD1602驱动代码

  1. uchar code num[] = "0123456789 -";
  2. uchar code week[][3] = {"MON","TUE","WED","THU","FRI","SAT","SUN"};
  3. uchar yyH,yyL,moH,moL,ddH,ddL,hhH,hhL,miH,miL,ssH,ssL;
  4. uint wk;

  5. //LCD1602写命令
  6. void LCD_wr_cmd(uchar cmd)
  7. {
  8.    busy_check();
  9.    LCD_RS=0;
  10.    LCD_RW=0;
  11.    LCD_CE=1;
  12.    LCD_DA=cmd;
  13.    delay(100);
  14.    LCD_CE=0;
  15. }
  16. //LCD1602写数据
  17. void LCD_wr_dat(uchar dat)
  18. {
  19.    busy_check();
  20.    LCD_RS=1;
  21.    LCD_RW=0;
  22.    LCD_CE=1;
  23.    LCD_DA=dat;
  24.    delay(100);
  25.    LCD_CE=0;
  26. }
  27. //LCD1602查忙,检查前面数据是否已处理完
  28. void busy_check(void)
  29. {
  30.    uchar busy_flag;
  31.    busy_flag = 0xff;
  32.    LCD_RS=0;
  33.    LCD_RW=1;
  34.    do
  35.    {
  36.       LCD_CE=1;
  37.       busy_flag=LCD_DA;
  38.       delay(100);
  39.       LCD_CE=0;
  40.    }while(busy_flag & 0x80);
  41. }
  42. //LCD初始化
  43. void LCD_init(void)
  44. {
  45.    LCD_wr_cmd(0x01);        //清显示
  46.    LCD_wr_cmd(0x06);        //光标右移,文字不动
  47.    LCD_wr_cmd(0x0c);        //开显示,无光标,不闪烁
  48.    LCD_wr_cmd(0x38);        //8位总线,双行显示,5X7的点阵字符
  49. }
  50. //获取年月日,星期,时间数据
  51. void get_dat(void)
  52. {
  53.    yyH=RTC_rcom(0x8d)/16;
  54.    yyL=RTC_rcom(0x8d)%16;
  55.    moH=RTC_rcom(0x89)/16;
  56.    moL=RTC_rcom(0x89)%16;
  57.    ddH=RTC_rcom(0x87)/16;
  58.    ddL=RTC_rcom(0x87)%16;
  59.    wk =RTC_rcom(0x8b);
  60.    hhH=RTC_rcom(0x85)/16;
  61.    hhL=RTC_rcom(0x85)%16;
  62.    miH=RTC_rcom(0x83)/16;
  63.    miL=RTC_rcom(0x83)%16;
  64.    ssH=RTC_rcom(0x81)/16;
  65.    ssL=RTC_rcom(0x81)%16;
  66. }
复制代码

按键设置

  1. uchar key=0;
  2. uchar code month_day[]={31,28,31,30,31,30,31,31,30,31,30,31};
  3. //按键扫描
  4. void key_scan(void)
  5. {
  6.    if(!t_set)
  7.       {
  8.          delay10ms(1);
  9.          if(!t_set)
  10.          while(!t_set);
  11.          key=1;
  12.       }
  13.    if(!t_rst)
  14.       {
  15.          delay10ms(1);
  16.          if(!t_rst)
  17.          while(!t_rst);
  18.          key=2;
  19.       }
  20. }
  21. //按加减键设置时间
  22. void manual_set(uchar min,uchar max,uchar LCD_cmd,uchar RTC_cmd)
  23. {
  24.    uchar temp=min;
  25.    do
  26.    {
  27.       key_scan();        //按键扫描
  28.       if(!t_add)        //加按键按下,按住就一直增加
  29.       {
  30.          delay10ms(10);
  31.          if(!t_add)
  32.          {
  33.             ++temp;
  34.             if(temp==max+1)temp=min;
  35.             LCD_wr_cmd(LCD_cmd|0x80);        //显示调整的值
  36.             LCD_wr_dat(num[temp/10]);
  37.             LCD_wr_dat(num[temp%10]);
  38.             delay10ms(20);                //增加延时,调节增加的速度
  39.          }
  40.       }
  41.       if(!t_dec)        //减按键按下,功能同上
  42.       {
  43.          delay10ms(10);
  44.          if(!t_dec)
  45.          {
  46.             if(temp==min)temp=max+1;
  47.             --temp;
  48.             LCD_wr_cmd(LCD_cmd|0x80);
  49.             LCD_wr_dat(num[temp/10]);
  50.             LCD_wr_dat(num[temp%10]);
  51.             delay10ms(20);
  52.          }
  53.       }
  54.    }while(key!=1);        //确定设置键是否按下,按下就跳出循环
  55.    key=0;                //按键值清零
  56.    RTC_wcom(RTC_cmd,temp/10*16+temp%10);        //最终值写入DS1302
  57. }
  58. //星期的计算
  59. void week_set(void)
  60. {
  61.    uchar i;
  62.    yyH=RTC_rcom(0x8d)/16;        //获取年月日数据
  63.    yyL=RTC_rcom(0x8d)%16;
  64.    moH=RTC_rcom(0x89)/16;
  65.    moL=RTC_rcom(0x89)%16;
  66.    ddH=RTC_rcom(0x87)/16;
  67.    ddL=RTC_rcom(0x87)%16;
  68.    wk=(yyH*10+yyL)*365+(yyH*10+yyL)/4;        //先按年的天数计算,加上闰年天数
  69.    for(i=0;i<moH*10+moL-1;i++)                //再加上月的天数
  70.    {
  71.       wk=wk+month_day[i];
  72.    }
  73.    wk=wk+ddH*10+ddL;                //再加上天数
  74.    if((yyH*10+yyL)/4==0)        //如果当年是闰年
  75.    {
  76.    if(moH*10+moL<3)                //且当月不到3月份
  77.       wk=wk-1;                        //需减去1天
  78.    }
  79.    wk=(wk%7+5)%7+1;        //总天数除以7取余,加上2000年1月1日补偿数5,可能超过7,再取余,避免出现0,再加1
  80.    RTC_wcom(0x8a,wk);        //写入寄存器
  81. }
  82. //时间设置
  83. void time_set(void)
  84. {
  85.    key_scan();
  86.    if(key==1)        //设置键按下
  87.    {
  88.       key=0;
  89.       LCD_wr_cmd(0x01);                //清显示
  90.       LCD_wr_cmd(0x0f);                //开显示,有光标,闪烁
  91.       LCD_wr_cmd(0x00|0x80);
  92.       LCD_wr_dat('2');
  93.       LCD_wr_dat('0');
  94.       LCD_wr_dat('0');
  95.       LCD_wr_dat('0');
  96.       RTC_wcom(0x8e,0x00);        //00允许写
  97.       RTC_wcom(0x80,0x80);        //停止计时
  98.       manual_set(0,99,0x02,0x8c);        //设置年
  99.       LCD_wr_dat('-');
  100.       LCD_wr_dat('0');
  101.       LCD_wr_dat('1');
  102.       manual_set(1,12,0x05,0x88);        //设置月
  103.       LCD_wr_dat('-');
  104.       LCD_wr_dat('0');
  105.       LCD_wr_dat('1');
  106.       manual_set(1,31,0x08,0x86);        //设置日
  107.       LCD_wr_cmd(0x40|0x80);
  108.       LCD_wr_dat('0');
  109.       LCD_wr_dat('0');
  110.       manual_set(0,23,0x40,0x84);        //设置小时
  111.       LCD_wr_dat(':');
  112.       LCD_wr_dat('0');
  113.       LCD_wr_dat('0');
  114.       manual_set(0,59,0x43,0x82);        //设置分钟
  115.       week_set();
  116.       RTC_wcom(0x80,0x00);        //开始计时
  117.       LCD_wr_cmd(0x0c);                //开显示,无光标,不闪烁
  118.    }
  119.    if(key==2)        //复位键按下
  120.    {
  121.       key=0;
  122.       RTC_init();        //DS1302恢复初始值
  123.    }
  124. }
复制代码

主函数及显示部分:

  1. #include <reg51.h>
  2. sbit LCD_RS=P2^0;        //LCD相关端口
  3. sbit LCD_RW=P2^1;
  4. sbit LCD_CE=P2^2;

  5. sbit t_set=P2^4;        //按键
  6. sbit t_add=P2^5;
  7. sbit t_dec=P2^6;
  8. sbit t_rst=P2^7;

  9. sbit RTC_DAT=P1^0;        //DS1302相关端口
  10. sbit RTC_CLK=P1^1;
  11. sbit RTC_RST=P1^2;

  12. sbit TMP_DQ=P3^7;

  13. #define LCD_DA P0        //LCD数据口
  14. typedef unsigned char uchar;
  15. typedef unsigned int uint;

  16. void display(void)
  17. {
  18.    uchar i;
  19.    uchar a,b,c;
  20.    get_dat();
  21.    //显示日期
  22.    LCD_wr_cmd(0x00|0x80);        //从1行0列开始显示
  23.    LCD_wr_dat('2');
  24.    LCD_wr_dat('0');
  25.    LCD_wr_dat(num[yyH]);
  26.    LCD_wr_dat(num[yyL]);
  27.    LCD_wr_dat('-');
  28.    LCD_wr_dat(num[moH]);
  29.    LCD_wr_dat(num[moL]);
  30.    LCD_wr_dat('-');
  31.    LCD_wr_dat(num[ddH]);
  32.    LCD_wr_dat(num[ddL]);
  33.    //显示星期
  34.    LCD_wr_cmd(0x0c|0x80);
  35.    for(i=0;i<3;i++)
  36.    {
  37.       LCD_wr_dat(week[wk-1][i]);
  38.    }   
  39.    //显示时间
  40.    LCD_wr_cmd(0x40|0x80);        //从2行0列开始显示
  41.    LCD_wr_dat(num[hhH]);
  42.    LCD_wr_dat(num[hhL]);
  43.    LCD_wr_dat(':');
  44.    LCD_wr_dat(num[miH]);
  45.    LCD_wr_dat(num[miL]);
  46.    LCD_wr_dat(':');
  47.    LCD_wr_dat(num[ssH]);
  48.    LCD_wr_dat(num[ssL]);
  49.    //显示温度
  50.    get_tmp();        //获取已乘10倍的温度值
  51.    a=tmp/100;        //取百位数作为十位数
  52.    b=tmp/10%10;        //取十位数作为个位数
  53.    c=tmp%10;        //取个位数作为小数点后一位数
  54.    LCD_wr_cmd(0x49|0x80);        //从2行9列开始显示
  55.    LCD_wr_dat(num[tmp_sign]);        //显示温度符号,正温度显示空格
  56.    if(a!=0)        //如果十位不是0,就显示,否则跳过不显示
  57.    LCD_wr_dat(num[a]);
  58.    LCD_wr_dat(num[b]);
  59.    LCD_wr_dat('.');
  60.    LCD_wr_dat(num[c]);
  61.    LCD_wr_dat(0xdf);        //角度符号,加上下面的大写“C”,作为温度符号
  62.    LCD_wr_dat('C');
  63.    LCD_wr_dat(num[10]);        //末尾加一个空格,避免十位不显示时,这里有残留的“C”符号
  64. }

  65. void main(void)
  66. {
  67.    RTC_init();        //DS1302初始化
  68.    LCD_init();        //LCD1602初始化
  69.    while (1)
  70.    {
  71.       display();        //显示
  72.       time_set();        //时间设置
  73.    }
  74. }

复制代码


    报错如下:
"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



分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:647261 发表于 2023-9-5 15:54 | 只看该作者
额……你这个朋友给的应该不是完整的吧,看下面链接
http://www.51hei.com/bbs/dpj-230067-1.html
回复

使用道具 举报

板凳
ID:1059989 发表于 2023-9-5 23:02 | 只看该作者
看起来 所有代码都是放在一个main.c里的,那要把下面的这些定义,放到main.c的开头。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;
回复

使用道具 举报

地板
ID:1059989 发表于 2023-9-5 23:06 | 只看该作者
看起来所有代码都是放在main.c里的,那要把RTC_CLK等的定义,放到main.c的开头,也就是放在引用这些定义的前面,要先定义,后面才能引用。
回复

使用道具 举报

5#
ID:607625 发表于 2023-9-6 08:15 | 只看该作者
FrankJi 发表于 2023-9-5 23:02
看起来 所有代码都是放在一个main.c里的,那要把下面的这些定义,放到main.c的开头。sbit LCD_RS=P2^0;     ...

谢谢指导
回复

使用道具 举报

6#
ID:607625 发表于 2023-9-6 08:16 | 只看该作者
sttt300 发表于 2023-9-5 15:54
额……你这个朋友给的应该不是完整的吧,看下面链接
http://www.51hei.com/bbs/dpj-230067-1.html

谢谢指导
回复

使用道具 举报

7#
ID:607625 发表于 2023-9-6 08:17 | 只看该作者
谢谢指导
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表