Simulink仿真入门到精通(十) S函数 您所在的位置:网站首页 simulink仿真函数曲线 Simulink仿真入门到精通(十) S函数

Simulink仿真入门到精通(十) S函数

2022-06-07 17:14| 来源: 网络整理| 查看: 265

10.1 S函数概述

S函数也称为Simulink中的系统函数,是用来描述模块的Simulink宏函数,支持M、C等多种语言。当Simulink默认的模块不能满足用户的需求时,用户可以通过S函数自己打造一个模块,实现自定义的算法或期待的动作。

10.2 S函数的类型 S函数有多种类型,按照语言分类有M、C、C++、Fortran等编写的; 按照所支持功能多少分类,包括Level1和Level2; 按照执行方式分类,可分为直接解释运行的M S函数和编译为Mex文件后执行的C Mex S函数。

Level1 M S函数输入输出端口最多位1且数据维数固定,Level2 M S函数的输入输出端口个数可以为多个,数据维数也可以动态改变。

编写一个既能用于仿真又能用于代码生成的算法时,需要给S函数编写同名的TLC文件。

由于M语言需要调用MATLAB解释器,故C Mex S函数运行速度比M S函数更快。

10.3 S函数的要素

一个Simulink模块包括输入、输出以及内部的状态量。除了3要素之外,还有一个无处不在的时间量。

所谓状态量,根据系统性质分为连续系统中的微分量和离散系统中的差分量。

dx/dt=f(t,x,u)

y=g(t,x,u)

10.4 S函数的组成及执行顺序

执行顺序:

main { 初始化模型; 计算下一个采样时间点(大步长); while(未到达仿真终止时间) { 计算模块的输出; 更新离散状态量; if(此模型带有连续状态模块) { here:计算微分; 计算模块的输出; if(精度未达标) goto here; 过零检测; 计算写一个采样时间点(大步长); } } 执行仿真终止动作; }

仿真运行时,模型首先要对模块进行初始化,这个过程包括模块的实例化:输入/输出端口、信号唯独、端口数据类型及采样时间等的确定,模块参数的获取及个数检查,并决定模块的执行顺序等。

 实例化:Simulink标准库中提供的模块类似于C++等面向对象语言中的一个类,每当模块被拷贝或拖曳到模型中时,就相当于创建了这个类的一个对象,继承了这个类的属性并载入了默认的构造函数方法对其参数、端口等各个属性进行了初始化工作。 信号维度:一根信号线传递的数据不仅可以是标量,也可以是一个向量或矩阵,一个模块的输出端口将具有这个数据维度的信号传递给相连的信号线然后再传递给下一个模块的输入端口,这些都是需要在初始化阶段确定下来的。 端口数据类型:模块的输出/输出数据是浮点数还是固定点数,是8为、16位、32为或64位,有无符号,内建类型或者用户自定义类型,这些也在初始化阶段指定。 采样时间:对于Simulink模型来说,解算器中的一个步长决定了整个模型最小的采样时间间隔。 模型中模块的执行顺序:当众多模块同时存在于一个模型中时,Simulink是有明确的顺序优先度的。

S函数子方法表:

子方法 作用说明 初始化 在第一个采样时间的仿真之前运行的函数,用来初始化模块,包括设定输入/输出端口的个数和维数,输入是否直接馈入,参数个数设定采样时间,当使用工作向量时还需要为其分配存储空间 下一个采样时间点计算 根据模型解算器的算法求得下一个采样时间点,通常用于变步长模块 输出函数计算 在每一个major step计算模型所有的输出口的输出值 离散状态更新 在每一个major step都进行一次离散状态的更新计算,在输出函数之后 积分计算 如果模型具有连续状态,才采取此方法。将major step分隔为数个minor step,在每一个minor step里进行一次输出函数与积分计算。积分计算主要用来更新连续状态。当模型中存在非采样过零检测时,还会在minor step中进行过零检测 模型终止 当模型终止仿真时调用的子函数,用于清除不用的变量,释放内存空间等动作 10.5 使用不同语言编写S函数

不同S函数的特点:

