21cnsound 发表于 2025-3-14 07:47:36

社区闲人 发表于 2025-3-14 06:51
STC提供的USB库太臃肿了,最佳解决方案是:STC公司再提供一个精简版的USB库。 ...

我之前也是觉得最好能把纯USB部分和虚拟设备(数码管、12864等)分开更灵活。

神农鼎 发表于 2025-3-14 08:08:31

Keil C251的如下 软件实现的浮点库函数 Ai8051U没有硬件支持:
double exp   (double val);
double log   (double val);
double log10 (double val);
double asin(double val);
double acos(double val);
double sinh(double val);
double cosh(double val);
double tanh(double val);
double atan2 (double y, double x);
double ceil(double val);
double floor (double val);
double modf(double val, double *n);
double pow   (double x, double y);
double fmod(double x, double y);

STC32G 需要实现全部的Keil C251 软件浮点库函数如下:
浮点数基本的加、减、乘、除、比较、取负数
浮点数与整数和长整数之间的转换
以及如下keil的基本浮点函数
double fabs(double val);
double sqrt(double val);
double exp   (double val);
double log   (double val);
double log10 (double val);
double sin   (double val);
double cos   (double val);
double tan   (double val);
double asin(double val);
double acos(double val);
double atan(double val);
double sinh(double val);
double cosh(double val);
double tanh(double val);
double atan2 (double y, double x);
double ceil(double val);
double floor (double val);
double modf(double val, double *n);
double pow   (double x, double y);
double fmod(double x, double y);

内部暂时能想到的有上面这些


王昱顺 发表于 2025-3-14 20:27:15

21cnsound 发表于 2025-3-14 00:21
经测试,16位的除法加入MDU32_SIDIV库解决了,但8位除法还是同样的问题,请楼主验证。
代码如下:
    char ...

现已加入了8位的除法部分,包含库以后,Keil编译器会优先使用用户定义的部分

所以可以避免掉Keil编译器本身的BUG

可以先行测试,稍后会同步到官方库中

机灵小老鼠 发表于 2025-3-14 22:50:53

21cnsound 发表于 2025-3-14 07:47
我之前也是觉得最好能把纯USB部分和虚拟设备(数码管、12864等)分开更灵活。 ...
我觉得也是。 看看C51标准库,一个库也就几个函数,分门别类,很清晰,由用户单独使用;
建议STC也可以这样, 将库分解为 USB接口部分, 数码管调试接口部分,液晶调试接口部分,...
而且这样也有利于将来再增加其他的调试接口库。

18344371880 发表于 2025-3-14 23:42:45

机灵小老鼠 发表于 2025-3-14 22:50
我觉得也是。 看看C51标准库,一个库也就几个函数,分门别类,很清晰,由用户单独使用;
建议STC也可以这样,...

附议

21cnsound 发表于 2025-3-15 08:12:32

王昱顺 发表于 2025-3-14 20:27
现已加入了8位的除法部分,包含库以后,Keil编译器会优先使用用户定义的部分

所以可以避免掉Keil编译器 ...

经验证,8位有符号除是OK的

王昱顺 发表于 2025-3-17 13:32:14

zhp 发表于 2025-3-13 12:57
关于在C251环境下使用USB的库函数时,如果加上REMOVEUNUSED链接指令后
Keil编译器会错误的移除部分Keil的内 ...
目前通过调试定位到,
原因是有其他程序文件使用了stdio.h的内的任意函数后(例如printf、scanf),
如果main函数没有调用这些函数,那么使用REMOVEUNUSED就会出现LCALL 0x0000异常。
最快的解决方案就是在程序开头加上一段没有意义的调用。
例如定义全局变量test;
然后在main函数开头写一个sprintf(test,"1");
就可以让全部的链接都变得正确了,无论是浮点还是整数的各种运算,都不会出现LCALL 0x0000
目前编译器内部导致链接错误的原因尚未得知

王昱顺 发表于 2025-3-17 15:44:03

目前可复现引起LCALL 0x0000问题的最小工程
大家可以帮忙测试看看是否能找到问题所在


已知触发原因为:
其他的.c文件内调用任意包含stdio.h的函数后,在main.c内未使用


已知解决方案为:
在程序最开头手动调用一次stdio.h中的任意函数即可解决问题
这里调用的是sprintf,向内存写了个数据,没有实际意义,但是可以避免掉编译器的Bug


以下是工程文件和出现问题的几种情况截图:







ercircle 发表于 2025-3-17 23:47:58

提供一个简单粗暴的解决办法,在头文件中宏替换main函数,看看是否可行
{:ciya:}:




神农鼎 发表于 2025-3-18 09:19:14

/*--------------------------------------------------------------------------
STDIO.H

Prototypes for standard I/O functions for C251 Version 3.
Copyright (c) 1995-2001 Keil Elektronik GmbH and Keil Software, Inc.
All rights reserved.
--------------------------------------------------------------------------*/

#pragma SAVE
#pragma PARM251

#ifndef EOF
#define EOF -1
#endif

#ifndef NULL
#define NULL ((void *) 0)
#endif

#ifndef _SIZE_T
#define _SIZE_T
typedef unsigned int size_t;
#endif

#if (__C251__ >= 200)
#pragma SAVE
#pragma FUNCTIONS(STATIC)
/* only static functions available */
extern char _getkey(void);
extern char getchar(void);
extern char ungetchar(char);
extern char putchar(char);
extern intprintf   (const char *, ...);
extern char *gets    (char *, int n);
extern intscanf    (const char *, ...);
extern intvprintf(const char *, char *);
extern intputs   (const char *);
#pragma RESTORE
/* available as reentrant & non-reentrant version */
extern intsprintf(char *, const char *, ...);
extern intvsprintf (char *, const char *, char *);
extern intsscanf   (char *, const char *, ...);
#else
extern char _getkey (void);
extern char getchar (void);
extern char ungetchar (char);
extern char putchar (char);
extern int printf   (const char *, ...);
extern int sprintf(char *, const char *, ...);
extern int vprintf(const char *, char *);
extern int vsprintf (char *, const char *, char *);
extern char *gets (char *, int n);
extern int scanf (const char *, ...);
extern int sscanf (char *, const char *, ...);
extern int puts (const char *);
#endif

#pragma RESTORE


页: 1 2 [3] 4 5
查看完整版本: 解决编译器【REMOVEUNUSED选项】,可能错误移除问题,现象是感觉复位了