浪潮携手环球仪器,用FuzionOF组装机攻克异形组装挑战
06-06
在单片机应用系统中,常用到很多复杂的数学计算,比如sin(x)、cos(x)的计算、有效值计算、非线性插值等,这些都很简单高级语言中的任务非常复杂,但微控制器的汇编语言中却非常复杂。
由于这些运算大多采用乘法、除法运算来进行近似运算,计算精度很难满足要求。
更令人难以接受的是,它的运算时间太长,特别是对于没有乘法和除法指令的单片机系统。
用查找表代替复杂的计算是明智的选择。
但这种查表程序的表往往很长,一般有几十到一两百条。
如果采用手工输入,不仅耗费大量时间,而且容易出错。
采用高级语言的单片机查表程序自动生成技术,可以大大减少工作量,不易出错。
使用过Microchip的PIC16系列单片机的读者都知道,该系列单片机有很多优点。
唯一遗憾的是该指令中没有乘法和除法指令(只有PIC17系列有乘法指令)。
在应用中,我们常常要自己编写乘法和除法程序来完成乘法和除法运算。
这种程序执行需要花费大量时间,例如双字节乘法。
一项运算需要多个指令周期,并且如果要使用乘法和除法来执行 sin(x)、cos(x) 和平方根的计算需要更多时间。
因此,利用高级语言自动生成单片机查表程序的技术在PIC16系列单片机中就显得更加有意义。
现在我们以目前在我国广泛使用的Microchip的PIC16系列单片机为例,通过几个例子来说明该技术的应用。
当然,这种方法也可以用在其他单片机上,但示例程序中有关单片机的语句必须改为相应的单片机语言。
本文使用Tubro C作为高级语言编程工具,但也可以使用其他高级语言。
1原理 利用高级语言自动生成查表程序的本质是利用高级语言的计算功能,将原本复杂的计算转换为简单的查表结果,并输出文本文件形式的表查找程序。
单片机编程时将此程序插入相应的程序中。
应用中需要注意的是查表结果没有小数,所以计算输出时必须四舍五入;查表结果只能在0到0之间,超出这个范围就必须处理。
PIC16 系列单片机汇编程序的默认计数系统是十六进制。
如果要使用小数,则必须加“.”号码之前。
另外需要注意的是,在插入查表程序时,要特别注意查表程序不能跨越0~页。
2 示例 2.1 使用D/A输出复杂波形 D/A器件可用于输出复杂波形,如sin(x)、双音多频信号等复杂波形。
这里我们以并行D/A并输出sin(x)为例。
假设电源电压为5V,D/A的参考电压也为5V。
同时假设sin(x)的半波总共输出90点(2°输出1点),对应的C语言源程序如下: /*程序A.C*/ #include #include main() { FILE *fp; char f[15]; float Vmax,v,w; int i,k; puts("输出文件名:"); gets(f); /* 输入要输出的文件名 */ if((fp=fopen(f,"w"))= =NULL) {puts("不打开输出文件"); exit( 0); } puts("Vmax:"); scanf("%f",&Vmax); /*输入要输出的sin波形峰值*/ fprintf(fp,"SUB1 MOVWF BUF"); /*输出查表程序的第一行*/ fprintf(fp,"SUBLW .%d",90); /*输出查表程序第二行*/ fprintf(fp,"BTFSS STATUS, C"); /*输出查表程序的第3行*/ fprintf(fp,"RETLW .0"); /*输出查表程序第4行*/ fprintf(fp,"MOVLW HIGH($)"); /*输出查表程序第5行*/ fprintf(fp,"MOVWF PCLATH"); /*输出查表程序第6行Line*/ fprintf(fp,"MOVF BUF,W"); /*输出查表程序第7行*/ fprintf(fp,"ADDWF PCL,F"); /*输出查表程序第8行*/ for(i=0;i)k=; fprintt(fp,"RETLW.%d;%.d",k,i) ; /*输出查找表*/ } fclose(fp); printf("按任意键结束..."); getch(); } 使用上述程序,计算时输入文件名A.ASM,Vmax=3。
得到的A.ASM内容如下(共90行表,省略大部分): ; A.ASM SUB1 MOVWF BUF SUBLW .90 BTFSS 状态,C RETLW .0 MOVLW 高 ($) MOVWF PCLATH MOVF BUF,W ADDWF PCL,0 … RETLW .11; 88 RETLW .5; 89 RETLW.0; 90 将以下程序插入单片机程序中适当的位置,查表时给W对应的值赋值。
然后CALL SUB1即可得到W点sin(x)的值。
整个计算大约需要10个指令周期(如果使用4MHz晶振则约为10μs)。
如果用乘法和除法的方法来计算,至少需要数百甚至数千个指令周期,而且结果的准确性较差。
2.2 非线性插值 在微控制器应用中会遇到非线性组件。
例如,热敏电阻的电阻温度特性和断路器的保护特性都是非线性关系。
这里以断路器的保护特性为例来说明自动编程的应用。
假设现在要模拟的断路器特性为双曲线,如图1所示。
据此,延时时间与电流的关系可设为 (I+I0)(t+ t0)=K (1) 由图1中的三点可得下列联立方程组: (I)(t)=K (I)(t)=K ( 2) (I)(t)=K 用迭代法求解I0=11.1,t0=0.2,K=1 .58,代入式(1),得 t= [1 .58/(I.1)]-0.2 (3) 现在假设在硬件电路中,电流信号为电压信号经过A/D转换后,对应点之间的关系为:0A →0V,A→3V,A/D为8位,A/D参考电压为5V。
转换计算首先将A/D值转换为对应的电压值,然后将电压值转换为对应的电流值I,然后根据式(3)计算对应的延迟时间T,最后将延迟时间T转换为延迟时间常数T0。
T0按式(4)计算: (t0)·Tcy·K=T (4) t0=t/(Tcy·K) (5) 其中,Tcy为指令周期。
在4MHz晶振情况下,Tcy=1μs; K为预分频器系数; t是要延迟的时间,单位为μs。
假设定时器采用TMR0,预分频系数为,晶振振荡频率为4MHz,则最大延时为65.ms。
程序如下(与程序A.C相同或相似的省略): /*程序B.C*/ …… fprintf(fp,"SUB2 MOVWF BUF"); fprintf(fp,"MOVLW HIGH($)"); fprintf(fp,"MOVWF PCLATH"); fprintf(fp,"MOVF BUF,W"); fprintf(fp, “ORG H,F”); /*表格从H开始,避免跨页*/ fprintf(fp,"ADDWF PLC,F"); for(i=0;i)k=; fprintf(fp ,) " RETLW.%d;AD=.%d,I=%5.1f(A),T=%5.1f(ms)",k,i,I,T); } 表格由… 组成的查找程序如下(共线表,大部分省略): ; B.asm SUB2 MOVWF BUF MOVLW 高($) MOVWF PCLATH MOVF BUF,W ORG H ADDWF PCL,F RETLW .0;AD= .0,I=0.0(A),T=92.8(ms) …… RETLW .;AD=.27,I=17.6(A),T=35.7(ms) RETLW . ;AD=.28,I=18.3(A),T=34.9(ms) RETLW .;AD=.29,I=19.0(A),T=34.2(ms) RETLW .;AD =.30,I=19.6(A),T=33.4(ms) … RETLW .;AD=.,I=.0(A),T=5.6(ms) 单片机进行电流采样A/D,将A/D结果赋值给W,CALL SUB2即可得到对应的延迟时间常数W。
3 结论 利用高级语言自动生成单片机的查表程序,可以完成许多单片机难以完成或需要大量计算的复杂运算,计算精度高。
微控制器使用该结果来执行插值并且运行速度更快。
对于典型的 4MHz 晶体振荡器,所需的操作时间为 10μs。
由于篇幅限制,本文仅举两个例子。

事实上,它可以应用于单片机测控系统的很多方面,如模糊控制中模糊规则的推理、非线性传感器特性的读取等方面。
版权声明:本文内容由互联网用户自发贡献,本站不拥有所有权,不承担相关法律责任。如果发现本站有涉嫌抄袭的内容,欢迎发送邮件 举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。
标签:
相关文章
06-18
06-21
06-18
06-18
06-08
06-18
06-21
最新文章
使用电子管有哪些注意事项?如何检查电子管之间是否短路?
博通支付1200万美元和解SEC财务欺诈指控
八名运营商高管确认加入虚拟运营商
内蒙古农牧区雷电灾害成因分析及防雷对策
北京联通将5G应用于世园会远程医疗急救
TD-SCDMA最后一轮冲刺测试启动,产业前景更加光明
专访阿里云总裁王健:云计算服务平台梦想成真
USB2.0控制器CY7C68013的接口设计与实现