S函数 特点 Level1 M 支持简单的MATLAB接口及少数的API Level2 M 支持扩展的S函数API及代码生成功能,使用场合更加广泛 C MEX 提供更灵活的编程方式,即可手写C代码也可以调用既存的C/C++或Fortran代码。要求掌握很多C MEX S函数API用法及TLC代码编写方法,才能够制定具有代码生成功能的C MEX S函数 10.5.1 Level1 M S函数

[sys,x0,str,ts]=f(t,x,u,flag,p1,p2,...)

其中f是S函数的函数名,Simulink会在仿真过程中的每个步长内多次调用f。

flag的值随着仿真过程自动变化,其值对应的S函数子方法如下:

flag值 Level1 M S函数子方法名 说明 0 mdlInitializeSizes 定义S函数的基本属性,如输入/输出维数、连续/离散状态变量个数、采样时间、以及输入是否为直接馈入等 1 mdlDerivatives 连续状态变量的微分函数,这里通常通过给定的微分计算表达式,通过积分计算得到状态变量的值 2 mdlUpdate 更新离散状态变量 3 mdlOutputs 计算S函数的输出 4 mdlGetTimeOfNextVarHit 仅在变离散采样时间情况下使用,用于计算下一个采样时时刻的绝对时间,若模块不是变步长此函数不会执行 9 mdlTerminate 在仿真结束时执行一些必要的动作,如清除临时变量,或显示提示信息等

说明——直接馈入:

如果S函数的输出y或采样时间t与输入u有直接联系,就是直接馈入;否则不存在直接馈入情况。如果若干直接馈入的模块通过反馈构成了一个环形,就会出现所谓的代数环。

Level1 M S输入参数表:

输入参数 功能 t 当前时刻的仿真时间 x 状态变量向量 u 输入向量 pn,n=1,2,3,... 用户自定义参数,数目不定

Level1 M S输出参数表:

输出参数 功能 sys 通用输出参数,根据flag的值来决定返回值,比如flag=3时返回S函数的输出信号;flag=2时则返回更新后的离散状态变量的值;flag=1时根据设置的微分值积分计算出连续状态变量的值 x0 状态变量的初始值,仅在flag=0时有效,其余情况被忽略 str 保留变量,用户只能将其初始化为[ ] ts S函数的采样时间,由一个二维的数组表示

ts=[m,n]中m为模块的采样时间周期,表示每隔多长时间采样一次,n为采样时间的偏移量,表示与采样时间周期所表示的时刻点的偏差时间。

例如:

采样时间表示 含义 [0,0] 连续采样时间 [-1,0] 继承S函数输入信号或父层模型的采样时间 [0.5,0.1] 离散采样时间,从0.1s开始每0.5s采样一次 [0.25,0;1,0.1] [0,0.1,0.25,0.5,0.75,1,1.1,...]

示例:

dx1/dt=-0.5572x1-0.7814x2+u1-u2;

dx2/dt=0.7814x1+2u2;

y=1.9691x1+6.4493x2;

由方程可知:

