找回密码
 立即注册
楼主: kpffq

请大家帮忙看看乘除法结果数据跑飞的原因是什么 | 已解决,见8楼

[复制链接]
  • 打卡等级:以坛为家III
  • 打卡总天数:682
  • 最近打卡:2025-12-18 09:49:39
已绑定手机

32

主题

370

回帖

3019

积分

论坛元老

机长

积分
3019
发表于 2025-12-2 23:25:47 | 显示全部楼层
kpf*** 发表于 2025-12-2 23:18
谢谢老机长的解答。我按照你的办法试过了还是不行,不管是用8位编译还是32位编译都不行,实在是想不通问题 ...
  1. sum1 = ((u32)ADC_VAL) * ((u32)ADC_VAL);
复制代码

业余撸代码,专业开飞机 https://gitee.com/STC-MCU
回复

使用道具 举报 送花

  • 打卡等级:以坛为家III
  • 打卡总天数:682
  • 最近打卡:2025-12-18 09:49:39
已绑定手机

32

主题

370

回帖

3019

积分

论坛元老

机长

积分
3019
发表于 2025-12-2 23:42:16 | 显示全部楼层

这是原始的C代码:

uint16_t calc1(uint16_t ADC_VAL)
{
    uint32_t sum1 = ADC_VAL * ADC_VAL;
    return (uint16_t)(sum1 / diff);
}

uint16_t calc2(uint16_t ADC_VAL)
{
    uint32_t sum1 = ((uint32_t)ADC_VAL) * ADC_VAL;
    return (uint16_t)(sum1 / diff);
}

这是生成的汇编:

;------------------------------------------------------------
;Allocation info for local variables in function 'calc1'
;------------------------------------------------------------
;ADC_VAL                   Allocated to registers r6 r7 
;sum1                      Allocated to registers 
;------------------------------------------------------------
;	.\src\main.c:27: uint16_t calc1(uint16_t ADC_VAL)
;	-----------------------------------------
;	 function calc1
;	-----------------------------------------
_calc1:
;	.\src\main.c:29: uint32_t sum1 = ADC_VAL * ADC_VAL;
	mov	r6,dpl
	mov	r7,dph
	mov	__mulint_PARM_2,r6
	mov	(__mulint_PARM_2 + 1),r7
	lcall	__mulint
;	.\src\main.c:30: return (uint16_t)(sum1 / diff);
	mov	r4,_diff
	mov	r5,(_diff + 1)
	mov	__divsint_PARM_2,r4
	mov	(__divsint_PARM_2 + 1),r5
;	.\src\main.c:31: }
	ljmp	__divsint

;------------------------------------------------------------
;Allocation info for local variables in function 'calc2'
;------------------------------------------------------------
;ADC_VAL                   Allocated to registers r6 r7 
;sum1                      Allocated to registers r4 r5 r6 r7 
;------------------------------------------------------------
;	.\src\main.c:33: uint16_t calc2(uint16_t ADC_VAL)
;	-----------------------------------------
;	 function calc2
;	-----------------------------------------
_calc2:
	mov	r6, dpl
	mov	r7, dph
;	.\src\main.c:35: uint32_t sum1 = ((uint32_t)ADC_VAL) * ADC_VAL;
	mov	r5,#0x00
	mov	r4,#0x00
	mov	__mullong_PARM_2,r6
	mov	(__mullong_PARM_2 + 1),r7
	mov	(__mullong_PARM_2 + 2),r5
	mov	(__mullong_PARM_2 + 3),r4
;	.\src\main.c:36: return (uint16_t)(sum1 / diff);
	mov	dpl, r6
	mov	dph, r7
	mov	b, r5
	mov	a, r4
	lcall	__mullong
	mov	__divulong_PARM_2,_diff
	mov	(__divulong_PARM_2 + 1),(_diff + 1)
	mov	(__divulong_PARM_2 + 2),#0x00
	mov	(__divulong_PARM_2 + 3),#0x00

