找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4035|回复: 6
收起左侧

单片机Keil C程序修改传入子函数的参数形式出现致命错误,请大佬解释

[复制链接]
ID:294657 发表于 2018-10-1 18:40 | 显示全部楼层 |阅读模式
今天写程序时遇到一个不能理解的语法错误,
编译时显示致命错误,
请问各位大神是什么原因呢

TIM截图20181001183448.png 20181001183322.png
报错如下:
compiling mian.c...
C51 FATAL-ERROR -
  ACTION:     GOBAL OPTIMIZATION
  FUNCTION:   _year_split
  ERROR:      CANNOT OPTIMIZE FUNCTION
COMPILATION TERMINATED.
use the following work-around:
  #pragma OPTIMIZE (7)
           /* your original function        */
    _year_split ()  {
       ....
    }
           /* end of your original function */
  #pragma OPTIMIZE (8)



实验显示我不给定义的变量赋初值,或者传到子程序的参数为修改为uchar类型之后就可以了,但是uint类型却不行,不知道为什么

全部程序如下:(问题语句为void year_split(int value)这个子函数钟
  1. #include <reg52.h>
  2. #define uchar unsigned char
  3. #define uint unsigned  int
  4. #define Date P0
  5. sbit RS=P1^0;
  6. sbit RW=P1^1;
  7. sbit EN=P2^5;
  8. sbit FM=P2^3;
  9. sbit SW1=P3^5;
  10. sbit SW2=P3^6;
  11. sbit SW3=P3^7;
  12. int second = 0, minute = 0, hour = 0;
  13. int nian = 1988,yue = 0,ri = 0;
  14. uint count = 0;
  15. uint num = 0;

  16. void delay(uint xms)
  17. {
  18. uint i,j;
  19. for(i=xms;i>0;i--)
  20. for(j=112;j>0;j--);
  21. }
  22. void ring()
  23. {
  24. FM=0;
  25. delay(100);
  26. FM=1;
  27. }
  28. void com(uchar command)
  29. {
  30. RS=0;
  31. RW=0;
  32. Date=command;
  33. delay(5);
  34. EN=1;
  35. delay(5);
  36. EN=0;
  37. }
  38. void dat(uchar date)
  39. {
  40. RS=1;
  41. RW=0;
  42. Date=date;
  43. delay(5);
  44. EN=1;
  45. delay(5);
  46. EN=0;
  47. }
  48. void year_split(int value)
  49. {
  50. int qian=0,bai=0,shi=0,ge=0;
  51. qian = value / 1000;
  52. bai = (value / 100) % 10;
  53. shi = (value / 10) % 10;
  54. ge = value % 10;
  55. com(0x80);
  56. dat(qian + 0x30);
  57. dat(bai + 0x30);
  58. dat(shi + 0x30);
  59. dat(ge + 0x30);
  60. }
  61. void date_split(uchar add,uchar value)
  62. {
  63. int shi,ge;
  64. shi = value / 10;
  65. ge = value % 10;
  66. com(0x80+add);
  67. dat(shi + 0x30);
  68. dat(ge + 0x30);
  69. }
  70. void time_split(uchar add,uchar value)
  71. {
  72. int shi,ge;
  73. shi = value / 10;
  74. ge = value % 10;
  75. com(0xc0+add);
  76. dat(shi + 0x30);
  77. dat(ge + 0x30);
  78. }
  79. void LCD_Init()
  80. {
  81. com(0x38); //LCD设置
  82. delay(5);
  83. com(0x01); //清屏
  84. com(0x06); //写入新数据后光标后移一位,整屏不移动
  85. com(0x0c); //显示光标,光标不显示
  86. }
  87. void Time_Init()
  88. {
  89. com(0x80+4);
  90. dat('-');
  91. com(0x80+7);
  92. dat('-');
  93. com(0xc0+6);
  94. dat(':');
  95. com(0xc0+9);
  96. dat(':');

  97. year_split(nian);
  98. date_split(5,yue);
  99. date_split(8,ri);

  100. time_split(4,hour);
  101. time_split(7,minute);
  102. time_split(10,second);

  103. TMOD = 0x01;
  104. TH0 = (65536-46083)/256;
  105. TL0 = (65536-46083)%256;
  106. EA = 1;
  107. ET0 = 1;
  108. TR0 = 1;
  109. }
  110. void Set_key()
  111. {
  112. if(SW1 == 0)
  113. {
  114.   delay(5);
  115.   if(SW1 == 0)
  116.   {
  117.    while(SW1 == 0);
  118.    num++;
  119.    ring();
  120.   }
  121. }
  122. switch(num)
  123. {
  124.   case 1:
  125.    TR0 = 0;    //定时器关
  126.    com(0xc0+10);
  127.    com(0x0f);   //显示开,光标闪烁
  128.    if(SW2 == 0)
  129.    {
  130.     delay(5);
  131.     if(SW2 == 0)
  132.     {
  133.      while(SW2 == 0);
  134.      second++;
  135.      ring();
  136.      if(second >= 60)
  137.      {
  138.       second = 0;
  139.      }
  140.      time_split(10,second);
  141.     }
  142.    }
  143.    
  144.    if(SW3 == 0)
  145.    {
  146.     delay(5);
  147.     if(SW3 == 0)
  148.     {
  149.      while(SW3 == 0);
  150.      second--;
  151.      ring();
  152.      if(second <= -1)
  153.      {
  154.       second = 59;
  155.      }
  156.      time_split(10,second);
  157.     }
  158.    }
  159.    break;

  160.    case 2:
  161.    com(0xc0+8);
  162.    if(SW2 == 0)
  163.    {
  164.     delay(5);
  165.     if(SW2 == 0)
  166.     {
  167.      while(SW2 == 0);
  168.      minute++;
  169.      ring();
  170.      if(minute >= 60)
  171.      {
  172.       minute = 0;
  173.      }
  174.      time_split(7,minute);
  175.     }
  176.    }
  177.    
  178.    if(SW3 == 0)
  179.    {
  180.     delay(5);
  181.     if(SW3 == 0)
  182.     {
  183.      while(SW3 == 0);
  184.      minute--;
  185.      ring();
  186.      if(minute <= -1)
  187.      {
  188.       minute = 59;
  189.      }
  190.      time_split(7,minute);
  191.     }
  192.    }
  193.    break;
  194.    
  195.    case 3:
  196.    com(0xc0+4);
  197.    if(SW2 == 0)
  198.    {
  199.     delay(5);
  200.     if(SW2 == 0)
  201.     {
  202.      while(SW2 == 0);
  203.      hour++;
  204.      ring();
  205.      if(hour >= 24)
  206.      {
  207.       hour = 0;
  208.      }
  209.      time_split(4,hour);
  210.     }
  211.    }   
  212.    
  213.    if(SW3 == 0)
  214.    {
  215.     delay(5);
  216.     if(SW3 == 0)
  217.     {
  218.      while(SW3 == 0);
  219.      hour--;
  220.      ring();
  221.      if(hour <= -1)
  222.      {
  223.       hour = 23;
  224.      }
  225.      time_split(4,hour);
  226.     }
  227.    }
  228.    
  229.    break;
  230.    
  231.    case 4:
  232.     num = 0;
  233.     TR0 = 1;   //定时器开
  234.     com(0x0c);  //显示关,光标不闪烁
  235.     break;
  236.   }
  237. }

  238. void Set_display()
  239. {
  240. if(count == 20)
  241. {
  242.   count = 0;
  243.   second++;
  244.   time_split(10,second);
  245.   if(second >= 60)
  246.   {
  247.    second = 0;
  248.    minute++;
  249.    time_split(10,second);
  250.    time_split(7,minute);
  251.    if(minute >= 60)
  252.    {
  253.     minute = 0;
  254.     hour++;
  255.     time_split(7,minute);
  256.     time_split(4,hour);
  257.     if(hour >= 24)
  258.     {
  259.      hour = 0;
  260.      time_split(4,hour);
  261.     }
  262.    }
  263.   }
  264. }
  265. }
  266. void main()
  267. {
  268. LCD_Init();
  269. Time_Init();
  270. while(1)
  271. {
  272.   Set_key();
  273.   Set_display();
  274. }
  275. }
  276. void time()interrupt 1
  277. {
  278. count++;
  279. TH0 = (65536-46083)/256; //50ms=(12/11059200)*1000*(65536-初值)
  280. TL0 = (65536-46083)%256;
  281. }
复制代码

回复

使用道具 举报

ID:387733 发表于 2018-10-1 20:29 | 显示全部楼层
把优化级别降到6级及6级以下就能通过了
回复

使用道具 举报

ID:387733 发表于 2018-10-2 16:21 | 显示全部楼层
经过实验,只要把 delay 函数的变量改成 uchar 也是可以通过的
void delay(uchar xms)
{
uchar i,j;
for(i=xms;i>0;i--)
for(j=112;j>0;j--);
}
回复

使用道具 举报

ID:405708 发表于 2018-10-5 23:00 | 显示全部楼层
你的dat形参是8位的,而你定义这几个变量都是int的,而且还加了个0x30很容易溢出,最后发现在屏蔽ge那行或把ge等于0去掉会编译通过,具体原因未知,但要把你的程序整理一下,你的程序风格不好,很不严谨,不方便维护。
回复

使用道具 举报

ID:294657 发表于 2018-10-6 18:31 | 显示全部楼层
psuxaog 发表于 2018-10-5 23:00
你的dat形参是8位的,而你定义这几个变量都是int的,而且还加了个0x30很容易溢出,最后发现在屏蔽ge那行或 ...

好的,谢谢您的提醒,确实存在容易溢出的问题,我以后会汲取这样的教训的的
回复

使用道具 举报

ID:294657 发表于 2018-10-6 18:40 | 显示全部楼层
sxhwdz 发表于 2018-10-2 16:21
经过实验,只要把 delay 函数的变量改成 uchar 也是可以通过的
void delay(uchar xms)
{

定义的时候定义成无符号字符型也可以赋值,并通过了
回复

使用道具 举报

ID:406159 发表于 2018-10-7 16:08 | 显示全部楼层
很不错我的也有这个问题看了之后解决了有用
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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