完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
嗨,我试着使用内嵌程序集XC16编译器来执行浮点乘法。该设备是30F4013。第一个值来自查找表,它是一个浮动值,在2和1之间变化,因此,0.9,0.3,0.4等。它与音频样本乘以一个已签名的int。是否有一种在内联汇编中这样做的方法,因为C是非常慢的。我需要执行每一个采样周期乘以48千赫。本质上,结果=AudioSoint(int)* LUTvalue(浮点)。我知道我可以把所有的浮点都转换成整数和比例,但这对于应用来说是不理想的。谢谢。
以上来自于百度翻译 以下为原文 Hi, I'm trying to perform a floating point multiply using inline assembly, XC16 compiler. The device is the 30F4013. The first value comes from a look up table and it's a float value which varies between 2.0 and 1.0, so, 0.9, 0.3, 0.4 etc. It's getting multiplied with an audio sample which is a signed int. Is there a way of doing this in inline assembly as doing it is C is woefully slow. I need to perform the multiply every sample period, running at 48Khz. In essence, Results = AudioSample(INT) * LUTvalue(Float). I understand I can covert all the floats to integers and scale but that isn't ideal for the application. Thanks. |
|
相关推荐
14个回答
|
|
这是我的代码,它似乎不工作。CONCONBITES.IF=0;/*分数模式*/易失性寄存器INT ASM(“A”);ASM(“MOV.W.Audio,W4”);/*已初始化int音频*/ASM(“MOV.W.TrimValuy,W5”);/*浮点LUT值*/ASM(“MPY W4*W5,A”);
以上来自于百度翻译 以下为原文 This is my code, that doesn't appear to work. CORCONbits.IF = 0; /* FRACTION MODE */ volatile register int A asm("A"); asm("MOV.W _AUDIO, W4"); /*Singned Int Audio */ asm("MOV.W _TREMVALUE, W5"); /*Float LUT value */ asm("MPY W4*W5, A"); _FLOATAUDIO = __builtin_ACCL(A); |
|
|
|
用这个或这个替换这个,或者你可以这样做
以上来自于百度翻译 以下为原文 Replace this _FLOATAUDIO = __builtin_ACCL(A); with this FLOATAUDIO = __builtin_ACCH(A); or this FLOATAUDIO = __builtin_sac(A,0); Or you can do this A = __builtin_mpy(AUDIO, TREMVALUE, NULL, NULL, 0, NULL, NULL, 0); FLOATAUDIO = __builtin_sac(A, 0); |
|
|
|
|
|
|
|
谢谢,我现在就试一试。LUT可以保持任何浮点值,在我的例子中,它是一个正弦波,它在1开始,在π/ 2上升到2,在π处上升到1,然后在π/3处上升到0。
以上来自于百度翻译 以下为原文 Thanks, I'll give that a try now. The LUT can hold any float value, in my case, it's a sine wave which starts at 1.0, rises to 2.0 at pi/2, 1.0 at pi ..then 0.0 at pi/3 etc. |
|
|
|
你是指0×3π/2,而不是π/3吗?在这种情况下,我建议你把LUT值除以二,并使用Q15格式,其范围为[-1,+1)。然后将音频样本分成两个这样的例子:
以上来自于百度翻译 以下为原文 Do you mean 0.0 at 3*pi/2, not pi/3? In that case, I suggest you to divide the LUT values by two and use Q15 format which has a range of [-1, +1). Then multiple the audio sample by two like this: A = __builtin_mpy(2 * AUDIO, TREMVALUE, NULL, NULL, 0, NULL, NULL, 0); FLOATAUDIO = __builtin_sacr(A, 0); or this A = __builtin_mpy(AUDIO, TREMVALUE, NULL, NULL, 0, NULL, NULL, 0); FLOATAUDIO = __builtin_sacr(A, -1); |
|
|
|
是的,抱歉3×PI / 2。)宾果!我已经开始工作了!非常感谢输入。我接受了你的建议,但是我把LUT转换成Q15格式,[-1,+1 ],然后我使用分数模式倍增。在C文件中,中间音频是一个已签名的int,并且TrimeValm也是一个签名的int。我猜我可以使用DSP中定义的“分数”数据类型,但是签名INT由于签名和大小相同的顺序而工作。我的问题是需要使用一个叫做“流代码”的编程系统,因此在“补充代码”部分包含Q15数据类型,这使得FC环境难以看到它们。不管怎么说,那是一派胡言。这里的工作是作为参考……CONCONBITIONS = 0;/*分数模式*/易失性寄存器int ASM(“A”);ASM(“MOV.W.IdiimOdio,W4”);ASM(“MOV.W.TrimValuy,W5”);ASMIODION=Y-BuuthTiN-AcCH(A);CONCONBITI.IF=1;/*整数模式*/I认为我需要做一个小MOR。关于蓄能器等的研究(我对这个装置是新的)。我欣赏32位结果中的16×16结果,但在我的逻辑中,乘法的结果应该以ACCL结尾。除非当然,结果是存储MSB第一:……时间挖出来的参考指南!
以上来自于百度翻译 以下为原文 Yes, sorry 3*pi/2. :) Bingo! I've got it working! Many thanks for the input on this. I took your advise but I converted the LUT to Q15 format, [-1, +1], this I then multiply using the fractional mode. In the C file, Interim Audio is a signed INT and TremValue is also a signed INT. I'm guessing I could have used the 'fractional' data type as defined in dsp.h but the signed INT works due to it being signed and of the same order of size. The issue I have is compounded by the need to use a programming system called 'Flowcode' and therefore include Q15 data types in the 'supplementary code' section, this then makes it difficult for the FC environment to see them! Anyway, that's an aside. Here is the working as a reference to others.. CORCONbits.IF = 0; /* FRACTION MODE */ volatile register int A asm("A"); asm("MOV.W _InterimAudio, W4"); asm("MOV.W _TremValue, W5"); asm("MPY W4*W5, A"); InterimAudio = __builtin_ACCH(A); CORCONbits.IF = 1; /* INTEGER MODE */ I think I need to do a little more research with respect to the accumulator etc. (I'm new to this device). I appreciate a 16 * 16 results in 32 bit result, but to my logic, the results of the multiplication should end up in ACCL. Unless of course the results is stored MSB first :) ..time to dig out the reference guide! |
|
|
|
所有这些关于浮动的话题,指数呢?我认为你没有正确的术语。
以上来自于百度翻译 以下为原文 All this talk of floats, what about the exponent? I don't think you have the correct terminology. |
|
|
|
也许。我给OP带来了疑问,因为TyrValm是一个浮点类型;而不是int(分数)类型。
以上来自于百度翻译 以下为原文 Perhaps. I gave OP the benefit of the doubt as to _TremValue is a float type ;) and not an int (fractional) type. |
|
|
|
当你学会了多个两个十进制数时,回到小学时,你必须跟踪小数点。这同样适用于这里——你必须跟踪二进制点。据我所知,你现在用Q1.15(Q15)数乘以一个Q16.0个数。这个乘法的结果有一些Q1715格式(ACC是40位长)。分数模式自动将该乘积乘以2,得到Q16.16格式的结果。正如您所见,ACCL包含小数部分,并且需要ACCH中的整数部分。其中最大Q15值不是1;即Fo* 1!=没有舍入的FO。
以上来自于百度翻译 以下为原文 Go back to grade school when you learned how to multiple two decimal numbers, where you have to keep track of the decimal point. The same applies here -- you have to keep track of the binary point. As I understand it, you are now multiplying a Q16.0 number by a Q1.15 (Q15) number. The result of this multiplication has a number of Q17.15 format (the ACC is 40-bit long). Fractional mode automatically multiples this product by 2 yielding a result of Q16.16 format. As you can see, ACCL contains the fractional part and you want the integral part in ACCH. That said, I would replace this InterimAudio = __builtin_ACCH(A); with this InterimAudio = __builtin_sacr(A,0); as I've shown in my previous post for a rounded result, which also handles the case where max Q15 value is not 1; i.e. foo*1.0 != foo without rounding. |
|
|
|
……我想我数学还好,谢谢。问题是一个实现,可用FC编程环境的数据类型是“浮点”,这与我发现的一个与“双”隐藏使用的问题有关。唉,这个问题通过Q15的使用得到了解决。在乘法之前,我将转换为二进制的ADC值转换为Q15。我已经放弃了在整个代码中使用“浮点”的定义……不过我仍然打算深入研究一下内置函数。再次感谢新年快乐!
以上来自于百度翻译 以下为原文 :) ..I think I'm OK with the math thanks. The issue is one of implementation, the data types available with the FC programming environment were 'float', this was compounded with an issue I found with the manufacturers somewhat hidden use of 'double'! Alas, the issue is solved with the use of Q15 throughout. I'm converting ADC values which are offset binary into Q15 prior to the multiplication. I've ditched the use of 'float' definitions throughout the code. ..I still intend to look into the built in functions a little more though. Thanks again and happy new year! |
|
|
|
您可以简单地使用乘法指令乘以浮点和/或双(除非该设备具有FPU)。
以上来自于百度翻译 以下为原文 You can simply use a multiply instruction to multiply floats and/or double (unless the device has an FPU). |
|
|
|
是的,这个案子有两个问题。Q15乘以分数模式排序。FC环境的细微差别,我躲避…我只是避免那些现在!γ
以上来自于百度翻译 以下为原文 Yes, the issue in this case was two fold. Speed..the Q15 multiply in fractional mode sorted that. The FC environment nuances which I've eluded to...I just avoid those now! |
|
|
|
与累加器相乘并不比正规整数乘法快。
以上来自于百度翻译 以下为原文 Multiplication with accumulator is not any faster than regular integer multiplication. |
|
|
|
使用汇编程序而不是内联速度。C将管理内联的VARS和寄存器,这可能包括修改寄存器。您必须告诉它如何以及这就是问题所在。在ASM中编码更快。如果没有常数,DIVF指令将给出Q1.5个数。否则:;康斯坦图莫夫2 ^ 15×0.25,W4MOV V 1000,W5MPY W4*W5,B;B=1000×0.25内联汇编程序看起来可怕,难以读取,需要更长的代码。你必须要注意登记注册,我已经花了时间,再也没有。
以上来自于百度翻译 以下为原文 Use the assembler rather than inline for speed. C will manage vars and registers with inline which may include modifying registers. You have to tell it how and that is the problem. It's quicker to code in asm. The divf instruction will give Q1.5 numbers if you don't have constants. Otherwise: ;CONSTANT mov #2 ^ 15 * 0.25,w4 mov #1000,w5 mpy w4*w5,B ;B = 1000 * 0.25 ;divide and load B mov offsety,w2 repeat #18-1 divf offsetx,w2 lac w0,#-1,B ;~~~~~~~~~~~~~~~~~~~~~~~~~~~ zeroy: inc offsety,cnt ;~~~~~~~~~~~~~~~~~~~~~~~~~~~ ;plot x,y,color loopliy: mov #ACCAU,w2 add xpos,[w2],w0 mov ypos,w1 mov color,w2 INLINE ASSEMBLER LOOKS HORRIBLE, IS HARD TO READ AND TAKES LONGER TO CODE. You have to take care of register clobbering. I've spent time on it, never again. int listsector(ulong Sector){ ulong addr=Sector; int tmp,ERROR; ubyte s,buf[16],*ptr=buf; //shift sector by sdhd (9 or 0) asm volatile("sl %d0,%1,%d0":"+r"(Sector):"r"(FC->SDHD)); asm volatile("subr %1,#16,%0":"+r"(tmp):"r"(FC->SDHD)); asm volatile("lsr %1,%0,%0":"+r"(tmp):"r"(Sector)); asm volatile("sl %0,%1,%0":"+r"(Sector):"r"(FC->SDHD)); asm volatile("ior %d0,%1,%d0":"+r"(Sector):"r"(tmp)); //send asm volatile("mov.b #%0,w0nmov.d %1,w2ncall _SPI_Send"::"i"(READ_BLOCK),"r"(Sector):"w0","w2","w3"); //check response, if ok get token asm volatile("rcall _SPI_GetR1nsub.b #0xff,w0nbra nz,lresponse":::"w0"); asm volatile("mov #%1,%0":"+r"(ERROR):"i"(ERROR_R1_00));/// asm volatile("bra exit_listsector"); asm volatile("lresponse:"); |
|
|
|
只有小组成员才能发言,加入小组>>
5198 浏览 9 评论
2016 浏览 8 评论
1940 浏览 10 评论
请问是否能把一个ADC值转换成两个字节用来设置PWM占空比?
3188 浏览 3 评论
请问电源和晶体值之间有什么关系吗?PIC在正常条件下运行4MHz需要多少电压?
2243 浏览 5 评论
753浏览 1评论
640浏览 1评论
有偿咨询,关于MPLAB X IPE烧录PIC32MX所遇到的问题
542浏览 1评论
PIC Kit3出现目标设备ID(00000000)与预期的设备ID(02c20000)不匹配。是什么原因
652浏览 0评论
552浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-3 23:26 , Processed in 1.633808 second(s), Total 103, Slave 86 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号