mirror of
https://github.com/espressif/esp-idf.git
synced 2026-09-22 13:01:16 +03:00
Merge branch 'fix/mcpwm_cap_prescale' into 'master'
fix(mcpwm): correct the wrong capture prescale Closes IDFGH-18010 See merge request espressif/esp-idf!51691
This commit is contained in:
74
docs/_static/mcpwm/capture_prescale_both.svg
vendored
Normal file
74
docs/_static/mcpwm/capture_prescale_both.svg
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 700 440" font-family="'DejaVu Sans Mono', 'Consolas', 'Liberation Mono', monospace">
|
||||
<defs>
|
||||
<marker id="arr" markerWidth="8" markerHeight="6" refX="8" refY="3" orient="auto">
|
||||
<polygon points="0,0 8,3 0,6" fill="#555"/>
|
||||
</marker>
|
||||
</defs>
|
||||
<rect width="700" height="440" fill="#ffffff" rx="8"/>
|
||||
<text x="350" y="24" text-anchor="middle" font-size="13" fill="#333" font-weight="700">Both edges</text>
|
||||
<text x="350" y="42" text-anchor="middle" font-size="10" fill="#666">API prescale = same-edge ratio</text>
|
||||
|
||||
<text x="20" y="68" font-size="12" fill="#333" font-weight="700">A. prescale = 1 (bypass)</text>
|
||||
<g transform="translate(80, 78)">
|
||||
<text x="-10" y="36" text-anchor="end" font-size="11" fill="#1e88e5" font-weight="600">input</text>
|
||||
<polyline fill="none" stroke="#1e88e5" stroke-width="2"
|
||||
points="0,40 0,12 35,12 35,40 70,40 70,12 105,12 105,40 140,40 140,12 175,12 175,40 210,40"/>
|
||||
<g fill="#e53935"><circle cx="0" cy="12" r="3.5"/><circle cx="70" cy="12" r="3.5"/><circle cx="140" cy="12" r="3.5"/></g>
|
||||
<g fill="#fb8c00"><rect x="31" y="8" width="8" height="8"/><rect x="101" y="8" width="8" height="8"/><rect x="171" y="8" width="8" height="8"/></g>
|
||||
<text x="-10" y="100" text-anchor="end" font-size="11" fill="#333" font-weight="600">capture</text>
|
||||
<line x1="0" y1="92" x2="210" y2="92" stroke="#999" stroke-width="1.5"/>
|
||||
<line x1="0" y1="12" x2="0" y2="92" stroke="#e53935" stroke-width="1" stroke-dasharray="3,3"/>
|
||||
<line x1="35" y1="40" x2="35" y2="92" stroke="#fb8c00" stroke-width="1" stroke-dasharray="3,3"/>
|
||||
<line x1="70" y1="12" x2="70" y2="92" stroke="#e53935" stroke-width="1" stroke-dasharray="3,3"/>
|
||||
<line x1="105" y1="40" x2="105" y2="92" stroke="#fb8c00" stroke-width="1" stroke-dasharray="3,3"/>
|
||||
<polyline points="0,92 0,72 12,72 12,92" fill="none" stroke="#e53935" stroke-width="2"/>
|
||||
<polyline points="35,92 35,72 47,72 47,92" fill="none" stroke="#fb8c00" stroke-width="2"/>
|
||||
<polyline points="70,92 70,72 82,72 82,92" fill="none" stroke="#e53935" stroke-width="2"/>
|
||||
<polyline points="105,92 105,72 117,72 117,92" fill="none" stroke="#fb8c00" stroke-width="2"/>
|
||||
<text x="6" y="66" text-anchor="middle" font-size="10" fill="#e53935" font-weight="700">R</text>
|
||||
<text x="41" y="66" text-anchor="middle" font-size="10" fill="#fb8c00" font-weight="700">F</text>
|
||||
<text x="76" y="66" text-anchor="middle" font-size="10" fill="#e53935" font-weight="700">R</text>
|
||||
<text x="111" y="66" text-anchor="middle" font-size="10" fill="#fb8c00" font-weight="700">F</text>
|
||||
<text x="250" y="36" font-size="10" fill="#e53935" font-weight="600">R = GPIO rising</text>
|
||||
<text x="250" y="54" font-size="10" fill="#fb8c00" font-weight="600">F = GPIO falling</text>
|
||||
</g>
|
||||
|
||||
<text x="20" y="228" font-size="12" fill="#333" font-weight="700">B. prescale = 4</text>
|
||||
<g transform="translate(80, 250)">
|
||||
<text x="-10" y="36" text-anchor="end" font-size="11" fill="#1e88e5" font-weight="600">input</text>
|
||||
<polyline fill="none" stroke="#1e88e5" stroke-width="2"
|
||||
points="0,40 0,12 35,12 35,40 70,40 70,12 105,12 105,40 140,40 140,12 175,12 175,40 210,40 210,12 245,12 245,40 280,40 280,12 315,12 315,40 350,40 350,12 385,12 385,40 420,40 420,12 455,12 455,40 490,40 490,12"/>
|
||||
<!-- first at cycle 1, then every 2: 1(R),3(F),5(R),7(F) -->
|
||||
<g fill="#1e88e5"><circle cx="70" cy="12" r="3.5"/><circle cx="210" cy="12" r="3.5"/><circle cx="350" cy="12" r="3.5"/><circle cx="490" cy="12" r="3.5"/></g>
|
||||
<g fill="#bbb"><circle cx="0" cy="12" r="3"/><circle cx="140" cy="12" r="3"/><circle cx="280" cy="12" r="3"/><circle cx="420" cy="12" r="3"/></g>
|
||||
<g fill="#ccc"><rect x="31" y="8" width="8" height="8"/><rect x="101" y="8" width="8" height="8"/><rect x="171" y="8" width="8" height="8"/><rect x="241" y="8" width="8" height="8"/><rect x="311" y="8" width="8" height="8"/><rect x="381" y="8" width="8" height="8"/><rect x="451" y="8" width="8" height="8"/></g>
|
||||
<text x="70" y="-4" text-anchor="middle" font-size="9" fill="#1e88e5" font-weight="700">cycle 1</text>
|
||||
<text x="210" y="-4" text-anchor="middle" font-size="9" fill="#1e88e5" font-weight="700">cycle 3</text>
|
||||
<text x="350" y="-4" text-anchor="middle" font-size="9" fill="#1e88e5" font-weight="700">cycle 5</text>
|
||||
<text x="490" y="-4" text-anchor="middle" font-size="9" fill="#1e88e5" font-weight="700">cycle 7</text>
|
||||
|
||||
<text x="-10" y="100" text-anchor="end" font-size="11" fill="#333" font-weight="600">capture</text>
|
||||
<line x1="0" y1="92" x2="490" y2="92" stroke="#999" stroke-width="1.5"/>
|
||||
<line x1="70" y1="12" x2="70" y2="92" stroke="#e53935" stroke-width="1" stroke-dasharray="3,3"/>
|
||||
<line x1="210" y1="12" x2="210" y2="92" stroke="#fb8c00" stroke-width="1" stroke-dasharray="3,3"/>
|
||||
<line x1="350" y1="12" x2="350" y2="92" stroke="#e53935" stroke-width="1" stroke-dasharray="3,3"/>
|
||||
<line x1="490" y1="12" x2="490" y2="92" stroke="#fb8c00" stroke-width="1" stroke-dasharray="3,3"/>
|
||||
<polyline points="70,92 70,70 82,70 82,92" fill="none" stroke="#e53935" stroke-width="2"/>
|
||||
<polyline points="210,92 210,70 222,70 222,92" fill="none" stroke="#fb8c00" stroke-width="2"/>
|
||||
<polyline points="350,92 350,70 362,70 362,92" fill="none" stroke="#e53935" stroke-width="2"/>
|
||||
<polyline points="490,92 490,70 502,70 502,92" fill="none" stroke="#fb8c00" stroke-width="2"/>
|
||||
<text x="76" y="64" text-anchor="middle" font-size="10" fill="#e53935" font-weight="700">R</text>
|
||||
<text x="216" y="64" text-anchor="middle" font-size="10" fill="#fb8c00" font-weight="700">F</text>
|
||||
<text x="356" y="64" text-anchor="middle" font-size="10" fill="#e53935" font-weight="700">R</text>
|
||||
<text x="496" y="64" text-anchor="middle" font-size="10" fill="#fb8c00" font-weight="700">F</text>
|
||||
|
||||
<line x1="70" y1="110" x2="70" y2="120" stroke="#666"/><line x1="210" y1="110" x2="210" y2="120" stroke="#666"/>
|
||||
<line x1="70" y1="115" x2="210" y2="115" stroke="#666" stroke-width="1.5" marker-end="url(#arr)"/>
|
||||
<text x="140" y="134" text-anchor="middle" font-size="10" fill="#666" font-weight="600">adj = 2 x T = (prescale/2) x T</text>
|
||||
|
||||
<line x1="70" y1="144" x2="70" y2="154" stroke="#e53935"/><line x1="350" y1="144" x2="350" y2="154" stroke="#e53935"/>
|
||||
<line x1="70" y1="149" x2="350" y2="149" stroke="#e53935" stroke-width="1.5" marker-end="url(#arr)"/>
|
||||
<text x="210" y="168" text-anchor="middle" font-size="11" fill="#e53935" font-weight="600">R-to-R = 4 x T = prescale x T</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 6.5 KiB |
61
docs/_static/mcpwm/capture_prescale_falling.svg
vendored
Normal file
61
docs/_static/mcpwm/capture_prescale_falling.svg
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 700 420" font-family="'DejaVu Sans Mono', 'Consolas', 'Liberation Mono', monospace">
|
||||
<defs>
|
||||
<marker id="arr" markerWidth="8" markerHeight="6" refX="8" refY="3" orient="auto">
|
||||
<polygon points="0,0 8,3 0,6" fill="#555"/>
|
||||
</marker>
|
||||
</defs>
|
||||
<rect width="700" height="420" fill="#ffffff" rx="8"/>
|
||||
<text x="350" y="24" text-anchor="middle" font-size="13" fill="#333" font-weight="700">Falling-edge only</text>
|
||||
<text x="350" y="42" text-anchor="middle" font-size="10" fill="#666">API prescale = same-edge ratio</text>
|
||||
|
||||
<text x="20" y="68" font-size="12" fill="#333" font-weight="700">A. prescale = 1 (bypass)</text>
|
||||
<g transform="translate(80, 78)">
|
||||
<text x="-10" y="36" text-anchor="end" font-size="11" fill="#1e88e5" font-weight="600">input</text>
|
||||
<polyline fill="none" stroke="#1e88e5" stroke-width="2"
|
||||
points="0,40 0,12 35,12 35,40 70,40 70,12 105,12 105,40 140,40 140,12 175,12 175,40 210,40"/>
|
||||
<g fill="#ccc"><circle cx="0" cy="12" r="3"/><circle cx="70" cy="12" r="3"/><circle cx="140" cy="12" r="3"/></g>
|
||||
<g fill="#fb8c00"><rect x="31" y="8" width="8" height="8"/><rect x="101" y="8" width="8" height="8"/><rect x="171" y="8" width="8" height="8"/></g>
|
||||
<text x="-10" y="100" text-anchor="end" font-size="11" fill="#fb8c00" font-weight="600">capture</text>
|
||||
<line x1="0" y1="92" x2="210" y2="92" stroke="#fb8c00" stroke-width="1.5"/>
|
||||
<line x1="35" y1="40" x2="35" y2="92" stroke="#ccc" stroke-width="1" stroke-dasharray="3,3"/>
|
||||
<line x1="105" y1="40" x2="105" y2="92" stroke="#ccc" stroke-width="1" stroke-dasharray="3,3"/>
|
||||
<line x1="175" y1="40" x2="175" y2="92" stroke="#ccc" stroke-width="1" stroke-dasharray="3,3"/>
|
||||
<polyline points="35,92 35,72 47,72 47,92" fill="none" stroke="#fb8c00" stroke-width="2"/>
|
||||
<polyline points="105,92 105,72 117,72 117,92" fill="none" stroke="#fb8c00" stroke-width="2"/>
|
||||
<polyline points="175,92 175,72 187,72 187,92" fill="none" stroke="#fb8c00" stroke-width="2"/>
|
||||
<text x="41" y="66" text-anchor="middle" font-size="10" fill="#fb8c00" font-weight="700">F</text>
|
||||
<text x="111" y="66" text-anchor="middle" font-size="10" fill="#fb8c00" font-weight="700">F</text>
|
||||
<text x="181" y="66" text-anchor="middle" font-size="10" fill="#fb8c00" font-weight="700">F</text>
|
||||
<text x="250" y="40" font-size="10" fill="#555">Every falling edge -> F</text>
|
||||
<text x="250" y="58" font-size="10" fill="#888">Rising edges ignored</text>
|
||||
</g>
|
||||
|
||||
<text x="20" y="228" font-size="12" fill="#333" font-weight="700">B. prescale = 4</text>
|
||||
<g transform="translate(80, 250)">
|
||||
<text x="-10" y="36" text-anchor="end" font-size="11" fill="#1e88e5" font-weight="600">input</text>
|
||||
<polyline fill="none" stroke="#1e88e5" stroke-width="2"
|
||||
points="0,40 0,12 35,12 35,40 70,40 70,12 105,12 105,40 140,40 140,12 175,12 175,40 210,40 210,12 245,12 245,40 280,40 280,12 315,12 315,40 350,40 350,12 385,12 385,40 420,40 420,12 455,12 455,40 490,40 490,12"/>
|
||||
<!-- first at cycle 3, then every 4: cycle 3, 7 -->
|
||||
<g fill="#1e88e5"><circle cx="210" cy="12" r="3.5"/><circle cx="490" cy="12" r="3.5"/></g>
|
||||
<g fill="#bbb"><circle cx="0" cy="12" r="3"/><circle cx="70" cy="12" r="3"/><circle cx="140" cy="12" r="3"/><circle cx="280" cy="12" r="3"/><circle cx="350" cy="12" r="3"/><circle cx="420" cy="12" r="3"/></g>
|
||||
<g fill="#ccc"><rect x="31" y="8" width="8" height="8"/><rect x="101" y="8" width="8" height="8"/><rect x="171" y="8" width="8" height="8"/><rect x="241" y="8" width="8" height="8"/><rect x="311" y="8" width="8" height="8"/><rect x="381" y="8" width="8" height="8"/><rect x="451" y="8" width="8" height="8"/></g>
|
||||
<text x="210" y="-4" text-anchor="middle" font-size="9" fill="#1e88e5" font-weight="700">cycle 3</text>
|
||||
<text x="490" y="-4" text-anchor="middle" font-size="9" fill="#1e88e5" font-weight="700">cycle 7</text>
|
||||
<line x1="0" y1="52" x2="70" y2="52" stroke="#bbb" stroke-width="1"/>
|
||||
<line x1="0" y1="48" x2="0" y2="56" stroke="#bbb"/><line x1="70" y1="48" x2="70" y2="56" stroke="#bbb"/>
|
||||
<text x="35" y="68" text-anchor="middle" font-size="10" fill="#888">T</text>
|
||||
<text x="-10" y="108" text-anchor="end" font-size="11" fill="#fb8c00" font-weight="600">capture</text>
|
||||
<line x1="0" y1="100" x2="490" y2="100" stroke="#fb8c00" stroke-width="1.5"/>
|
||||
<line x1="210" y1="12" x2="210" y2="100" stroke="#ccc" stroke-width="1" stroke-dasharray="3,3"/>
|
||||
<line x1="490" y1="12" x2="490" y2="100" stroke="#ccc" stroke-width="1" stroke-dasharray="3,3"/>
|
||||
<polyline points="210,100 210,80 222,80 222,100" fill="none" stroke="#fb8c00" stroke-width="2"/>
|
||||
<polyline points="490,100 490,80 502,80 502,100" fill="none" stroke="#fb8c00" stroke-width="2"/>
|
||||
<text x="216" y="74" text-anchor="middle" font-size="10" fill="#fb8c00" font-weight="700">F</text>
|
||||
<text x="496" y="74" text-anchor="middle" font-size="10" fill="#fb8c00" font-weight="700">F</text>
|
||||
<text x="350" y="90" text-anchor="middle" font-size="10" fill="#555">first = prescale - 1, then every 4</text>
|
||||
<line x1="210" y1="118" x2="210" y2="130" stroke="#333"/><line x1="490" y1="118" x2="490" y2="130" stroke="#333"/>
|
||||
<line x1="210" y1="124" x2="490" y2="124" stroke="#333" stroke-width="1.5" marker-end="url(#arr)"/>
|
||||
<text x="350" y="146" text-anchor="middle" font-size="11" fill="#333" font-weight="600">same-edge = 4 x T = prescale x T</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.4 KiB |
60
docs/_static/mcpwm/capture_prescale_rising.svg
vendored
Normal file
60
docs/_static/mcpwm/capture_prescale_rising.svg
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 700 400" font-family="'DejaVu Sans Mono', 'Consolas', 'Liberation Mono', monospace">
|
||||
<defs>
|
||||
<marker id="arr" markerWidth="8" markerHeight="6" refX="8" refY="3" orient="auto">
|
||||
<polygon points="0,0 8,3 0,6" fill="#555"/>
|
||||
</marker>
|
||||
</defs>
|
||||
<rect width="700" height="400" fill="#ffffff" rx="8"/>
|
||||
<text x="350" y="24" text-anchor="middle" font-size="13" fill="#333" font-weight="700">Rising-edge only</text>
|
||||
<text x="350" y="42" text-anchor="middle" font-size="10" fill="#666">API prescale = same-edge ratio</text>
|
||||
|
||||
<text x="20" y="68" font-size="12" fill="#333" font-weight="700">A. prescale = 1 (bypass)</text>
|
||||
<g transform="translate(80, 78)">
|
||||
<text x="-10" y="36" text-anchor="end" font-size="11" fill="#1e88e5" font-weight="600">input</text>
|
||||
<polyline fill="none" stroke="#1e88e5" stroke-width="2"
|
||||
points="0,40 0,12 35,12 35,40 70,40 70,12 105,12 105,40 140,40 140,12 175,12 175,40 210,40"/>
|
||||
<g fill="#1e88e5"><circle cx="0" cy="12" r="3.5"/><circle cx="70" cy="12" r="3.5"/><circle cx="140" cy="12" r="3.5"/></g>
|
||||
<g fill="#ccc"><rect x="31" y="8" width="8" height="8"/><rect x="101" y="8" width="8" height="8"/><rect x="171" y="8" width="8" height="8"/></g>
|
||||
<text x="-10" y="100" text-anchor="end" font-size="11" fill="#e53935" font-weight="600">capture</text>
|
||||
<line x1="0" y1="92" x2="210" y2="92" stroke="#e53935" stroke-width="1.5"/>
|
||||
<line x1="0" y1="12" x2="0" y2="92" stroke="#ccc" stroke-width="1" stroke-dasharray="3,3"/>
|
||||
<line x1="70" y1="12" x2="70" y2="92" stroke="#ccc" stroke-width="1" stroke-dasharray="3,3"/>
|
||||
<line x1="140" y1="12" x2="140" y2="92" stroke="#ccc" stroke-width="1" stroke-dasharray="3,3"/>
|
||||
<polyline points="0,92 0,72 12,72 12,92" fill="none" stroke="#e53935" stroke-width="2"/>
|
||||
<polyline points="70,92 70,72 82,72 82,92" fill="none" stroke="#e53935" stroke-width="2"/>
|
||||
<polyline points="140,92 140,72 152,72 152,92" fill="none" stroke="#e53935" stroke-width="2"/>
|
||||
<text x="6" y="66" text-anchor="middle" font-size="10" fill="#e53935" font-weight="700">R</text>
|
||||
<text x="76" y="66" text-anchor="middle" font-size="10" fill="#e53935" font-weight="700">R</text>
|
||||
<text x="146" y="66" text-anchor="middle" font-size="10" fill="#e53935" font-weight="700">R</text>
|
||||
<text x="250" y="40" font-size="10" fill="#555">Every rising edge -> R</text>
|
||||
<text x="250" y="58" font-size="10" fill="#888">Falling edges ignored</text>
|
||||
</g>
|
||||
|
||||
<text x="20" y="228" font-size="12" fill="#333" font-weight="700">B. prescale = 4</text>
|
||||
<g transform="translate(80, 250)">
|
||||
<text x="-10" y="36" text-anchor="end" font-size="11" fill="#1e88e5" font-weight="600">input</text>
|
||||
<polyline fill="none" stroke="#1e88e5" stroke-width="2"
|
||||
points="0,40 0,12 35,12 35,40 70,40 70,12 105,12 105,40 140,40 140,12 175,12 175,40 210,40 210,12 245,12 245,40 280,40 280,12 315,12 315,40 350,40 350,12 385,12 385,40 420,40 420,12"/>
|
||||
<!-- first at cycle 1, then every 4: cycle 1, 5 -->
|
||||
<g fill="#bbb"><circle cx="0" cy="12" r="3"/><circle cx="140" cy="12" r="3"/><circle cx="210" cy="12" r="3"/><circle cx="280" cy="12" r="3"/><circle cx="420" cy="12" r="3"/></g>
|
||||
<g fill="#1e88e5"><circle cx="70" cy="12" r="3.5"/><circle cx="350" cy="12" r="3.5"/></g>
|
||||
<text x="70" y="-4" text-anchor="middle" font-size="9" fill="#1e88e5" font-weight="700">cycle 1</text>
|
||||
<text x="350" y="-4" text-anchor="middle" font-size="9" fill="#1e88e5" font-weight="700">cycle 5</text>
|
||||
<line x1="0" y1="52" x2="70" y2="52" stroke="#bbb" stroke-width="1"/>
|
||||
<line x1="0" y1="48" x2="0" y2="56" stroke="#bbb"/><line x1="70" y1="48" x2="70" y2="56" stroke="#bbb"/>
|
||||
<text x="35" y="68" text-anchor="middle" font-size="10" fill="#888">T</text>
|
||||
<text x="-10" y="108" text-anchor="end" font-size="11" fill="#e53935" font-weight="600">capture</text>
|
||||
<line x1="0" y1="100" x2="420" y2="100" stroke="#e53935" stroke-width="1.5"/>
|
||||
<line x1="70" y1="12" x2="70" y2="100" stroke="#ccc" stroke-width="1" stroke-dasharray="3,3"/>
|
||||
<line x1="350" y1="12" x2="350" y2="100" stroke="#ccc" stroke-width="1" stroke-dasharray="3,3"/>
|
||||
<polyline points="70,100 70,80 82,80 82,100" fill="none" stroke="#e53935" stroke-width="2"/>
|
||||
<polyline points="350,100 350,80 362,80 362,100" fill="none" stroke="#e53935" stroke-width="2"/>
|
||||
<text x="76" y="74" text-anchor="middle" font-size="10" fill="#e53935" font-weight="700">R</text>
|
||||
<text x="356" y="74" text-anchor="middle" font-size="10" fill="#e53935" font-weight="700">R</text>
|
||||
<text x="210" y="90" text-anchor="middle" font-size="10" fill="#555">first = prescale/2 - 1, then every 4</text>
|
||||
<line x1="70" y1="118" x2="70" y2="130" stroke="#333"/><line x1="350" y1="118" x2="350" y2="130" stroke="#333"/>
|
||||
<line x1="70" y1="124" x2="350" y2="124" stroke="#333" stroke-width="1.5" marker-end="url(#arr)"/>
|
||||
<text x="210" y="146" text-anchor="middle" font-size="11" fill="#333" font-weight="600">same-edge = 4 x T = prescale x T</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.0 KiB |
@@ -68,15 +68,56 @@ Capture channel configuration
|
||||
|
||||
.. list::
|
||||
|
||||
- :cpp:member:`gpio_num <mcpwm_capture_channel_config_t::gpio_num>` — the GPIO carrying the input signal.
|
||||
- :cpp:member:`prescale <mcpwm_capture_channel_config_t::prescale>` — divides the input signal before capture; the effective input frequency is the capture clock divided by ``prescale``. Raise it to extend the measurable period range, at the cost of time resolution.
|
||||
- :cpp:member:`gpio_num <mcpwm_capture_channel_config_t::gpio_num>` — the GPIO carrying the input signal. The driver configures it as an input but does not enable any pull-up or pull-down; if the signal is not actively driven to both levels, call :cpp:func:`gpio_set_pull_mode()` so the pin idles at the level you expect.
|
||||
- :cpp:member:`prescale <mcpwm_capture_channel_config_t::prescale>` — input prescale ratio. Same-edge captures (same reported edge type) are spaced about ``prescale`` input periods apart (capture rate ≈ ``input_rate / prescale``). ``0`` or ``1`` means no prescaling (bypass); any other value must be even. Leaving the field at ``0`` (the C default) is therefore bypass. Raise it to extend the measurable period range, at the cost of time resolution. See :ref:`mcpwm-cap-input-prescale` for pipeline order and edge-mode behavior.
|
||||
- :cpp:member:`pos_edge <mcpwm_capture_channel_config_t::flags::pos_edge>` and :cpp:member:`neg_edge <mcpwm_capture_channel_config_t::flags::neg_edge>` — which edges are captured. The example captures both, which is what a pulse-width measurement needs.
|
||||
- :cpp:member:`invert_cap_signal <mcpwm_capture_channel_config_t::flags::invert_cap_signal>` — inverts the input signal before capture, so a logical ``1`` on the pin is seen as ``0`` by the capture peripheral and vice versa.
|
||||
- :cpp:member:`intr_priority <mcpwm_capture_channel_config_t::intr_priority>` — the interrupt priority used by the capture callbacks. Not setting it (``0``) lets the driver choose a low priority.
|
||||
|
||||
.. _mcpwm-cap-input-prescale:
|
||||
|
||||
Input prescale
|
||||
==============
|
||||
|
||||
The capture channel processes the input in a **fixed, serial** order; the two stages cannot be swapped:
|
||||
|
||||
1. **First** divide the GPIO waveform by ``prescale`` (``0``/``1`` means bypass);
|
||||
2. **Then** use ``pos_edge``/``neg_edge`` to decide which post-prescale events are reported to software.
|
||||
|
||||
In other words, hardware does **not** “pick GPIO edges by the configured polarity first, then divide those edges.” With ``prescale > 1``:
|
||||
|
||||
- The :cpp:member:`cap_edge <mcpwm_capture_event_data_t::cap_edge>` in the callback may not match the physical GPIO edge;
|
||||
- Adjacent opposite-edge gaps are **not pulse width**, and **the true duty cycle cannot be recovered**.
|
||||
|
||||
Always compute period or frequency from timestamps of the same reported edge type. See the figures below for per-mode timing.
|
||||
|
||||
.. note::
|
||||
|
||||
The capture driver configures the GPIO as an input but does not set any pull-up or pull-down resistor. If the input signal is not actively driven to both levels, call :cpp:func:`gpio_set_pull_mode()` to select the pull direction that keeps the pin at the level you expect when the line is idle.
|
||||
Keep ``prescale = 1`` (bypass) and capture both edges when measuring pulse width or duty cycle. Prefer raising ``prescale`` only for very fast inputs when you only need frequency or period, and capture a single edge type only.
|
||||
|
||||
The figures below show how ``prescale`` affects capture timing for rising-only, falling-only, and both-edge modes.
|
||||
|
||||
.. figure:: /../_static/mcpwm/capture_prescale_rising.svg
|
||||
:align: center
|
||||
:alt: Rising-edge only capture with prescale bypass and prescale 4.
|
||||
|
||||
Rising-edge only. With ``prescale = 1`` (bypass), every rising edge captures as ``R``. With ``prescale > 1``, the first capture is at cycle ``prescale / 2 - 1``, then every ``prescale``-th rising edge (the figure shows ``prescale = 4``: cycle 1, 5, …). Same-edge spacing is ``prescale`` input periods.
|
||||
|
||||
.. figure:: /../_static/mcpwm/capture_prescale_falling.svg
|
||||
:align: center
|
||||
:alt: Falling-edge only capture with prescale bypass and prescale 4.
|
||||
|
||||
Falling-edge only. With ``prescale = 1`` (bypass), every falling edge captures as ``F``. With ``prescale > 1``, GPIO falling edges do not produce captures; **events land on rising steps**. The first capture is at cycle ``prescale - 1``, then every ``prescale`` rising steps, while ``cap_edge`` still reports ``F`` (the figure shows ``prescale = 4``: cycle 3, 7, …).
|
||||
|
||||
.. figure:: /../_static/mcpwm/capture_prescale_both.svg
|
||||
:align: center
|
||||
:alt: Both-edge capture with prescale bypass and prescale 4.
|
||||
|
||||
Both edges. With ``prescale = 1`` (bypass), ``R``/``F`` match the physical pin edges. With ``prescale > 1``, captures fire on rising pin steps only (every ``prescale / 2`` periods). The first capture matches rising-only (cycle ``prescale / 2 - 1``) and reports ``R``, then ``R``/``F`` alternate; adjacent ``R``/``F`` spacing is not pulse width. Same-edge gaps remain about ``prescale`` periods. Always compute period or frequency from timestamps of the same reported edge type.
|
||||
|
||||
.. warning::
|
||||
|
||||
With ``prescale > 1``, edge polarity can disappear: reported ``R``/``F`` describe the post-prescale event type, not the physical GPIO edge. Falling-edge-only capture in particular can fire on rising pin steps while still reporting ``F``. Do not infer the pin transition from ``cap_edge``, and do not treat adjacent opposite-edge gaps as pulse width.
|
||||
|
||||
Capture event callbacks
|
||||
=======================
|
||||
|
||||
@@ -68,15 +68,56 @@ MCPWM 捕获:测量输入脉冲
|
||||
|
||||
.. list::
|
||||
|
||||
- :cpp:member:`gpio_num <mcpwm_capture_channel_config_t::gpio_num>` — 承载输入信号的 GPIO。
|
||||
- :cpp:member:`prescale <mcpwm_capture_channel_config_t::prescale>` — 捕获前对输入信号分频,有效输入频率为捕获时钟除以 ``prescale``。提高它可扩展可测周期范围,但会降低时间分辨率。
|
||||
- :cpp:member:`gpio_num <mcpwm_capture_channel_config_t::gpio_num>` — 承载输入信号的 GPIO。驱动会把它配成输入,但不会设置上拉或下拉;若信号并非主动驱动到两个电平,请调用 :cpp:func:`gpio_set_pull_mode()`,让引脚空闲时保持在期望电平。
|
||||
- :cpp:member:`prescale <mcpwm_capture_channel_config_t::prescale>` — 输入预分频比。同沿(相同上报边沿类型)两次捕获的间隔约为 ``prescale`` 个输入周期(捕获速率 ≈ ``输入速率 / prescale``)。``0`` 或 ``1`` 表示不分频(bypass);其它值必须为偶数。结构体里不写该字段时默认为 ``0``,即 bypass。提高它可扩展可测周期范围,但会降低时间分辨率。流水线顺序与各边沿模式下的行为见 :ref:`mcpwm-cap-input-prescale`。
|
||||
- :cpp:member:`pos_edge <mcpwm_capture_channel_config_t::flags::pos_edge>` 和 :cpp:member:`neg_edge <mcpwm_capture_channel_config_t::flags::neg_edge>` — 捕获哪些边沿。示例同时捕获两个边沿,这正是脉宽测量所需的。
|
||||
- :cpp:member:`invert_cap_signal <mcpwm_capture_channel_config_t::flags::invert_cap_signal>` — 捕获前反相输入信号,让引脚上的逻辑 ``1`` 在捕获外设看来是 ``0``,反之亦然。
|
||||
- :cpp:member:`intr_priority <mcpwm_capture_channel_config_t::intr_priority>` — 捕获回调使用的中断优先级。不设置(``0``)时由驱动选择较低优先级。
|
||||
|
||||
.. _mcpwm-cap-input-prescale:
|
||||
|
||||
输入预分频
|
||||
==========
|
||||
|
||||
捕获通道内部按**固定顺序**串行处理输入,两级不能对调:
|
||||
|
||||
1. 先用 ``prescale`` 对 GPIO 波形做预分频(``0``/``1`` 为 bypass);
|
||||
2. 再根据 ``pos_edge``/``neg_edge`` 决定哪些分频后的事件上报给软件。
|
||||
|
||||
也就是说,硬件不是“先按设定的边沿挑选 GPIO,再对选中的边沿分频”。因此 ``prescale > 1`` 时:
|
||||
|
||||
- 回调里的 :cpp:member:`cap_edge <mcpwm_capture_event_data_t::cap_edge>` 不一定等于 GPIO 的物理边沿;
|
||||
- 相邻异沿间隔**不是真实脉宽**,**无法还原真实占空比**。
|
||||
|
||||
请用相同上报类型(同沿)的时间戳计算周期或频率。各边沿模式下的具体时序见下方示意图。
|
||||
|
||||
.. note::
|
||||
|
||||
捕获驱动会把 GPIO 配置为输入,但不会设置任何上拉或下拉电阻。如果输入信号并非主动驱动到两个电平,请调用 :cpp:func:`gpio_set_pull_mode()` 选择上拉或下拉方向,让引脚空闲时保持在你期望的电平。
|
||||
测脉宽或占空比时保持 ``prescale = 1`` (bypass)并捕获双边沿。建议仅在输入过快、只需测量频率/周期时再提高 ``prescale``,且只捕获单边沿。
|
||||
|
||||
下图说明 ``prescale`` 在仅上升沿、仅下降沿和双边沿模式下如何影响捕获时机。
|
||||
|
||||
.. figure:: /../_static/mcpwm/capture_prescale_rising.svg
|
||||
:align: center
|
||||
:alt: 仅上升沿捕获:prescale bypass 与 prescale 4。
|
||||
|
||||
仅上升沿。``prescale = 1`` (bypass)时每个上升沿捕获为 ``R``。``prescale > 1`` 时,首次捕获在 cycle ``prescale / 2 - 1``,之后每隔 ``prescale`` 个上升沿一次(图中 ``prescale = 4``:cycle 1、5、…)。同沿间隔为 ``prescale`` 个输入周期。
|
||||
|
||||
.. figure:: /../_static/mcpwm/capture_prescale_falling.svg
|
||||
:align: center
|
||||
:alt: 仅下降沿捕获:prescale bypass 与 prescale 4。
|
||||
|
||||
仅下降沿。``prescale = 1`` (bypass)时每个下降沿捕获为 ``F``。``prescale > 1`` 时 GPIO 下降沿不产生捕获;**事件落在上升沿步骤上**。首次捕获在 cycle ``prescale - 1``,之后每隔 ``prescale`` 个上升沿一次,``cap_edge`` 仍报 ``F`` (图中 ``prescale = 4``:cycle 3、7、…)。
|
||||
|
||||
.. figure:: /../_static/mcpwm/capture_prescale_both.svg
|
||||
:align: center
|
||||
:alt: 双边沿捕获:prescale bypass 与 prescale 4。
|
||||
|
||||
双边沿。``prescale = 1`` (bypass)时 ``R``/``F`` 对应真实引脚边沿。``prescale > 1`` 时只在上升沿步骤触发(每隔 ``prescale / 2`` 个周期)。首次与仅上升沿相同(cycle ``prescale / 2 - 1``)且报 ``R``,随后 ``R``/``F`` 交替;相邻 ``R``/``F`` 间隔不是脉宽。同沿间隔仍约为 ``prescale`` 个周期。请用相同上报类型(同沿)的时间戳计算周期或频率。
|
||||
|
||||
.. warning::
|
||||
|
||||
``prescale > 1`` 时边沿极性可能“消失”:上报的 ``R``/``F`` 描述的是分频之后的事件类型,不是 GPIO 物理边沿。尤其是仅下降沿路径会出现“上升沿步骤却报 ``F``”——不要用它推断引脚真实跳变,也不要用相邻异沿去算脉宽。
|
||||
|
||||
捕获事件回调
|
||||
============
|
||||
|
||||
Reference in New Issue
Block a user