肉眼可见的差异巨大。虽然我用的sdcc可能和keil有区别,但不会太离谱

业余撸代码,专业开飞机 https://gitee.com/STC-MCU
回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:108
  • 最近打卡:2025-12-18 09:07:02
已绑定手机

13

主题

25

回帖

139

积分

注册会员

积分
139
发表于 2025-12-2 23:46:32 | 显示全部楼层
  1.         diff = 301;
  2.     sum1 = ((u32)diff)*((u32)diff);
  3.     rms = (u16)sum1/diff;         //       
  4. //        rms = 301;
复制代码
如果使用后面的rms = 301,显示的返回值是12D,说明显示子程序是没问题的,但如果屏蔽这条语句,平方再开方后显示的运算结果居然是0X0053。


回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:295
  • 最近打卡:2025-12-03 10:18:33

8

主题

319

回帖

1846

积分

金牌会员

积分
1846
发表于 2025-12-3 10:18:33 | 显示全部楼层
kpf*** 发表于 2025-12-2 23:46
如果使用后面的rms = 301,显示的返回值是12D,说明显示子程序是没问题的,但如果屏蔽这条语句,平方再开 ...

我很好奇你为啥偏要加个(u16)在sum1前?
sum1 = 301 * 301 =  90601 = 0x161E9
(u16) sum1 = 0x61E9
rms = 0x61E9 / 0x012D = 0x0053
没毛病
回复

使用道具 举报 送花

  • 打卡等级:以坛为家III
  • 打卡总天数:682
  • 最近打卡:2025-12-18 09:49:39
已绑定手机

32

主题

370

回帖

3019

积分

论坛元老

机长

积分
3019
发表于 2025-12-3 10:27:48 | 显示全部楼层
[quote][size=2][url=forum.php?mod=redirect&goto=findpost&pid=197329&ptid=21113][color=#999999]kpffq 发表于 2025-12-2 23:46[/color][/url][/size] 如果使用后面的rms = 301,显示的返回值是12D,说明显示子程序是没问题的,但如果屏蔽这条语句,平方再开 ...[/quote]
diff = 301;
sum1 = ((u32)diff) * ((u32)diff);
rms = (u16) (sum1 / diff);

大哥,当你看到我第二次回复,就应该勤点打括号了呀。

我也记不住那么多类型隐式转换的细节,但知道肯定是这个隐式类型转换的锅。
diff = 301 (0x012D)
sum1 = 90601(0x000161E9)
没括号时:
(u16)sum1 = 0x61E9(25065)
rms = 25065 / 301 = 83(0x0053)
这不是很符合你的结果么?

业余撸代码,专业开飞机 https://gitee.com/STC-MCU
回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:191
  • 最近打卡:2025-12-18 08:26:01
已绑定手机

19

主题

541

回帖

1919

积分

金牌会员

积分
1919
发表于 2025-12-3 11:03:03 | 显示全部楼层
计算结果不管怎样,应该不至于跑飞
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看II
  • 打卡总天数:24
  • 最近打卡:2025-12-18 11:09:37
已绑定手机

1

主题

57

回帖

203

积分

中级会员

积分
203
发表于 2025-12-3 11:19:04 | 显示全部楼层
解决了吗?
你这代码里能看到u8、u16、u32的定义吗?建议确认一下。
回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:108
  • 最近打卡:2025-12-18 09:07:02
已绑定手机

13

主题

25

回帖

139

积分

注册会员

积分
139
发表于 2025-12-3 19:06:12 | 显示全部楼层
lcws*** 发表于 2025-12-3 11:19
解决了吗?
你这代码里能看到u8、u16、u32的定义吗?建议确认一下。

解决了,方法在8楼
回复

使用道具 举报 送花

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

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-12-18 14:47 , Processed in 0.114188 second(s), 86 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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