精华内容
下载资源
问答
  • 2021-11-11 00:51:36

    什么是过零检测功能
    所谓过零检测就是指在交流回路中,当波形由正半周向负半周转换或者由负半周向正半周转换时,经过零位,系统要检测到这个零位。可控硅过零检测是指,系统检测到零位时,要让可控硅在零位或者零位附近时触点导通或者断开。可以设计过零检测电路来实现功能,也可以使用带有过零检测功能的光耦来实现。
    可控硅做过零检测的意义
    前文说过,可控硅的过零检测就是让可控硅在零位附近导通或者关断,即在零位附近的时候要让用户负载快速接入回路或者从回路中断开。我们知道,在电流很大的时候,导通回路或者切断回路会对负载和电源造成很大的冲击,电流越大冲击越大,会给电网带来很多谐波干扰。如果在电流为零的时候把负载接入或者断开,就能把冲击降到最小,从而避免了因负载频繁开断而带来影响。所以,在大功率负载控制回路中,过零检测很有意义。

    更多相关内容
  • 在这里和大家分享一个用C语言检测过零方法
  • 通过与传统的零点检测方法作对比,设计出一种基于预测相位的二次平均测量信号周期(简称预测相位积分)的方法,通过其核心部件密勒积分器、比较器和计数器,对于每个周期信号尽可能准确地在相同相位点上开始...
  • 本文提出一种基于反激式(Flyback)原边反馈控制结构的电感电流过零检测实现方法,主要应用于临界导通模式(Boundary Conduction Mode, BCM)下的LED恒流控制方案中。分析了传统反激式原边反馈控制结构方案在实现...
  • 过零检测电路可以用很多方法来设计,比如使用晶体管,使用运算放大器或是光耦 IC 等。该文中我们将使用运算放大器来打造一个过零检测电路,正如上面所说,此处的运算放大器用作比较器。 过零检测电路的理想波形如下...
  • 过零检测代码

    2013-05-15 21:03:56
    自定义过零检测 生产函数 测量信号之间的相位差
  • 改进的过零检测法的matlab程序

    热门讨论 2009-07-29 14:26:55
    改进的过零检测法的matlab程序,可以克服传统过零检测法的缺点,提高精度。
  • 行业资料-电子功用-单相交流电过零检测方法的说明分析.rar
  • 电子政务-永磁直流无刷无霍尔电机反电动势的过零检测方法及装置.zip
  • 这个程序将检测信号的第一个交叉,对于任何采样时间。有时我们的采样时间很长,我们无法在我们的数据中有精确的,所以对于那种信号数据,通过使用这个程序,我们可以找到第一个(符号变化)
  • FSK过零检测技术软件实现

    千次阅读 2021-06-05 10:12:46
    最近调试了一个FSK解调的项目,期间换了两种算法,其中基于过零检测技术的FSK软件解调方法最后是最好用的一种,特意分享出来给大家! 先附上对应github源码连接:fsk过零检测github源码地址(经过工程验证) 原理 ...

    前言

    最近调试了一个FSK解调的项目,期间换了两种算法,其中基于过零检测技术的FSK软件解调方法最后是最好用的一种,特意分享出来给大家!
    先附上对应github源码连接:fsk过零检测github源码地址(经过工程验证)

    原理

    FSK信号制式描述

    根据《中国来电显示标准》,在两次振铃之间产生数据传送。FSK制式信号是连续相位移频键控,由两种不同的频率表示逻辑0和逻辑1。
    FSK数据要求:
    逻辑1: 1200Hz±1%
    逻辑0: 2200Hz±1%
    传输速率: 1200bit/s±1%
    在基于特定平台的路由交换系统中,其交换机的发送速率为8KHz,接收速率也为8KHz。
    在这里插入图片描述

    如图所示,为单数据消息帧格式,在现在的交换机系统中,其由固定的300个0/1交替组成的信道占用信号,180个连续1组成的标志信号,10个bit组成的消息字组成,消息字中间存在7个连续的1组成的标志位。

    算法描述

    过零检测法是一种常用且简便的解调方法,2FSK信号的过零点数随载频的变化而不同,因此检测出过零点个数就可以得到载频的差异,从而进一步得到调制信号的信息,过零检测法的原理如下:
    在这里插入图片描述

    如图所示,为过零检测法解调原理。其目的是将FSK调制的采样信号转换为ASK调制的信号。FSK信号经过限幅、微分、整流后形成与频率变化相对应的脉冲序列,由此再形成 相同宽度的矩形脉冲,矩形脉冲的低频分量与数字信号相对应,由滤波器滤出低频分量, 然后经抽样判决,即可得到原始的数字调制信号。
    过零检测法本质是一种模拟解调的方法,这里用数字信号处理的方式对其进行了软件实现。

    仿真分析

    这里采用了一段真实接收的信号作为仿真验证。
    在这里插入图片描述

    如图所示,一段1.2KHz的FSK调制信号由8KHz的AD进行采样,大约9000个采样点。前1000个点是响铃,后边一长段是一段信号的有用数据。
    在进行数字信号处理前,对其进行3倍插值。一段8KHz采样的1.2KHz频率的信号,每20个采样点有3个完整bit,单个bit有6~7个采样点。为了使其方便后续处理,对采样点进行3倍插值,插值后的数据每20个采样点代表1个完整的bit。
    采样数据3倍插值后,对其放大限幅,这里实际进来的是满量程的short型数据,所谓的放大限幅是将其转换为了能够代表变化快慢的方波,所以这里对其修改为,大于0的为幅值100,小于0的为幅值-100。

    图4 放大限幅后的数据

    微分部分,在数字信号处理中用差分表示,用后一个采样bit减去前一个采样bit即可。
    在这里插入图片描述

    随后对其进行整流,这里直接对其取绝对值。
    在这里插入图片描述

    然后对其进行相同脉宽的脉宽调制,这里每有一个幅值为200的点,将其宽度扩展为3个点处理。

    在这里插入图片描述

    对输入的原始采样数据进行一系列处理后,将其调制为了如图所示的脉冲数随频率变化的脉宽信号。将频率不同的脉宽信号过低通滤波器,滤除其高频分量。
    在这里插入图片描述
    在这里插入图片描述

    能得到这张图就已经解调成功了。
    从图中可以看到,不同频率的信号明显被调制为了不同幅度的信号,变化快的2.2KHz信号幅值高,变化慢的1.2KHz信号幅值低。图9为一段数据的全部输出,前边交替变化的是300个0、1,中间一段低幅值信号是180个1,后边的则是0开始1结尾的消息字和穿插在其中的标志位。
    将FSK经过如上方法转换为了ASK信号,将其找到一个合适的门限值,即可将0和1准确判断出来。

    如图所示,将86作为此次数据的门限值,超过门限的做0处理,低于门限的做1处理。从图中可以看出,0和1bit基本是每20个采样点一个的。实际C代码编写中,将300个信道占用信号0、1对门限进行训练。
    训练方法为,初始化门限值为80,300个信道占用信号有总计6000个采样点,利用其中5000个采样点,每200个为一组,分为25组。因为200个点是10个bit的0、1值,并且0和1的数量是相等的,将其200个点进行累加,理论值是100,利用这些数据对门限进行调节,最终使门限值收敛与接近最优的门限值。

    在这里插入图片描述

    如图所示,门限值逐步收敛于一个定值。

    在这里插入图片描述

    如图所示,按照门限值,大于门限值为1,小于门限值为0。每20个bit进行一次判决,大于10的为0,小于10的为1。即可解调出正确bit。

    展开全文
  • 单片机过零检测电路图 ...采用移相方法就需过零检测作为移相基点。过零检测其实并不难,如果要求调压比不是很高采用简单的方法即可奏效;用一只三极管即可。用单片机进行移相调压控制可以做得很精。
  • 过零检测

    千次阅读 2019-12-11 17:24:41
    过零检测主要有三个作用: (1) 可控硅触发。通过检测AC220V零点,可以调节可控硅的导通时间,从而进行电压控制等。 (2) 继电器保护。当使用继电器控制AC220v通断时,如果继电器在AC220v的峰值附近闭合,则会产生很...

    AC-220V零点检测
    一般系统结构都是如下图所示。
    http://bbs.21ic.com/data/attachment/forum/201705/08/130422eerrnrn9shz28gzd.png.thumb.jpg
    过零检测主要有三个作用:
    (1) 可控硅触发。通过检测AC220V过零点,可以调节可控硅的导通时间,从而进行电压控制等。
    (2) 继电器保护。当使用继电器控制AC220v通断时,如果继电器在AC220v的峰值附近闭合,则会产生很大的火花,影响继电器的寿命并产生各种电磁干扰,如果在AC220v的过零点处闭合,就会减少影响。
    (3) 计时。AC220v频率为50Hz,周期为20ms。经过全波整流后,在每个零点产生中断,可以以10ms为单位进行计时。

     

    设计原理:
    过零检测原理图如图 所示,AC220v经过变压器降为AC 9v,然后全波整流,整流后的信号便可以直接用于过零检测。滤波电容c1接后续电路如7805可以作为它用。二极管D1用来隔离整流和滤波部分,保持Zero处的波形,给过零点检测提供信号源。
    在Zero处得到取样信号,然后用两个10K电阻分压,分压后接三极管。三极管工作在开关方式,当基极电压Vbe≥0.7V时,三极管导通,输出低电平给PB4;反之三极管工作于截止状态,输出高电平给PB4。Zero处的取样信号和PB4的输入信号对应关系如图 2-2所示。利用PB4的上升沿产生10ms外部中断,每次中断产生时便是AC220v的零点。
    本范例使用6个LED作为显示,当每次过零中断产生时刷新LED显示,LED刷新频率如下:
    LED0 50HZ 闪烁10ms点亮,10ms熄灭,点亮和熄灭与电源零点同步
    LED1 25HZ闪烁20ms点亮,20ms熄灭,点亮和熄灭与电源零点同步
    LED2 12.5HZ闪烁40ms点亮,40ms熄灭,点亮和熄灭与电源零点同步
    LED3 6.25HZ闪烁80ms点亮,80ms熄灭,点亮和熄灭与电源零点同步
    LED4 3.125HZ闪烁160ms点亮,160ms熄灭,点亮和熄灭与电源零点同步
    LED5 1.5625HZ闪烁320ms点亮,320ms熄灭,点亮和熄灭与电源零点同步

    http://bbs.21ic.com/data/attachment/forum/201705/08/130700ryveqgz7moe64mue.png.thumb.jpg
    过零检测原理图

    http://bbs.21ic.com/data/attachment/forum/201705/08/130752ggxm9u9mn2rkfrr7.png.thumb.jpg

    过零中断产生与实际AC220v零点之间的时间误差
    http://bbs.21ic.com/data/attachment/forum/201705/08/130851vl8yavwxsl8sak86.png.thumb.jpg

    如上图所示,当电压降到0.7V时,PB4口得到上升沿,中断产生。中断地产生与真正的零点有一段时间差,这段时间差与变压器的输出电压和三极管前端的电阻分压有关。在本电路中,中断产生和零点之间的时间差的理论计算式为:
    0.7=4.5√2 *sin(w * t)
    其中 4.5√2是由电压峰值9√2经过两个10k电阻分压所得
    w=2*3.14* f (f为50Hz)
    经过计算,t=350us。
    经示波器实际测量,中断产生和零点之间的时间差约为500us。

     

     

     

     

     

     

    交流电的过零点检测方案较多,目前较常见的也是我之前所使用的方案如图1所示:

    http://bbs.21ic.com/data/attachment/forum/201705/08/154025wylydir421pzipdl.jpg.thumb.jpg

    图1 交流电光耦过零检测电路

    图1的电路可以检测到交流电经过零点的时间,但是它存在诸多的弊端,现列举如下:

    1. 电阻消耗功率太大,发热较多。220V交流电,按照有效值进行计算三个47K的电阻平均每个电阻的功率为220^2/(3*47k)/3=114.42mw。对于0805的贴片电阻按照1/8w的功率计算,当前的消耗功率接近其额定功率,电阻 发热大较大。同时需要注意市电的有效值为220V,其峰值电压为311V,以此计算我们可以得到每个电阻的瞬时最大功率为228mw,严重超过了电阻的额定功率,因此使用是存在危险的。
    2. 光耦的过零点反应速度慢,TZA上升沿时间长。实际测试发现光耦过零点上升沿和下降沿的跳变时间为120us左右(高低电平压差为3.3V)。对于一般的应用可以接受,但是对于通信中的同步应用该反应时间将严重影响通信质量。因为在120us内都可以认为是发生了过零事件,也就是说我对过零的判断可能存在最高达120us的偏差。
    3. 根据光耦的导通特性,该电路的零点指示滞后实际交流电发生的零点。滞后时间可以根据光耦的导通电流计算,NEC2501的典型值是10ma,实际上,当前向电流达到1ma的时候光耦一般就已经导通了。现以1ma电流计算,电阻3×47k=141k,则电压为141V,相应的滞后零点时间约为1.5ms。假设0.5ma导通则电压为70V,则滞后时间为722us。
    4. 光耦导通时间较长,即光耦电流由0变为导通电流这个渐变过程较长,导致光耦特性边缘时间差异明显,产品一致性差。假设以1ma作为光耦的导通电流,那么在220v交流电由0V变化到141V的过程需要1.5ms。而因为期间的一致性问题,部分光耦可能会在0.5ma的时候就导通,部分可能在0.7ma的时候导通。现假设一致性带来的最低导通电流为0.5ma,那么对应导通电压为71V,对应滞后零点时间为736us,这表明,不同光耦之间零点差异可能达到764us!(实际测试中我检测了10个样品,其中两个光耦导通性能差别最大的时间差达到50us,其他普遍在10us左右)。这为不同设备使用该电路进行同步制造了很大的麻烦。
    5. 受光耦导通电流限制,该电路能够检测的交流信号幅度范围较窄。以1ma计算,该光耦只能检测交流信号幅度大于141V的信号。如果该信号用于同步,那么在设备进行低压测试时将不能获取同步信号。
    6. TZA输出波形和标准方波相差较大,占空比高于50%。实际测试中占空比的时间误差达到1.2ms,在应用中该时差不能被忽略。

    基于以上列出的各个问题导致利用交流电过零点进行同步质量较差,需要改进。首先我想到的方案是利用比较器的比较功能来产生标准的方波。在交流电的正半周比较器输出高电平,在交流电的负半周比较器输出低电平。该方案的时间误差仅取决于比较器电平跳变的响应速度和比较器的差分电平分辨率。以lm319为例,偏置电压最大为10mv,比较灵敏度为5mv,5V输出电平跳变响应时间在300ns以内,加上asin(10e-3/311)/2//pi/50 = 100ns。二者总共相差约400ns,远低于图1所示的方案。在实际应用中我使用了LM358来代替比较器,其偏置电流为50na,串接1M的电阻,满足偏置电流的电压为50na×1M=50mv。按照st-lm358资料,其开环频率响应1k一下可以达到100db,因此理论上输入1mv的电平依然可以识别,和前边假设相比取50mv,asin(50mv/311)/2/pi/50 = 500ns,放大器的SR为0.6V/us,假设转换到4V,需要7us。因此使用LM358的绝对误差为7.5us,而实际上由于每个器件的共性,因此在同步上偏差应该小于1.5us。

     

    方案定下来以后就应该进行电路设计了,在实际电路调试的时候遇到很多问题,现记录于此供以后参考。主要问题包括有:

    • 对于差分运放电路缺乏基本的认识,最初考虑用电阻分压电路,按照最大电压311V,电阻分压1:100,选用2M电阻串接一个20k,取20k两端的电压,理论最大差为3.11V的样子,电路如图2-1所示。该电路最终以失败告终。经过学习和查找原因,是因为没有可靠的工作点,或者说没有统一的参考地,浮地输入无法实现放大。同样因为这个原因,在网上寻找的如图2-2所示的电路也以失败告终。

    http://bbs.21ic.com/data/attachment/forum/201705/08/154026ahd0hlzbdhhgwdzd.jpg.thumb.jpg

    • 为了能够对差分放大电路提供统一的参考基准最终对图2-2进行修改,分别从差分输入的+端和-端引一个大电阻到测试系统的“地”,因为是单电源放大考虑到LM358的共模输入信号范围0-VCC-1.5V,由于二极管限幅,二极管两端电压最多0.7V,又因为对于去其中间电平连接到地,正负端对地输入的电压范围为-0.35到+0.35。最终电路如图3所示,该电路可以实现设计功能。

    http://bbs.21ic.com/data/attachment/forum/201705/08/154026serdtkq7zzsdqied.jpg.thumb.jpg

     

     

    经验总结:

    1. 理解运算放大器的共模输入范围,这对运放电路设计很重要。如果输入信号超过共模电压范围,放大器将不能正常工作。
    2. 任何信号耦合都是需要电流驱动的,放大器限流以及不同设备间“地”的连接不是电阻越大越好。当初设计图3的电路,最初R2和R3取500K时,用示波器双通道同时测试测试地到R2,R3两端差分电压,显示其具有相同的波形,幅度8V左右。理论上其原R2,R3两端波形幅度应该为0.35V,相位相反。经过反复试验,发现其原因就在于经过R2,R3电流太小已经没有达到共“地”的效果了,降低R2,R3阻值测试波形和理论一致。
    3. 当初为了安全测试220V端电压波形,查阅了浮地测试技术的相关资料。同时经过实验验证,浮地测试必须要将示波器和被测试系统的公共地断开,具体来说就是让测试仪器和被测试平台不具备相同的参考地电位,这样短接示波器探头的地到被测试平台才不会发生事故。拿本实验举例,假设我们需要测量市电实时波形,怎么测量呢。我们可以这样测试,示波器供电时三芯插头只连接L和N端,接地不连接,这样就可以通过接地夹夹在市电的一端,用探头去测量另一端的波形了。当然最好还是在接地夹串接以大电阻去接市电一端,探头也串接一大电阻去接市电另一端。如果不这样测试会有什么后果???如果不这样测试,因为示波器探头的接地夹是和三芯插头地线导通的,在通过接地夹去夹火线或者零线是就相当于把火线或零线直接与大地相连,如果是零线还没事,如果是火线那必然短路!非常危险!!!

     

    ——转自21IC社区

    http://bbs.21ic.com/icview-1714198-1-1.html

     

    展开全文
  • 关于反电动势过零检测无刷直流电机转子位置新方法. 不同導通角度之下的無感測驅動方式與特性的分析,其中無 感測驅動的技術為使用數位式相位移器與遮罩來偵測由感應電動勢訊號所得到的 零交越點,並且藉由判斷這些零...
  • FOC中的Clarke变换_TI和ST电机控制库的源码实现 FOC中的PARK变换_TI和ST电机控制库的源码实现 FOC中的反PARK变换_TI和ST电机控制库的源码实现 ...基于模型的位置/转速观测器有三部分,反电动势、磁链信息

    FOC中的Clarke变换_TI和ST电机控制库的源码实现
    FOC中的PARK变换_TI和ST电机控制库的源码实现
    FOC中的反PARK变换_TI和ST电机控制库的源码实现

    1.位置信息

    无刷电机的控制不可脱离转子的位置信息。知道转子的位置反馈是对无刷电机控制的前提。通常分为有感和无感。

    有感:即为有位置传感器,像霍尔、光电增量式编码器、旋转变压器、磁编等等。

    无感:则是电机不需要位置传感器,通过电机自身的信息计算或则估计转子的位置。

    2.无感的方法

    基于模型法的位置/转速观测器有三部分,反电动势、磁链信息观测、位置误差信号解耦位置/转速观测。反电动势或磁链信息观测方法的不同,模型有自适应法、扩展卡尔曼滤波器法、磁链观测法、状态观测法、滑膜观测法。

    反电动势过零检测法应用广泛,实现简单、技术成熟。

    3.反电动势过零检测

    3.1反电动势过零检测法基本原理:

    忽略电动机电枢反应,无刷直流电动机在稳态运行过程中,通过检测关断相的反电动势过零点获得转子的位置信号,进行对逆变器开关导通顺序切换,控制电机运动。

    3.2缺点:

    电机静止和低速时,反电动势很小或者为0,无法获取转子位置信号,电机低速时性能较差,启动时需要开环启动。

    3.3硬件电路

    在这里插入图片描述
    反电动势图:
    在这里插入图片描述
    正向反电动势过零点变化:

    反电动势零点变化趋势
    C-C相反电动势又正到负
    B+B相反电动势又负到正
    A-A相反电动势又正到负
    C+C相反电动势又负到正
    B-B相反电动势又正到负
    A+A相反电动势又负到正

    3.4电路计算:

    在这里插入图片描述
    可以直接得到电机端的电压方程:
    { U A = R i A + L d i A d t + e A + U N U B = R i B + L d i B d t + e B + U N U C = R i C + L d i C d t + e C + U N ① \left\{ \begin{array}{l} U_A=Ri_A+L\frac{di_A}{dt}+e_A+U_N\\ U_B=Ri_B+L\frac{di_B}{dt}+e_B+U_N\\ U_C=Ri_C+L\frac{di_C}{dt}+e_C+U_N\\ \end{array} \right. ① UA=RiA+LdtdiA+eA+UNUB=RiB+LdtdiB+eB+UNUC=RiC+LdtdiC+eC+UN

    假设c相不导通时有:
    { U C = e C + U N i A + i B = 0 e A + e B = 0 ② \left\{ \begin{array}{l} U_C=e_C+U_N\\ i_A+i_B=0\\ e_A+e_B=0\\ \end{array} \right. ② UC=eC+UNiA+iB=0eA+eB=0
    可以得到反电动势:
    e C = U C − 1 2 ( U A + U B ) e_C=U_C-\frac{1}{2}\left( U_A+U_B \right) eC=UC21(UA+UB)
    同理可以得到A、B相的的反电动势
    { e A = U A − 1 2 ( U C + U B ) e B = U B − 1 2 ( U A + U C ) e C = U C − 1 2 ( U A + U B ) \left\{ \begin{array}{l} e_A=U_A-\frac{1}{2}\left( U_C+U_B \right)\\ e_B=U_B-\frac{1}{2}\left( U_A+U_C \right)\\ e_C=U_C-\frac{1}{2}\left( U_A+U_B \right)\\ \end{array} \right. eA=UA21(UC+UB)eB=UB21(UA+UC)eC=UC21(UA+UB)
    通过这三个方差去判断反电动势的正负变化得到零点。但是还可以优化一下,方便编程。
    ①和②重新组合一下合一得到:
    U A + U B + U C = e C + 3 U N U_A+U_B+U_C=e_C+3U_N UA+UB+UC=eC+3UN
    当Ec=0时候满足:
    U A + U B + U C = 3 U N ③ U_A+U_B+U_C=3U_N ③ UA+UB+UC=3UN
    可以得到:
    { 3 e A = 3 U A − 3 U N 3 e B = 3 U B − 3 U N 3 e C = 3 U C − 3 U N \left\{ \begin{array}{l} 3e_A=3U_A-3U_N\\ 3e_B=3U_B-3U_N\\ 3e_C=3U_C-3U_N\\ \end{array} \right. 3eA=3UA3UN3eB=3UB3UN3eC=3UC3UN

    4.TI程序:

    4.1换向点电气行为

    **因为在在相位换向的瞬间,由于直流电平或电源板的寄生电感和电容,可能会出现高dV /dt和dI/dt毛刺。可能会对计算的中性点电压有错误。**通过丢弃前几次扫描来克服这问题。(比如从负到正,先一直为负,检测到4次为正时,标志到了过零点检测,算是滤波)

    在代码中,这是通过名为“NOISE_WIN”的功能实现的。持续时间取决于电源开关,电源板设计,相电感和驱动的直流电。此参数取决于系统,并且在电动机的低速范围内设置为较大的值。随着速度的增加,由于Bemf零交叉点也以更高的速度变得越来越近,所以逐渐降低了该持续时间。

    4.2换向30度延迟

    在有效的传感控制中,Bemf的零交叉点从相位换向时刻偏移了30º。因此,在借助六个过零事件来运行无传感器BLDC电动机之前,有必要计算与该30º延迟角相对应的时间延迟获得精确的换向点。这是通过实现位置插值功能来实现的。
    相应的时间延迟以采样时间段的数量表示,并存储在变量CmtnDelay中。

    Time delay = CmtnDelay .Ts = T(a/360) = VirtualTimer.Ts(a/360) = VirtualTimer . Ts/12

    其中,Ts是采样时间段,VirtualTimer是计时器,用于对转子上一圈旋转期间的采样周期数进行计数。

    4.3TI代码实现

    
    typedef  struct { Uint32 CmtnTrig;       	// Output: Commutation trigger output (0 or 0x00007FFF)       
                      _iq Va;                 	// Input: Motor phase a voltage referenced to GND (pu)  
                      _iq Vb;                 	// Input: Motor phase b voltage referenced to GND (pu)  
                      _iq Vc;                 	// Input: Motor phase c voltage referenced to GND (pu) 
                      _iq Neutral;            	// Variable: 3*Motor netural voltage (pu) 
                      Uint32 RevPeriod;      	 // Variable: revolution time counter (Q0)        
                      Uint32 ZcTrig;         	// Variable: Zero-Crossing trig flag (0 or 0x00007FFF)  
                      Uint32 CmtnPointer;     	// Input: Commutation state pointer input (0,1,2,3,4,5)
                      _iq DebugBemf;         	// Variable: 3*Back EMF = 3*(vx=vn), x=a,b,c (pu)
                      Uint32 NoiseWindowCounter;// Variable: Noise windows counter (Q0) 
                      Uint32 Delay30DoneFlag;   // Variable: 30 Deg delay flag (0 or 0x0000000F) 
                      Uint32 NewTimeStamp;  	// Variable: Time stamp (Q0) 
                      Uint32 OldTimeStamp;  	// History: Previous time stamp (Q0) 
    	              Uint32 VirtualTimer;    	// Input: Virtual timer (Q0) 
                      Uint32 CmtnDelay;      	// Variable: Time delay in terms of number of sampling time periods (Q0)    
                      Uint32 DelayTaskPointer; 	// Variable: Delay task pointer, see note below (0 or 1)
                      Uint32 NoiseWindowMax;  	// Variable: Maximum noise windows counter (Q0)
                      Uint32 CmtnDelayCounter; 	// Variable: Time delay counter (Q0) 
                      Uint32 NWDelta;      		// Variable: Noise windows delta (Q0)
                      Uint32 NWDelayThres;    	// Variable: Noise windows dynamic threshold (Q0)
    		 	 	   int32 GPR1_COM_TRIG;		// Variable: Division reminder
    		 	 	   int32 Tmp;				// Variable: Temp. variable
                    } CMTN;
    
    /*
    Note: 
    DelayTaskPointer = 0, branch for #COUNT_DWN
    DelayTaskPointer = 1, branch for #CHK_TRIGGER
    */
    
    /*-----------------------------------------------------------------------------
    Default initalizer for the CMTN object.
    -----------------------------------------------------------------------------*/                     
    #define CMTN_DEFAULTS { 0, \
                            0, \
                            0, \
                            0, \
                            0, \
                            0, \
                            0, \
                            0, \
                            0, \
                            0, \
                            0, \
                            0, \
                            0, \
                            0, \
                            0, \
                            1, \
                            0, \
                            0, \
                            0, \
                            0, \
                            0, \
                            0, \
                  		   }
    /*----------------------------------------------------------------------------------------------
    	 CMTN_TRIG Macro Definition
    ----------------------------------------------------------------------------------------------*/
    
    #define CMTN_TRIG_MACRO(v)																\
    																						\
    /* Always clear flags on entry*/														\
        v.CmtnTrig = 0;																		\
        v.ZcTrig = 0;																		\
            																				\
    /* Neutral voltage calculation (3*motor Neutral voltage)*/								\
    	v.Neutral = v.Va + v.Vb + v.Vc;														\
    																						\
    /* Commutation State table Tasks*/														\
    /* State s1: current flows to motor windings from phase A->B, de-energized phase = C*/	\
       if (v.CmtnPointer == 0)																\
        {																					\
    	  v.DebugBemf = _IQmpy(_IQ(3),v.Vc) - v.Neutral;									\
    	  if (v.DebugBemf > 0)																\
    	       v.NoiseWindowCounter = 0;													\
    	  else   /*  Zero crossing Noise window processing*/								\
               NOISE_WINDOW_CNT_MACRO(v);													\
        }   /* else if-end: State s1*/ 														\
    																						\
    /* State s2: current flows to motor windings from phase A->C, de-energized phase = B*/ 	\
        else if (v.CmtnPointer == 1)  														\
    	{																					\
    	  v.DebugBemf = _IQmpy(_IQ(3),v.Vb) - v.Neutral;									\
    	  if (v.DebugBemf < 0)																\
    	       v.NoiseWindowCounter = 0;													\
    	  else   /*  Zero crossing Noise window processing*/								\
               NOISE_WINDOW_CNT_MACRO(v);													\
        }   /* else if-end: State s2*/														\
    																						\
    /* State s3: current flows to motor windings from phase B->C, de-energized phase = A*/ 	\
        else if (v.CmtnPointer == 2)  														\
        {																					\
    	  v.DebugBemf = _IQmpy(_IQ(3),v.Va) - v.Neutral;									\
    	  if (v.DebugBemf > 0)																\
    	       v.NoiseWindowCounter = 0;													\
    	  else  /*  Zero crossing Noise window processing*/									\
               NOISE_WINDOW_CNT_MACRO(v);													\
        }   /* else if-end: State s3*/														\
    																						\
    /* State s4: current flows to motor windings from phase B->A, de-energized phase = C*/	\
        else if (v.CmtnPointer == 3)  														\
        {																					\
    	  v.DebugBemf = _IQmpy(_IQ(3),v.Vc) - v.Neutral;									\
    	  if (v.DebugBemf < 0)																\
    	       v.NoiseWindowCounter = 0;													\
    	  else   /*  Zero crossing Noise window processing*/								\
               NOISE_WINDOW_CNT_MACRO(v);													\
        }   /* else if-end: State s4*/														\
    																						\
    /* State s5: current flows to motor windings from phase C->A, de-energized phase = B*/	\
        else if (v.CmtnPointer == 4)														\
        {	
            /*计算三十度延迟的flag置位*/													\
    	  v.Delay30DoneFlag = 0;	       /* clear flag for delay calc in State 5*/		\
    	  																					\
    	  v.DebugBemf = _IQmpy(_IQ(3),v.Vb) - v.Neutral;									\
    	  if (v.DebugBemf > 0)																\
    	       v.NoiseWindowCounter = 0;													\
    	  else   /*  Zero crossing Noise window processing */								\
               NOISE_WINDOW_CNT_MACRO(v);													\
        }   /* else if-end: State s5	 */													\
    																						\
    /* State s6: current flows to motor windings from phase C->B, de-energized phase = A*/	\
        else if (v.CmtnPointer == 5)  														\
        {																					\
    	  v.DebugBemf = _IQmpy(_IQ(3),v.Va) - v.Neutral;									\
    	  if (v.DebugBemf < 0)																\
    	       v.NoiseWindowCounter = 0;													\
    	  else   /*  Zero crossing Noise window processing*/								\
               NOISE_WINDOW_CNT_MACRO(v);													\
          /*计算三十度延迟*/
          DELAY_30DEG_MACRO(v);																\
        }   /* else if-end: State s6*/														\
    																						\
    /* Zero crossing to Commutation trigger delay*/											\
       v.CmtnTrig = 0;     /* Always clear flag on entry */									\
    	
       /* 得到过零点后,进行30度延迟 */												     	\
       if (v.DelayTaskPointer > 0)     /* v.DelayTaskPointer = 1 for #CHK_TRIGGER*/			\
       { 																					\
          if (v.ZcTrig != 0)																\
          {																					\
    /* Substract NoiseWindowMax to compensate the advanced zero-crossing validation point */\
              v.CmtnDelayCounter = v.CmtnDelay - v.NoiseWindowMax;							\
              v.DelayTaskPointer = 0;     /* v.DelayTaskPointer = 0 for #COUNT_DWN*/		\
          }																					\
       }																					\
       else     /* v.DelayTaskPointer = 0 for #COUNT_DWN */									\
       {
          /* 计数减到0,得到换向点*/  										            	\
           v.CmtnDelayCounter -= 1;															\
           if (v.CmtnDelayCounter == 0) 													\
           {																				\
              v.CmtnTrig = 0x00007FFF; /* Yes!- Set trigger. This is used */				\
    /* as an input to "MOD6_CNTR" module that changes the commutation sequence.*/			\
    						             													\
              v.DelayTaskPointer = 1;       /* v.DelayTaskPointer = 1 for #CHK_TRIGGER*/	\
           }    																			\
       }
    
    /*----------------------------------------------------------------------------------------------
    	 NOISE_WINDOW_CNT Macro Definition
    ----------------------------------------------------------------------------------------------*/
    // 滤噪窗口,认为过了NoiseWindowMax个计数才算过零点
    #define NOISE_WINDOW_CNT_MACRO(v)															\
       if (v.CmtnDelay >= v.NWDelayThres)      /* noise window is fixed Value*/					\
          v.NoiseWindowMax = v.NWDelayThres - v.NWDelta;										\
       else                                       /* noise window adjusted dynamically*/		\
          v.NoiseWindowMax = v.CmtnDelay - v.NWDelta;											\
    																							\
       v.NoiseWindowCounter += 1;																\
    																							\
       if (v.NoiseWindowCounter == v.NoiseWindowMax)  /* zc must occur max_noise_window times*/	\
       {																						\
         v.ZcTrig = 0x00007FFF;       /* Yes! Set trigger */									\
         v.NoiseWindowCounter = 0;																\
       }								
    
    /*----------------------------------------------------------------------------------------------
    	DELAY_30DEG Macro Definition
    ----------------------------------------------------------------------------------------------*/
    // 30度角的延迟计算
    #define DELAY_30DEG_MACRO(v)																\
    /* Delay 30 deg calculator*/																\
       if (v.Delay30DoneFlag == 0)																\
       { 
          /*更新时间计数、计算上一圈花了多少时间*/ 								         		\
          v.OldTimeStamp = v.NewTimeStamp; 														\
          v.NewTimeStamp = v.VirtualTimer; 														\
          v.Tmp = v.NewTimeStamp - v.OldTimeStamp; 												\
          																						\
          if (v.Tmp > 0) /* Period = NewTimeStamp - OldTimeStamp*/								\
              v.RevPeriod = v.Tmp;																\
          else       /* If Period is negative, allow "wrapping"  */								\
              v.RevPeriod = 0x00007FFF + v.Tmp;													\
    																							\
          v.RevPeriod &= 0x0000FFFF;															\
    		 /* T/12算下一圈30度角延迟计数*/					         		            	\
          v.CmtnDelay = v.RevPeriod/12;                  /* Division quotient*/					\
          /* 算余数,大于6则再+1*/	
          v.GPR1_COM_TRIG = v.RevPeriod - v.CmtnDelay*12;  /* Division reminder*/				\
          if (v.GPR1_COM_TRIG >= 6) 															\
               v.CmtnDelay += 1;     /* if Division reminder >= 6, rounding division quotient*/	\
          v.Delay30DoneFlag = 0x0000000F;  /* flag indicates "gone through" once*/				\
       }   /* if-end: v.Delay30DoneFlag == 0*/    
    
    

    参考学习:
    TI Digital Motor Control,DMC MATH_V13.1
    [1]李伟.无位置传感器 BLDC 电机控制器研究[D].吉林:吉林大学.2014:7
    [2]韩芳.双模型无刷直流电动机控制器设计与实现[D].成都.电子科技大学.2015.4
    [3]刘雨锋.无刷直流电机无位置传感器关键控制技术研究[D].江西.江西理工大学.2019.5
    [4]童小健.无位置传感器永磁无刷直流电机控制策略研究[D].深圳.深圳大学.2015.4
    [5]李自成.无刷直流电机无位置传感器控制关键技术研究[D].武汉.华中科技大学.2010.3


    被抛弃的写随笔公众号改写技术文章了,感兴趣的可以关注公众号:王崇卫
    在这里插入图片描述

    展开全文
  • 基于短时能量和过零率分析的语音端点检测方法研究,刘波,聂明新, 短时能量分析和过零率分析作为语音信号时域分析中最基本的方法,应用相当广泛,特别是在语音信号端点检测方面。由于在语音信��
  • 为了实现对电机的同步控制, 提出了一种获取三相交流电的电压过零信号和电源相序自适应方法。该方法以P87C591单片机为核心,利用6N137光耦和P87C591单片机的捕获功能实现对电压零点的检测;由软件实现对电源相序的...
  • 一种快速的基于短时能量和过零率的语音端点检测方法,于俊,王明英,本文结合时域信号中短时能量和过零率提出了一种快速的语音端点检测方法,我们通过设置和综合使用两个门限电平来得到语音信号的端��
  • 无位置传感器无刷直流电机在高速段时反电势信号大, 容易造成检测电路无法正常工作甚至损坏, 而在较低速段时, 反电势信号又难以有效检测
  • 过零法测频率matlab程序

    热门讨论 2011-04-05 19:27:51
    一个利用过零法测回波频率的matlab程序,目前多普勒计程仪多用此种算法,
  • 提出了一种新的基于SVM的虹膜识别算法,通过对虹膜纹理采用小波变换来实现特征提取,最后通过SVM完成模式匹配。实验结果表明,该算法识别率高并可有效地应用于虹膜身份鉴别系统中。
  • 基于目标和背景两区域平均灰度值之差的平方构造外部能量函数(区域间差异性函数),并使其最大化,确保水平集曲线稳定地收敛于目标边界。实验结果表明,提出的模型不仅有效地克服了传统模型需重新初始化的缺点,...
  • lm393 过零检测 功率因数检测 引脚图 multism仿真 实际电路 注意事项: 引脚图 multism仿真 实际电路 vcc 12V in+ 幅值4V的正弦信号 IN- 接地 注意事项: 两个二级管不能少 lm393为集电极输出,要在输出加上拉电阻 ...
  • 一种多门限过零率前端检测理论的参数自优化方法研究置、电子技术,开发板制作交流
  • 行业资料-电子功用-用于同步降压型变换器的过零检测电路及检测方法
  • 过零检测电路原理与作用 可控整流

    万次阅读 2015-04-27 09:24:01
    原文地址:... 使用光耦 ...网友建议 电容代替那只47K的电阻,330欧电阻直接短路....电阻限流的缺点是过零脉冲的宽度与检测电压值相关.可以用一只0.1u/400v的无极性电
  • 基于matlab语音端点检测(包括过零率,短时能量和终点检测~) 基于matlab语音端点检测(包括过零率,短时能量和终点检测~)
  • 为提高零点检测精度,减小漏电保护器的拒动作和误动作,本文介绍了零点检测的基本原理,理论论述零点检测误差存在的原因,提出一种新的零点检测方法;给出电路设计图及仿真结果。经验证,该电路将过零检测的...
  • 此电路采用了更简便,安全的方法检测三相电路相位,还可以进行过零检测和缺相检测,非常安全

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 166,003
精华内容 66,401
关键字:

过零检测法