A=[-0.5572,-0.7814;0.7814,0]; B=[1,-1;0,2]; C=[1.9691,6.4493]; function [sys,x0,str,ts,simStateCompliance] = sfun_state01(t,x,u,flag,A,B,C) switch flag, case 0, [sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes; case 1, sys=mdlDerivatives(t,x,u); case 2, sys=mdlUpdate(t,x,u,A,B); case 3, sys=mdlOutputs(t,x,u,C); case 4, sys=mdlGetTimeOfNextVarHit(t,x,u); case 9, sys=mdlTerminate(t,x,u); otherwise DAStudio.error('Simulink:blocks:unhandledFlag', num2str(flag)); end function [sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes sizes = simsizes; sizes.NumContStates = 0; sizes.NumDiscStates = 2; sizes.NumOutputs = 1; sizes.NumInputs = 2; sizes.DirFeedthrough = 0; sizes.NumSampleTimes = 1; sys = simsizes(sizes); x0 = [0 0]'; str = []; ts = [0,0]; simStateCompliance = 'UnknownSimState'; function sys=mdlDerivatives(t,x,u) sys = []; function sys=mdlUpdate(t,x,u,A,B) % update state variable sys = A * x + B * u; function sys=mdlOutputs(t,x,u,C) % update output sys = C * x; function sys=mdlGetTimeOfNextVarHit(t,x,u) sampleTime = 1; sys = t + sampleTime; function sys=mdlTerminate(t,x,u) sys = [];

示例:积分

function [sys,x0,str,ts,simStateCompliance] = int_hyo(t,x,u,flag) switch flag, case 0, [sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes; case 1, sys=mdlDerivatives(t,x,u); case 2, sys=mdlUpdate(t,x,u); case 3, sys=mdlOutputs(t,x,u); case 4, sys=mdlGetTimeOfNextVarHit(t,x,u); case 9, sys=mdlTerminate(t,x,u); otherwise DAStudio.error('Simulink:blocks:unhandledFlag', num2str(flag)); end function [sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes sizes = simsizes; sizes.NumContStates = 1; sizes.NumDiscStates = 0; sizes.NumOutputs = 1; sizes.NumInputs = 1; sizes.DirFeedthrough = 0; sizes.NumSampleTimes = 1; % at least one sample time is needed sys = simsizes(sizes); x0 = [0]; str = []; ts = [0 0]; simStateCompliance = 'UnknownSimState'; function sys=mdlDerivatives(t,x,u) sys = u; function sys=mdlUpdate(t,x,u) sys=[]; function sys=mdlOutputs(t,x,u) sys=x; function sys=mdlGetTimeOfNextVarHit(t,x,u) sampleTime = 1; % Example, set the next hit to be one second later. sys = t + sampleTime; function sys=mdlTerminate(t,x,u) sys = [];

10.5.2 Level2 M S函数

Level2 M S函数使得用户能够使用MATLAB语言来编写支持多个输入/输出端口的自定义模块,并且每个端口都能够支持包括矩阵在内的Simulink支持的所有数据类型。

1. Setup子方法

Setup子方法是Level2 M S函数体中唯一调用的语句,对模块的属性和其他子方法进行初始化,Setup子方法类似Level1 M S函数中mdlInitializeSizes子方法的功能,并且相比之下功能更加强大,在Setup中不仅可以设置多输入多输出,而且每个输出的端口信号的维数可以是标量数或矩阵甚至是可变维数,另外S函数的其他子方法也是通过Setup子方法进行注册的,因此Setup可以成为Level2 M S函数的根本。

Setup子方法实现以下功能:

设定模块输入输出端口的个数; 设定每一个端口的数据类型、数据维度、实数复数性和采样时间等; 规定模块的采样时间; 设定S函数参数的个数; 注册S函数的子方法(将子方法函数的句柄传递到实时对象的RegBlockMethod函数的对应属性中)。

S函数实时对象的属性列表:

实时对象属性成员 说明 NumDialogPrms 模块GUI参数个数 NumInputPorts 输入端口数 NumOutputPorts 输出端口数 BlockHandle 模块句柄,只读 CurrentTime 当前仿真时间,只读 NumContStates 连续状态变量数目 NumDworkDiscStates 离散状态变量数目 NumRuntimePrms 运行时参数个数 SampleTimes 产生输出的模块的采样时间 NumDworks 离散工作向量个数

函数端口的属性列表:

属性端口名 说明 Dimensions 端口数据维度 DatatypeID/Datatype 端口数据类型,可以通过ID号指定也可以直接指定数据类型名 Complexity 端口数据是否为复数 DirectFeedthrough 端口数据是否直接馈入 DimensionsMode 端口维数是固定或可变的(fixed/variable)

实时对象的方法列表:

实时对象方法 说明 ContStates 获取模块的连续状态 DataTypeIsFixedPoint 判断数据类型是否为固定点数 DatatypeName 获取数据类型的名称 DatatypeSize 获取数据类型大小 Derivatives 获取连续状态的微分 DialogPrm 获取GUI中的参数 Dwork 获取Dwork向量 FixedPointNumericType 获取固定点数据类型的操作 InputPort 获取输入端口 OutputPort 获取输出端口 RuntimePrm 获取运行时参数

其他子方法列表:

子方法名 说明 PostPropagationSetup 设置工作向量及状态变量的函数(可选) InitializeConditions 在仿真开始时被调用的初始化函数(可选) Start 在模型运行仿真时调用一次,用来初始化状态变量和工作向量(可选) Outputs 在每个步长里计算模型输出 Updata 在每个步长里更新离散状态变量的值(可选) Derivatives 在每个步长里更新连续状态变量的微分值(可选) Terminate 在仿真结束时调用,用来清除变量内存 2. PostPropagationSetup

PostPropagationSetup子方法是用来初始化Dwork工作向量的方法,规定Dwork向量的个数及每个向量的维数、数据类型、离散状态变量的名字和虚拟性,以及是否作为离散变量使用。

Dwork向量是Simulink分配给模型中每个S函数实例的存储空间块。当不同S函数块之间需要通过全局变量或者静态变量进行数据交互时,必须在S函数中使用Dwork向量来进行变量存储。

Dwork属性列表:

名称 含义 Name 名字 Dimensions 数据维数 DatetypeID 数据类型 Complexity 是否复数 UsedAsDiscState 是否作为离散变量使用

代表不同数据类型的ID(整数):

数据类型 ID ingerited -1 double 0 single 1 int8 2 uint8 3 int16 4 uint16 5 int32 6 uint32 7 boolean或定点类型 8 3. InitializeConditions/Start子方法

InitializeConditions子方法可以用来初始化状态变量或者Dwork工作向量的值。

Start子方法跟InitializeConditions子方法功能一致,但仅仅在仿真开始的时候初始化一次,而S函数模块放置在是能子系统中时其InitializeConditions子方法在每次子系统被使能时都会被调用。

4. Output子方法

Output子方法跟Level1 M S函数的mdlOutputs子方法作用一样,用于计算S函数的输出。

5. Updata子方法

Updata子方法跟Level1 M S函数中mdlUpdata子方法作用相同,用于计算离散状态变量的值。

6. Derivatives子方法

Derivatives子方法跟Level1 M S函数中的mdlDerivatives子方法作用相同,用于计算并更新连续状态变量的值。

7. Terminate子方法

S函数的收尾工作放在Terminate子方法中进行,如存储空间的释放,变量的删除等。

阿布罗狄:

艾欧里亚:

m1=imread('阿布罗狄.jpg'); m1=m1(:,:,1); m2=imread('艾欧里亚.jpg'); m2=m2(:,:,1);

function sfun_image_merge(block) setup(block); function setup(block) block.BlockHandle % Register number of ports block.NumInputPorts = 2; block.NumOutputPorts = 0; % Setup port properties to be inherited or dynamic block.SetPreCompInpPortInfoToDynamic; % Override input port properties block.InputPort(1).Dimensions = [375 500]; block.InputPort(1).DatatypeID = 3; % uint8 block.InputPort(1).Complexity = 'Real'; block.InputPort(1).DirectFeedthrough = false; block.InputPort(2).Dimensions = [375 500]; block.InputPort(2).DatatypeID = 3; % uint8 block.InputPort(2).Complexity = 'Real'; block.InputPort(2).DirectFeedthrough = false; % Register parameters block.NumDialogPrms = 0; % Register sample times % [0 offset] : Continuous sample time % [positive_num offset] : Discrete sample time % % [-1, 0] : Inherited sample time % [-2, 0] : Variable sample time block.SampleTimes = [0 0]; % Specify the block simStateCompliance. The allowed values are: % 'UnknownSimState', < The default setting; warn and assume DefaultSimState % 'DefaultSimState', < Same sim state as a built-in block % 'HasNoSimState', < No sim state % 'CustomSimState', < Has GetSimState and SetSimState methods % 'DisallowSimState' < Error out when saving or restoring the model sim state block.SimStateCompliance = 'DefaultSimState'; block.RegBlockMethod('Terminate', @Terminate); % Required function Terminate(block) imshow((block.InputPort(1).data + block.InputPort(2).data) / 2);

好丑!看不出什么效果。

再试一次:

融合后:

原来核心语句在这里:

imshow((block.InputPort(1).data + block.InputPort(2).data) / 2); 10.5.3 C MEX S函数

S函数支持的语言除了MATLAB/Simulink自身环境的M语言之外,最常用的就是C语言了。使用C语言编写S函数成为C Mex Sh函数,相比于解释运行的M S函数,在仿真过程中不需要反复调用MATALB解释器,而是在运行前将.c文件编译成mexw32/mexw64类型的可执行文件,运行速度和效率上有明显优势;并且C语言拥有编程语言生的灵活性优势。

C Mex S函数的运行机制与M S函数是一致的,包括常用的初始化、更新、微分计算、输出和终止等子方法,这些子方法几乎可以与Level2 M S函数的子方法一一对应起来。但是由于语言的不同,所使用的数据结构形式上也有区别。

对应关系:

C Mex S函数子方法 Level2 M S函数子方法 子方法功能 mdlInitializeSizes Setup 模块属性初始化 mdlDerivatices Derivatives 更新连续状态变量的微分值 mdlInitializeConditions InitializeConditions 初始化工作向量的状态值 mdlOutputs Outputs 计算模块的输出 mdlSetWorkWidths PostPropagationSetup 当S函数模块存在于使能子系统中时,每次子系统被使能均进行工作向量属性的初始化工作 mdlStart Start 在仿真开始时初始化工作向量及状态变量的属性 mdlTerminate Terminate 在仿真终止时所调用的子方法 mdlUpdate Updata 更新离散状态变量的子方法 mdlRTW WriteRTW 将S函数中获取到的GUI参数变量值写入到rtw文件中以使TLC文件用来生成代码的子方法 1. C Mex S函数的构成 最开头必须定义的两个宏:C Mex S函数名及C Mex S函数的等级。 头文件包含部分C Mex S函数核心数据结构simstruct类型的声明及其他库文件,另外用户根据使用需要也可以包含其他头文件。 参数对话框访问宏函数的定义。 紧接着定义C Mex S函数的各个子方法。 S函数必须根据使用情况包含必要的源文件和头文件,从而将该S函数文件与Simulink或Simulink Coder产品进行连接。 2. C Mex S函数的编译

编译型语言编写的程序执行之前,需要一个专门的编译过程,把程序编译成为机器语言的文件,如exe文件或mexw32/menw64文件,运行时不需要重新翻译。

>> mex -setup MEX 配置为使用 'Microsoft Visual C++ 2010 (C)' 以进行 C 语言编译。 Warning: The MATLAB C and Fortran API has changed to support MATLAB variables with more than 2^32-1 elements. In the near future you will be required to update your code to utilize the new API. You can find more information about this at: http://www.mathworks.com/help/matlab/matlab_external/upgrading-mex-files-to-use-64-bit-api.html. 要选择不同的语言,请从以下选项中选择一种命令: mex -setup C++ mex -setup FORTRAN >> mex -setup C++ MEX 配置为使用 'Microsoft Visual C++ 2010' 以进行 C++ 语言编译。 >> mex sfun_c_filter.c 使用 'Microsoft Visual C++ 2010 (C)' 编译。 MEX 已成功完成。 3. C Mex S函数的应用

//sfun_c_filter.c#define S_FUNCTION_NAME sfun_c_filter #define S_FUNCTION_LEVEL 2 #include "simstruc.h" #define COEF_IDX 0 #define COEF(S) mxGetScalar(ssGetSFcnParam(S,COEF_IDX)) /*================* * Build checking * *================*/ /* Function: mdlInitializeSizes =============================================== * Abstract: * Setup sizes of the various vectors. */ static void mdlInitializeSizes(SimStruct *S) { ssSetNumSFcnParams(S, 1); if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) { return; /* Parameter mismatch will be reported by Simulink */ } if (!ssSetNumInputPorts(S, 1)) return; ssSetInputPortWidth(S, 0, DYNAMICALLY_SIZED); ssSetInputPortDirectFeedThrough(S, 0, 1); if (!ssSetNumOutputPorts(S,1)) return; ssSetOutputPortWidth(S, 0, DYNAMICALLY_SIZED); ssSetNumDWork(S, 1); ssSetDWorkWidth(S, 0, DYNAMICALLY_SIZED); ssSetNumSampleTimes(S, 1); /* specify the sim state compliance to be same as a built-in block */ ssSetSimStateCompliance(S, USE_DEFAULT_SIM_STATE); ssSetOptions(S, SS_OPTION_WORKS_WITH_CODE_REUSE | SS_OPTION_EXCEPTION_FREE_CODE | SS_OPTION_USE_TLC_WITH_ACCELERATOR); } /* Function: mdlInitializeSampleTimes ========================================= * Abstract: * Specifiy that we inherit our sample time from the driving block. */ static void mdlInitializeSampleTimes(SimStruct *S) { ssSetSampleTime(S, 0, INHERITED_SAMPLE_TIME); ssSetOffsetTime(S, 0, 0.0); ssSetModelReferenceSampleTimeDefaultInheritance(S); } #define MDL_INITIALIZE_CONDITIONS /* Function: mdlInitializeConditions ======================================== * Abstract: * Initialize both discrete states to one. */ static void mdlInitializeConditions(SimStruct *S) { real_T *x = (real_T*) ssGetDWork(S,0); x[0] = 0.0; // initial to 0.0 } /* Function: mdlOutputs ======================================================= * Abstract: * y = 2*u */ static void mdlOutputs(SimStruct *S, int_T tid) { int_T i; InputRealPtrsType uPtrs = ssGetInputPortRealSignalPtrs(S,0); real_T *y = ssGetOutputPortRealSignal(S,0); int_T width = ssGetOutputPortWidth(S,0); real_T *x = (real_T*) ssGetDWork(S,0); real_T Lc = COEF(S); for (i = 0; i < width; i++) { y[i] = (*uPtrs[i] - x[i]) * Lc + x[i]; } /* save the current output as the DWork Vector */ for (i=0; i> lct_spec=legacy_code('initialize') lct_spec = 包含以下字段的 struct: SFunctionName: '' InitializeConditionsFcnSpec: '' OutputFcnSpec: '' StartFcnSpec: '' TerminateFcnSpec: '' HeaderFiles: {} SourceFiles: {} HostLibFiles: {} TargetLibFiles: {} IncPaths: {} SrcPaths: {} LibPaths: {} SampleTime: 'inherited' Options: [1×1 struct]

LCT对象的各个属性:

属性名 作用说明  SFunctionName 所生成S函数的名字  InitializeConditionsFcnSpec 应用于InitializeConditions子方法中的既存C代码函数原型  OutputFcnSpec 应用于OutputFcn子方法中的既存C代码函数原型  StartFcnSpec 应用于StartFcn子方法中的既存C代码函数原型  TerminateFcnSpec 应用于TerminateFcn子方法中的既存C代码函数原型  HeaderFiles 声明既存C函数及其他需要编译的头文件  SourceFiles 定义既存C函数及其他需要编译的源文件  HostLLibFiles/TargetLibFiles 主机/目标端编译C文件所依赖的库文件   IncPaths LCT搜索路径寻找编译需要的头文件   SrcPaths LCT搜索路径寻找编译需要的源文件   LibPaths Lct搜索路径寻找编译需要的库和目标文件   SampleTime 采样时间   Options 控制S函数Options的选项  legacy_code('help'):打开LCT工具的详细使用说明的帮助文档; legacy_code('sfcn_cmex_generate',lct_spec):根据lct_spec生成S函数源文件; legacy_code('compile',lct_spec):对生成的S函数进行编译链接; legacy_code('slblock_generate',lct_spec,modename):生成一个封装模块调用生成的S函数,并自动将此模块添加到名为modename的模型文件里; legacy_code('sfcn_tlc_generate',lct_spec):生成S函数配套的TLC文件,用于加速仿真模型或通过Simulink模型生成代码; legacy_code('rtwmakecfg_generate',lct_spec):生成rtwmakecfg.m文件,此文件是用于生成适用于当前lct_spec对象的makefile的M脚本。 例:使用Legacy Code Tool集成正弦C代码 //EmMath.c #include"EmMath.h" const unsigned short SinTbl[] = {0x0000, //0 0x0019, 0x0032, 0x004B, 0x0064, 0x007D, 0x0096, 0x00AF, 0x00C8, 0x00E2, 0x00FB,//10 0x0114, 0x012D, 0x0146, 0x015F, 0x0178, 0x0191, 0x01AA, 0x01C3, 0x01DC, 0x01F5,//20 0x020E, 0x0227, 0x0240, 0x0258, 0x0271, 0x028A, 0x02A3, 0x02BC, 0x02D4, 0x02ED,//30 0x0306, 0x031F, 0x0337, 0x0350, 0x0368, 0x0381, 0x0399, 0x03B2, 0x03CA, 0x03E3,//40 0x03FB, 0x0413, 0x042C, 0x0444, 0x045C, 0x0474, 0x048C, 0x04A4, 0x04BC, 0x04D4,//50 0x04EC, 0x0504, 0x051C, 0x0534, 0x054C, 0x0563, 0x057B, 0x0593, 0x05AA, 0x05C2,//60 0x05D9, 0x05F0, 0x0608, 0x061F, 0x0636, 0x064D, 0x0664, 0x067B, 0x0692, 0x06A9,//70 0x06C0, 0x06D7, 0x06ED, 0x0704, 0x071B, 0x0731, 0x0747, 0x075E, 0x0774, 0x078A,//80 0x07A0, 0x07B6, 0x07CC, 0x07E2, 0x07F8, 0x080E, 0x0824, 0x0839, 0x084F, 0x0864,//90 0x087A, 0x088F, 0x08A4, 0x08B9, 0x08CE, 0x08E3, 0x08F8, 0x090D, 0x0921, 0x0936,//100 0x094A, 0x095F, 0x0973, 0x0987, 0x099C, 0x09B0, 0x09C4, 0x09D7, 0x09EB, 0x09FF,//110 0x0A12, 0x0A26, 0x0A39, 0x0A4D, 0x0A60, 0x0A73, 0x0A86, 0x0A99, 0x0AAB, 0x0ABE,//120 0x0AD1, 0x0AE3, 0x0AF6, 0x0B08, 0x0B1A, 0x0B2C, 0x0B3E, 0x0B50, 0x0B61, 0x0B73,//130 0x0B85, 0x0B96, 0x0BA7, 0x0BB8, 0x0BC9, 0x0BDA, 0x0BEB, 0x0BFC, 0x0C0C, 0x0C1D,//140 0x0C2D, 0x0C3E, 0x0C4E, 0x0C5E, 0x0C6E, 0x0C7D, 0x0C8D, 0x0C9C, 0x0CAC, 0x0CBB,//150 0x0CCA, 0x0CD9, 0x0CE8, 0x0CF7, 0x0D06, 0x0D14, 0x0D23, 0x0D31, 0x0D3F, 0x0D4D,//160 0x0D5B, 0x0D69, 0x0D76, 0x0D84, 0x0D91, 0x0D9F, 0x0DAC, 0x0DB9, 0x0DC6, 0x0DD2,//170 0x0DDF, 0x0DEB, 0x0DF8, 0x0E04, 0x0E10, 0x0E1C, 0x0E28, 0x0E33, 0x0E3F, 0x0E4A,//180 0x0E55, 0x0E60, 0x0E6B, 0x0E76, 0x0E81, 0x0E8B, 0x0E96, 0x0EA0, 0x0EAA, 0x0EB4,//190 0x0EBE, 0x0EC8, 0x0ED1, 0x0EDB, 0x0EE4, 0x0EED, 0x0EF6, 0x0EFF, 0x0F07, 0x0F10,//200 0x0F18, 0x0F21, 0x0F29, 0x0F31, 0x0F39, 0x0F40, 0x0F48, 0x0F4F, 0x0F56, 0x0F5D,//210 0x0F64, 0x0F6B, 0x0F72, 0x0F78, 0x0F7F, 0x0F85, 0x0F8B, 0x0F91, 0x0F96, 0x0F9C,//220 0x0FA1, 0x0FA7, 0x0FAC, 0x0FB1, 0x0FB6, 0x0FBA, 0x0FBF, 0x0FC3, 0x0FC7, 0x0FCB,//230 0x0FCF, 0x0FD3, 0x0FD7, 0x0FDA, 0x0FDE, 0x0FE1, 0x0FE4, 0x0FE7, 0x0FE9, 0x0FEC,//240 0x0FEE, 0x0FF0, 0x0FF2, 0x0FF4, 0x0FF6, 0x0FF8, 0x0FF9, 0x0FFB, 0x0FFC, 0x0FFD,//250 0x0FFE, 0x0FFE, 0x0FFF, 0x0FFF, 0x0FFF, 0x0FFF}; //256 /**************************************************** Function name: Em_Sin description: calculate sin(theta) input: Angle(0x3FFFFF equal one Cycle output: ****************************************************/ signed long Em_Sin(unsigned long Angle) { unsigned long AngleTemp; signed long SineValue; AngleTemp = Angle >> 12; AngleTemp &= 0x03FF; //0~1024 if (AngleTemp


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有