1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | /// /// Where **prescaler can be (1, 8, 64, 512)** and **TOP can be 0 to 65532**. /// Modulated value is represented by 16 bits in process data and internally scaled to 0 to TOP range. /// Because this leads to a bigger value of TOP and so a better resolution of the modulated value. /// Prescaler Recommended range low boundary Recommended range high boundary /// 8 100 Hz TOP = 40000 < 1 kHz TOP = 4000 /// 512 1 Hz TOP = 62500 < 10 Hz TOP = 6250 /// Example: /// f_PWM = 10Hz => 16#C352 = 50002 /// base frequency of the PWM, anywhere from 1Hz to 100kHz (10 Hz = 10, 100kHz = 100000) ePrescale : MNR.ePrescaler; /// Determined prefered prescaler uiRangeLow : UINT; uiRangeHigh : UINT; uiTOP : UINT; /// Determined TOP setting /// clip the input Hz on lower and upper bound; _uidiHz := LIMIT( 1, udiHz, 100000); //// Determine prescaler and TOP according to table CASE _uidiHz OF 1..9 : ePrescale := ePrescaler.ScaleFactor512; uiTOP := TO_UINT( (32000000/ 64/ _uidiHz)); // interpolate between 10 and 100Hz 100..999 : ePrescale := ePrescaler.ScaleFactor8; uiTOP := TO_UINT( (32000000/ 1/ _uidiHz));// interpolate between 1000 and 100000Hz END_CASE /// Now set prescaler /// bit 15 .. 2 : TOP / 4 CASE ePrescale OF /// 00 0 : prescaler = 1 ePrescaler.ScaleFactor1 : fPWM.0 := FALSE; fPWM.1 := FALSE; /// 01 1 : prescaler = 8 ePrescaler.ScaleFactor8 : fPWM.0 := TRUE; /// 10 2 : prescaler = 64 ePrescaler.ScaleFactor64 : fPWM.0 := FALSE; fPWM.1 := TRUE; /// 11 3 : prescaler = 512 ePrescaler.ScaleFactor512 : fPWM.0 := TRUE; // 8.0 2.0 PWM1 frequency THIS^._abyIntTxBuf[16] := WORD_TO_BYTE(fPWM); THIS^._abyIntTxBuf[17] := WORD_TO_BYTE(SHR(fPWM,8)); |