大明狐 发表于 2025-3-13 12:01
因为平时主要玩的是OLED屏幕,当时遇到的情况是USB下载和REMOVEUNUSED同时用会重启。
现象总结起来就是
我现在尝试同时添加USB-CDC库和使用乘除法(添加MDU32LIB情况下),得到程序是正常使用的
可以帮忙测试一下原来有问题工程中,添加官网刚更新的MDU32LIB库,看看是否能正常使用?				
			
		大明狐 发表于 2025-3-13 12:24
试了一下在LIB方式USB下载的有问题的工程里,添加楼主的MDU32_SIDIV.LIB,
重新编译之后果然不会重启了
目前此程序分支已经合并进入官网的MDU32库中
可以直接使用官网的LIB库来解决了
				
			
		王昱顺 发表于 2025-3-13 12:24
我现在尝试同时添加USB-CDC库和使用乘除法(添加MDU32LIB情况下),得到程序是正常使用的
可以帮忙测试一 ...
刚试完你就问到了{:4_187:}				
			
		关于在C251环境下使用USB的库函数时,如果加上REMOVEUNUSED链接指令后
Keil编译器会错误的移除部分Keil的内部库函数
目前发现错误的移除的库包括:
1、浮点加、减、乘、除、取负数函数
2、所有三角函数和反三角函数
3、楼主发现的整型有符号除法SIDIV函数
如下图,函数移除后,编译器会默认将原函数的地址设置为0000H,导致程序复位
直接去掉REMOVEUNUSED链接指令,可以解决上的问题
但去掉REMOVEUNUSED后,Keil会将USB库中所有模块全部链接到目标文件中
从而会导致相当一部分的程序空间和RAM空间被浪费
建议的解决办法:
如果需要使用USB的库,请同时将STC32G对应的MDU32的库和
FPMU浮点库也一同加入到项目中,如下图:
另外还需要注意一点,由于USB.LIB 库+REMOVEUNUSED,Keil C251 会无条件移除全部的Keil内部的浮点库,
所以如果您的代码中浮点运算并没有在STC32G的FPMU库中支持,依然会出现复位的情况
如上图中的asin函数,STC32G的FPMU库没有支持,依然会LCALL 0000H的地址
所以您需要特别注意STC32G的MDU32和FPMU库所支持的函数
MDU32支持的函数如下:
长整型乘法运算(包含有符号和无符号)
整型乘法运算(包含有符号和无符号)
无符号长整型除法运算
无符号长整型除以无符号整型运算
有符号长整型除法运算
有符号整型除法运算
FPMU指定的函数如下:
浮点数加法运算
浮点数减法运算
浮点数乘法法运算
浮点数除法运算
开方运算
浮点数比较
浮点数取负数运算
浮点数取绝对值运算
浮点数与整数之间的转换函数
正弦三角函数
余弦三角函数
正切三角函数
反正切三角函数
如果您的程序使用了USB库,且需要使用REMOVEUNUSED,
则注意不能使用上面函数之外其他数学函数
				
			
		zhp 发表于 2025-3-13 12:57
关于在C251环境下使用USB的库函数时,如果加上REMOVEUNUSED链接指令后
Keil编译器会错误的移除部分Keil的内 ...
void main(void)
{
    int volatile x;
    x /= 100;
    while (1)
    {
    }
}
转成ASM后的结果是:
$NOMACRO
$MODSRC
$MODEL(1)
$CASE
;
; 'main.SRC' generated from 'main.c'
; COMPILER INVOKED BY:
;      D:\Software\单片机\编译\C251_V560\C251.EXE main.c SRC
;
                NAME main
      EXTRN         CODE : NEAR (?C?STARTUP)
      EXTRN         CODE : NEAR (?C?SIDIV)
            ?PR?MAIN?MAINSEGMENTCODE
            ?DT?MAIN?MAINSEGMENTDATA OVERLAYABLE (main) 
      RSEG       ?DT?MAIN?MAIN
         x?040:DSW1
;--- special function registers and bits:
             ACCDATA0E0H
             PSWDATA0D0H
             DPLDATA082H
             DPHDATA083H
               BDATA0F0H
            SPDATA081H
            PSW1DATA0D1H
               ZBIT   0D1H.1
            EABIT   0A8H.7
            OVBIT   0D0H.2
               PBIT   0D0H.0
            F0BIT   0D0H.5
             RS1BIT   0D0H.4
             RS0BIT   0D0H.3
            ACBIT   0D0H.6
;--- end of special function registers and bits.
      PUBLIC      main
; line 1: //#include "stc32g.h"
; line 2: 
; line 3: 
; line 4: 
; line 5: void main(void)
      RSEG       ?PR?MAIN?MAIN
      main PROC
; line 6: {
; line 7:   int volatile x;
; line 8:   x /= 100;
      MOV      WR4,#064H
      MOV      WR6,x?040
      LCALL    ?C?SIDIV
      MOV      x?040,WR6
; line 9:   while (1)
; line 10:   {
; line 11: 
; line 12:   }
?C0001:
      SJMP   ?C0001
      ENDP
; line 13: }
      END
并没有生成LCALL 0000H				
			
		21cnsound 发表于 2025-3-13 15:07
void main(void)
{
    int volatile x;
没有产生LCALL 0000H
是因为首先你没有使用usb的库
其次出现问题是最后的链接阶段
				
			
		mark,学习				
			
		经测试,16位的除法加入MDU32_SIDIV库解决了,但8位除法还是同样的问题,请楼主验证。
代码如下:
    char volatile x; 
    x /= 100; 
其他类型、其他运算暂未测试。				
			
		21cnsound 发表于 2025-3-14 00:21
经测试,16位的除法加入MDU32_SIDIV库解决了,但8位除法还是同样的问题,请楼主验证。
代码如下:
    char ...
好的,我们会继续扩大测试并补充进mdu32的lib库中
之后有新的更新会在本帖同步通知				
			
		STC提供的USB库太臃肿了,最佳解决方案是:STC公司再提供一个精简版的USB库。