From f8e57ebe6c39ea42c80167a77621aef451e11f1d Mon Sep 17 00:00:00 2001 From: Teodor Lina Date: Fri, 12 Jan 2024 12:39:00 +0200 Subject: [PATCH] MPAE-17086 : implemented comments after technical review --- .main-meta/main.json | 2 +- .../BEMF_Acquisition_Demo.mc3 | 0 .../Makefile | 0 .../main.c | 0 .../mcc_generated_files/ac/ac0.h | 0 .../mcc_generated_files/ac/src/ac0.c | 0 .../mcc_generated_files/system/ccp.h | 0 .../mcc_generated_files/system/clock.h | 0 .../mcc_generated_files/system/config_bits.h | 0 .../mcc_generated_files/system/interrupt.h | 0 .../mcc_generated_files/system/pins.h | 0 .../mcc_generated_files/system/port.h | 0 .../mcc_generated_files/system/protected_io.h | 0 .../mcc_generated_files/system/src/clock.c | 0 .../system/src/config_bits.c | 0 .../system/src/interrupt.c | 0 .../mcc_generated_files/system/src/pins.c | 0 .../system/src/protected_io.S | 0 .../mcc_generated_files/system/src/system.c | 0 .../mcc_generated_files/system/system.h | 0 .../system/utils/assembler.h | 0 .../system/utils/assembler/gas.h | 0 .../system/utils/assembler/iar.h | 0 .../mcc_generated_files/system/utils/atomic.h | 0 .../system/utils/compiler.h | 0 .../system/utils/interrupt_avr8.h | 0 .../mcc_generated_files/system/utils/utils.h | 0 .../system/utils/utils_assert.h | 0 .../mcc_generated_files/timer/src/tce0.c | 0 .../mcc_generated_files/timer/src/wex0.c | 0 .../mcc_generated_files/timer/tce0.h | 0 .../mcc_generated_files/timer/wex0.h | 0 .../nbproject/configurations.xml | 0 .../nbproject/project.xml | 0 BEMF_Acquisition_Demo/README.md | 345 ------------------ README.md | 319 +++++++++++++++- 36 files changed, 315 insertions(+), 351 deletions(-) rename {BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X => BEMF_Acquisition_Demo.X}/BEMF_Acquisition_Demo.mc3 (100%) rename {BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X => BEMF_Acquisition_Demo.X}/Makefile (100%) rename {BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X => BEMF_Acquisition_Demo.X}/main.c (100%) rename {BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X => BEMF_Acquisition_Demo.X}/mcc_generated_files/ac/ac0.h (100%) rename {BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X => BEMF_Acquisition_Demo.X}/mcc_generated_files/ac/src/ac0.c (100%) rename {BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X => BEMF_Acquisition_Demo.X}/mcc_generated_files/system/ccp.h (100%) rename {BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X => BEMF_Acquisition_Demo.X}/mcc_generated_files/system/clock.h (100%) rename {BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X => BEMF_Acquisition_Demo.X}/mcc_generated_files/system/config_bits.h (100%) rename {BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X => BEMF_Acquisition_Demo.X}/mcc_generated_files/system/interrupt.h (100%) rename {BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X => BEMF_Acquisition_Demo.X}/mcc_generated_files/system/pins.h (100%) rename {BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X => BEMF_Acquisition_Demo.X}/mcc_generated_files/system/port.h (100%) rename {BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X => BEMF_Acquisition_Demo.X}/mcc_generated_files/system/protected_io.h (100%) rename {BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X => BEMF_Acquisition_Demo.X}/mcc_generated_files/system/src/clock.c (100%) rename {BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X => BEMF_Acquisition_Demo.X}/mcc_generated_files/system/src/config_bits.c (100%) rename {BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X => BEMF_Acquisition_Demo.X}/mcc_generated_files/system/src/interrupt.c (100%) rename {BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X => BEMF_Acquisition_Demo.X}/mcc_generated_files/system/src/pins.c (100%) rename {BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X => BEMF_Acquisition_Demo.X}/mcc_generated_files/system/src/protected_io.S (100%) rename {BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X => BEMF_Acquisition_Demo.X}/mcc_generated_files/system/src/system.c (100%) rename {BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X => BEMF_Acquisition_Demo.X}/mcc_generated_files/system/system.h (100%) rename {BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X => BEMF_Acquisition_Demo.X}/mcc_generated_files/system/utils/assembler.h (100%) rename {BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X => BEMF_Acquisition_Demo.X}/mcc_generated_files/system/utils/assembler/gas.h (100%) rename {BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X => BEMF_Acquisition_Demo.X}/mcc_generated_files/system/utils/assembler/iar.h (100%) rename {BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X => BEMF_Acquisition_Demo.X}/mcc_generated_files/system/utils/atomic.h (100%) rename {BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X => BEMF_Acquisition_Demo.X}/mcc_generated_files/system/utils/compiler.h (100%) rename {BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X => BEMF_Acquisition_Demo.X}/mcc_generated_files/system/utils/interrupt_avr8.h (100%) rename {BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X => BEMF_Acquisition_Demo.X}/mcc_generated_files/system/utils/utils.h (100%) rename {BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X => BEMF_Acquisition_Demo.X}/mcc_generated_files/system/utils/utils_assert.h (100%) rename {BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X => BEMF_Acquisition_Demo.X}/mcc_generated_files/timer/src/tce0.c (100%) rename {BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X => BEMF_Acquisition_Demo.X}/mcc_generated_files/timer/src/wex0.c (100%) rename {BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X => BEMF_Acquisition_Demo.X}/mcc_generated_files/timer/tce0.h (100%) rename {BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X => BEMF_Acquisition_Demo.X}/mcc_generated_files/timer/wex0.h (100%) rename {BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X => BEMF_Acquisition_Demo.X}/nbproject/configurations.xml (100%) rename {BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X => BEMF_Acquisition_Demo.X}/nbproject/project.xml (100%) delete mode 100644 BEMF_Acquisition_Demo/README.md diff --git a/.main-meta/main.json b/.main-meta/main.json index 97a097c..843117a 100644 --- a/.main-meta/main.json +++ b/.main-meta/main.json @@ -7,7 +7,7 @@ "version": "1.0.0", "displayName": "BEMF Acquisition During Dead Time", "projectName": "avr16eb32-bemf-acquisition-demo-during-dead-time-mplab-mcc", - "shortDescription": "This repository contains an example of MCC Melody generated source code for the TCE and WEX peripherals of the AVR EB family of devices.", + "shortDescription": "This repository contains an example of MCC Melody generated source code for the TCE and WEX peripherals of the AVR EB family of devices. This use case shows a new method to detect and measure Back Electromotive Force (BEMF) in a Motor Control application for Brushless Direct Current Motors (BLDC) or Permanent Magnet Synchronous Motors (PMSM), that are driven with a Sinusoidal Drive.", "ide": { "name": "MPLAB X", "semverRange": ">=6.15.0" diff --git a/BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/BEMF_Acquisition_Demo.mc3 b/BEMF_Acquisition_Demo.X/BEMF_Acquisition_Demo.mc3 similarity index 100% rename from BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/BEMF_Acquisition_Demo.mc3 rename to BEMF_Acquisition_Demo.X/BEMF_Acquisition_Demo.mc3 diff --git a/BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/Makefile b/BEMF_Acquisition_Demo.X/Makefile similarity index 100% rename from BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/Makefile rename to BEMF_Acquisition_Demo.X/Makefile diff --git a/BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/main.c b/BEMF_Acquisition_Demo.X/main.c similarity index 100% rename from BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/main.c rename to BEMF_Acquisition_Demo.X/main.c diff --git a/BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/mcc_generated_files/ac/ac0.h b/BEMF_Acquisition_Demo.X/mcc_generated_files/ac/ac0.h similarity index 100% rename from BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/mcc_generated_files/ac/ac0.h rename to BEMF_Acquisition_Demo.X/mcc_generated_files/ac/ac0.h diff --git a/BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/mcc_generated_files/ac/src/ac0.c b/BEMF_Acquisition_Demo.X/mcc_generated_files/ac/src/ac0.c similarity index 100% rename from BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/mcc_generated_files/ac/src/ac0.c rename to BEMF_Acquisition_Demo.X/mcc_generated_files/ac/src/ac0.c diff --git a/BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/mcc_generated_files/system/ccp.h b/BEMF_Acquisition_Demo.X/mcc_generated_files/system/ccp.h similarity index 100% rename from BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/mcc_generated_files/system/ccp.h rename to BEMF_Acquisition_Demo.X/mcc_generated_files/system/ccp.h diff --git a/BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/mcc_generated_files/system/clock.h b/BEMF_Acquisition_Demo.X/mcc_generated_files/system/clock.h similarity index 100% rename from BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/mcc_generated_files/system/clock.h rename to BEMF_Acquisition_Demo.X/mcc_generated_files/system/clock.h diff --git a/BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/mcc_generated_files/system/config_bits.h b/BEMF_Acquisition_Demo.X/mcc_generated_files/system/config_bits.h similarity index 100% rename from BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/mcc_generated_files/system/config_bits.h rename to BEMF_Acquisition_Demo.X/mcc_generated_files/system/config_bits.h diff --git a/BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/mcc_generated_files/system/interrupt.h b/BEMF_Acquisition_Demo.X/mcc_generated_files/system/interrupt.h similarity index 100% rename from BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/mcc_generated_files/system/interrupt.h rename to BEMF_Acquisition_Demo.X/mcc_generated_files/system/interrupt.h diff --git a/BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/mcc_generated_files/system/pins.h b/BEMF_Acquisition_Demo.X/mcc_generated_files/system/pins.h similarity index 100% rename from BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/mcc_generated_files/system/pins.h rename to BEMF_Acquisition_Demo.X/mcc_generated_files/system/pins.h diff --git a/BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/mcc_generated_files/system/port.h b/BEMF_Acquisition_Demo.X/mcc_generated_files/system/port.h similarity index 100% rename from BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/mcc_generated_files/system/port.h rename to BEMF_Acquisition_Demo.X/mcc_generated_files/system/port.h diff --git a/BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/mcc_generated_files/system/protected_io.h b/BEMF_Acquisition_Demo.X/mcc_generated_files/system/protected_io.h similarity index 100% rename from BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/mcc_generated_files/system/protected_io.h rename to BEMF_Acquisition_Demo.X/mcc_generated_files/system/protected_io.h diff --git a/BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/mcc_generated_files/system/src/clock.c b/BEMF_Acquisition_Demo.X/mcc_generated_files/system/src/clock.c similarity index 100% rename from BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/mcc_generated_files/system/src/clock.c rename to BEMF_Acquisition_Demo.X/mcc_generated_files/system/src/clock.c diff --git a/BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/mcc_generated_files/system/src/config_bits.c b/BEMF_Acquisition_Demo.X/mcc_generated_files/system/src/config_bits.c similarity index 100% rename from BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/mcc_generated_files/system/src/config_bits.c rename to BEMF_Acquisition_Demo.X/mcc_generated_files/system/src/config_bits.c diff --git a/BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/mcc_generated_files/system/src/interrupt.c b/BEMF_Acquisition_Demo.X/mcc_generated_files/system/src/interrupt.c similarity index 100% rename from BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/mcc_generated_files/system/src/interrupt.c rename to BEMF_Acquisition_Demo.X/mcc_generated_files/system/src/interrupt.c diff --git a/BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/mcc_generated_files/system/src/pins.c b/BEMF_Acquisition_Demo.X/mcc_generated_files/system/src/pins.c similarity index 100% rename from BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/mcc_generated_files/system/src/pins.c rename to BEMF_Acquisition_Demo.X/mcc_generated_files/system/src/pins.c diff --git a/BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/mcc_generated_files/system/src/protected_io.S b/BEMF_Acquisition_Demo.X/mcc_generated_files/system/src/protected_io.S similarity index 100% rename from BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/mcc_generated_files/system/src/protected_io.S rename to BEMF_Acquisition_Demo.X/mcc_generated_files/system/src/protected_io.S diff --git a/BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/mcc_generated_files/system/src/system.c b/BEMF_Acquisition_Demo.X/mcc_generated_files/system/src/system.c similarity index 100% rename from BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/mcc_generated_files/system/src/system.c rename to BEMF_Acquisition_Demo.X/mcc_generated_files/system/src/system.c diff --git a/BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/mcc_generated_files/system/system.h b/BEMF_Acquisition_Demo.X/mcc_generated_files/system/system.h similarity index 100% rename from BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/mcc_generated_files/system/system.h rename to BEMF_Acquisition_Demo.X/mcc_generated_files/system/system.h diff --git a/BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/mcc_generated_files/system/utils/assembler.h b/BEMF_Acquisition_Demo.X/mcc_generated_files/system/utils/assembler.h similarity index 100% rename from BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/mcc_generated_files/system/utils/assembler.h rename to BEMF_Acquisition_Demo.X/mcc_generated_files/system/utils/assembler.h diff --git a/BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/mcc_generated_files/system/utils/assembler/gas.h b/BEMF_Acquisition_Demo.X/mcc_generated_files/system/utils/assembler/gas.h similarity index 100% rename from BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/mcc_generated_files/system/utils/assembler/gas.h rename to BEMF_Acquisition_Demo.X/mcc_generated_files/system/utils/assembler/gas.h diff --git a/BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/mcc_generated_files/system/utils/assembler/iar.h b/BEMF_Acquisition_Demo.X/mcc_generated_files/system/utils/assembler/iar.h similarity index 100% rename from BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/mcc_generated_files/system/utils/assembler/iar.h rename to BEMF_Acquisition_Demo.X/mcc_generated_files/system/utils/assembler/iar.h diff --git a/BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/mcc_generated_files/system/utils/atomic.h b/BEMF_Acquisition_Demo.X/mcc_generated_files/system/utils/atomic.h similarity index 100% rename from BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/mcc_generated_files/system/utils/atomic.h rename to BEMF_Acquisition_Demo.X/mcc_generated_files/system/utils/atomic.h diff --git a/BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/mcc_generated_files/system/utils/compiler.h b/BEMF_Acquisition_Demo.X/mcc_generated_files/system/utils/compiler.h similarity index 100% rename from BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/mcc_generated_files/system/utils/compiler.h rename to BEMF_Acquisition_Demo.X/mcc_generated_files/system/utils/compiler.h diff --git a/BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/mcc_generated_files/system/utils/interrupt_avr8.h b/BEMF_Acquisition_Demo.X/mcc_generated_files/system/utils/interrupt_avr8.h similarity index 100% rename from BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/mcc_generated_files/system/utils/interrupt_avr8.h rename to BEMF_Acquisition_Demo.X/mcc_generated_files/system/utils/interrupt_avr8.h diff --git a/BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/mcc_generated_files/system/utils/utils.h b/BEMF_Acquisition_Demo.X/mcc_generated_files/system/utils/utils.h similarity index 100% rename from BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/mcc_generated_files/system/utils/utils.h rename to BEMF_Acquisition_Demo.X/mcc_generated_files/system/utils/utils.h diff --git a/BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/mcc_generated_files/system/utils/utils_assert.h b/BEMF_Acquisition_Demo.X/mcc_generated_files/system/utils/utils_assert.h similarity index 100% rename from BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/mcc_generated_files/system/utils/utils_assert.h rename to BEMF_Acquisition_Demo.X/mcc_generated_files/system/utils/utils_assert.h diff --git a/BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/mcc_generated_files/timer/src/tce0.c b/BEMF_Acquisition_Demo.X/mcc_generated_files/timer/src/tce0.c similarity index 100% rename from BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/mcc_generated_files/timer/src/tce0.c rename to BEMF_Acquisition_Demo.X/mcc_generated_files/timer/src/tce0.c diff --git a/BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/mcc_generated_files/timer/src/wex0.c b/BEMF_Acquisition_Demo.X/mcc_generated_files/timer/src/wex0.c similarity index 100% rename from BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/mcc_generated_files/timer/src/wex0.c rename to BEMF_Acquisition_Demo.X/mcc_generated_files/timer/src/wex0.c diff --git a/BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/mcc_generated_files/timer/tce0.h b/BEMF_Acquisition_Demo.X/mcc_generated_files/timer/tce0.h similarity index 100% rename from BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/mcc_generated_files/timer/tce0.h rename to BEMF_Acquisition_Demo.X/mcc_generated_files/timer/tce0.h diff --git a/BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/mcc_generated_files/timer/wex0.h b/BEMF_Acquisition_Demo.X/mcc_generated_files/timer/wex0.h similarity index 100% rename from BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/mcc_generated_files/timer/wex0.h rename to BEMF_Acquisition_Demo.X/mcc_generated_files/timer/wex0.h diff --git a/BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/nbproject/configurations.xml b/BEMF_Acquisition_Demo.X/nbproject/configurations.xml similarity index 100% rename from BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/nbproject/configurations.xml rename to BEMF_Acquisition_Demo.X/nbproject/configurations.xml diff --git a/BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/nbproject/project.xml b/BEMF_Acquisition_Demo.X/nbproject/project.xml similarity index 100% rename from BEMF_Acquisition_Demo/BEMF_Acquisition_Demo.X/nbproject/project.xml rename to BEMF_Acquisition_Demo.X/nbproject/project.xml diff --git a/BEMF_Acquisition_Demo/README.md b/BEMF_Acquisition_Demo/README.md deleted file mode 100644 index eebc41d..0000000 --- a/BEMF_Acquisition_Demo/README.md +++ /dev/null @@ -1,345 +0,0 @@ -[![MCHP](../images/microchip.png)](https://www.microchip.com) - -## BEMF Acquisition Demo - -This example shows how to set a Timer/Counter type E (TCE) and a Waveform Extension (WEX) instance to generate six complementary Pulse-Width Modulation (PWM) signals to spin a 3-phase Brushless Direct Current Motor (BLDC) or a Permanent Magnet Synchronous Motor (PMSM) with a Sinusoidal Drive. This example also configures the Analog Comparator (AC) peripheral to measure directly the Back Electromotive Force (BEMF), when the motor is spinning. The measurement window is one of the two dead time periods during a PWM cycle. This dead time period is increased to 2 µs to have a big enough acquisition window to detect clean BEMF, that is not influenced by the PWM driving signals. The other dead time period is kept at 500 ns. A full PWM cycle has 50 µs (which is the classic 20 KHz frequency of MOSFET switching, used in Motor Control applications). The motor is spinning using forced commutation in this example without any sort of synchronization or Closed Loop algorithms. This code example just highlights the new BEMF measurement method during dead time. The motor is spinning at a constant speed and at a constant amplitude that are not modified at run time, because it is not the scope of this application. - -## Related Documentation - -More details and code examples on the AVR16EB32 can be found at the following links: - -- [AVR® EB Product Page](https://www.microchip.com/en-us/product/AVR16EB32) -- [AVR® EB Code Examples on GitHub](https://github.com/microchip-pic-avr-examples?q=AVR16EB32) - -## Software Used - -- [MPLAB® X IDE v6.15 or newer](https://www.microchip.com/en-us/tools-resources/develop/mplab-x-ide) -- [AVR-Ex DFP-2.8.189 or newer Device Pack](https://packs.download.microchip.com/) -- [MPLAB® XC8 compiler v2.45](https://www.microchip.com/en-us/tools-resources/develop/mplab-xc-compilers/downloads-documentation#XC8) -- [MPLAB® Code Configurator (MCC) v 5.3.7](https://www.microchip.com/en-us/tools-resources/configure/mplab-code-configurator) -- [MPLAB® Code Configurator (MCC) Melody Core v 2.6.3 or newer](https://www.microchip.com/en-us/tools-resources/configure/mplab-code-configurator) - -## Hardware Used - -- [AVR® EB Curiosity Nano](https://www.microchip.com/en-us/product/AVR16EB32) -- [Multi-Phase Power Board (MPPB)](www.microchip.com/en-us/development-tool/EV35Z86A) -- [AVR-EB Curiosity Nano Adaptor to MPPB](www.microchip.com/en-us/development-tool/EV88N31A) -- Motor (Suggestion: [Mikroe BLDC Motor with Hall sensor](https://www.mikroe.com/motor-bldc-42blf01-with-hall-sensor)) -- A Voltage Power Supply (24-36V and 1-3A is enough) - -## Setup - -The AVR16EB32 Curiosity Nano Development Board is used along with the MPPB, AVR-EB Cnano to MPPB Adaptor Board, the BLDC Motor and a Voltage Power Supply. - -
- -## Functionality - -
The peripheral clock, output port pins, TCE, WEX and AC are initialized and configured using the MPLAB X Code Configurator. At run-time, the driving sinewave signals are generated using a Lookup Table (LUT). The LUT is scrolled using three 16-bit counters, one for each phase. The drive is updated at every PWM cycle, once every 50 µs. The counters start from different values to ensure the 120 electrical degrees phase shift for the three phases. The BEMF is read once per PWM cycle as well. The counters increment is the actual motor's speed (LUT scrolling speed). The frequency of the sinewave signals is modified by increasing or decreasing the LUT scrolling speed. The amplitude of the sinewave signals is modified using TCE's hardware scaling accelerator. - -
At run-time the ```BEMF_Read()``` function is called in an Interrupt Service Routine (ISR). The ```BEMF_Read()``` function is registered as a callback on the TCE's CMP3 vector ISR. This function gets the output from the AC and sets an IO to high `1` logic if the value is one. If the value from the AC output is zero the IO is set to `0`, low logic. Every phase of the motor has an IO to show the sampled BEMF for the respective phase. PF1, PF2 and PF3 pins are used to show the sampled BEMF for the three phases of the motor. PF4 pin is used to mark the sampling moment of the BEMF during the long dead time. The AC has on the negative input the hardware reconstructed neutral phase of the motor. The AC has on the positive input the three phases of the motor, each one at a time, using a Multiplexor (MUX). The AC MUX is switched at every PWM cycle (whenever a new ISR occurs) to monitor a different phase. This means that each phase of the motor is monitored every 150 µs. The AC monitors phase A for 50 µs, switches to phase B for another 50 µs, and then to phase C for another 50 µs. After that, the process repeats itself over and over again. Another approach is to monitor one phase until a Zero-Cross of BEMF is detected, then switch to monitor another phase and so on. The second approach reduces the Zero-Cross Detection delay. - -## Function Called in Interrupt Service Routine - -```c -void BEMF_Read(void) -{ - bool bemf_state; - static mux_t mux = MUX_PHASE_A; - - /* BEMF sampling point marked by an IO toggling */ - IO_PF4_SetHigh(); - bemf_state = ((AC0.STATUS & AC_CMPSTATE_bm) != 0 ); - IO_PF4_SetLow(); - - /* Switching AC0 MUX from one phase to another one */ - switch(mux) - { - case MUX_PHASE_A: if(bemf_state) {IO_PF1_SetHigh();} else {IO_PF1_SetLow();} mux = MUX_PHASE_B; break; - case MUX_PHASE_B: if(bemf_state) {IO_PF2_SetHigh();} else {IO_PF2_SetLow();} mux = MUX_PHASE_C; break; - case MUX_PHASE_C: if(bemf_state) {IO_PF3_SetHigh();} else {IO_PF3_SetLow();} mux = MUX_PHASE_A; break; - default: mux = MUX_PHASE_A; break; - } - - /* Update Analog Comparator MUX to monitor another phase of the motor */ - Mux_Set(mux); - - /* Update drive to keep the motor spinning */ - Motor_Drive(); -} -``` - -## Analog Comparator MUX Setup - -
- -## Application Flowchart - -
- -
To generate this project using MPLAB X IDE and the MPLAB X Code Configurator (MCC Melody, MCC Clasic is not supported on this device), follow the next steps: - -
1. Open MPLAB X IDE and create a new project for the AVR16EB32 device. - -
2. Open MCC from the toolbar (more information on how to install the MCC plug-in can be found [here](https://onlinedocs.microchip.com/pr/GUID-1F7007B8-9A46-4D03-AEED-650357BA760D-en-US-6/index.html?GUID-D98198EA-93B9-45D2-9D96-C97DBCA55267)). - -
3. From the **MCC Content Manager** tab click the **Select MCC Melody** button and then click **Finish**.
-
-
- -
4. Click _Project>Resources>System>CLKCTRL_, then do the following configuration: -
-
- Disable the Prescaler enable button -
- -
5. To add the TCE module, go to _Device Resources>Drivers>Timer>TCE0_, then do the following configuration: -
-
- Module Enable: Must be enabled by default, if not just toggle the button (it turns blue if enabled) -
- Clock Selection: System clock (by default the divider must be 1 - System clock) -
- Counter Direction: UP -
- Waveform Generation Mode: Single-Slope PWM mode with overflow on TOP -
- Requested Period [s]: 0.00005 -
- Duty Cycle 0 [%]: 0 -
- Duty Cycle 1 [%]: 0 -
- Duty Cycle 2 [%]: 0 -
- Duty Cycle 3 [%]: 98.5 -
- Waveform Output n: Check the boxes from the Enable column for Waveform Output 0, 1, 2, 3 -
- Scale mode: CMP values are scaled from Center, 50% DC (duty cycle) -
- Scaled Writing to registers: Normal -
- Amplitude Control Enable: Toggle the button (it turns blue if enabled) -
- Amplitude Value: 0.1 -
- Generate ISR: Toggle the button (it turns blue if enabled) -
- Compare 3 Interrupt Enable: Toggle the button (it turns blue if enabled) -
- -
6. To add the WEX module, go to _Device Resources>Drivers>WEX>WEX0_, then do the following configuration: -
-
- Input Matrix: Direct -
- Update Source: TCE (the update condition for the output signals will be dictated by TCE) -
- Override Settings: Check all the boxes from the Output Enable column for the Waveform Output [0-5] -
- Dead-time Insertion Channel 0 Enable: Toggle the button (it turns blue if enabled) -
- Dead-time Insertion Channel 1 Enable: Toggle the button (it turns blue if enabled) -
- Dead-time Insertion Channel 2 Enable: Toggle the button (it turns blue if enabled) -
- Requested Dead-time Low Side (μs) : 2 -
- Requested Dead-time High Side (μs) : 0.5 -
- -
7. To add the AC module, go to _Device Resources>Drivers>AC>AC0_, then do the following configuration: -
-
- Enable: Toggle the button (it turns blue if enabled) -
- Positive Input MUX Selection: Positive Pin 5 -
- Negative Input MUX Selection: Negative Pin 1 -
- Output Pad Enable: Toggle the button (it turns blue if enabled) -
- -
8. In the **Pin Grid View** tab check if the WEX_WO [0-5] pins are locked as outputs on PORTA. When the boxes from the Enable column in the Output Settings of WEX are checked, the pins are also locked. To change the PORT simply click a pin from another PORT in **Pin Grid View**. Check if PA7 pin is set as AC output. Check if PD4 and PD0 pins are set as inputs for AC. Also, another two pins are needed as inputs for AC for the other two phases of the motor. Click PD5 and PD6 and set them as inputs from _Pins -> GPIO_. Last, the pins that show the sampled BEMF and the sampling moment must be set as outputs from _Pins>GPIO_. These pins are PF1, PF2, PF3 and PF4. - - | Pin | Configuration | - | :---------------------: | :----------------: | - | PA0 | TCE and WEX WO0 | - | PA1 | TCE and WEX WO1 | - | PA2 | TCE and WEX WO2 | - | PA3 | TCE and WEX WO3 | - | PA4 | TCE and WEX WO4 | - | PA5 | TCE and WEX WO5 | - | PA7 | AC output | - | PD0 | AC negative input 1 | - | PD4 | AC positive input 5 | - | PD5 | AC positive input 6 | - | PD6 | AC positive input 3 | - | PF1 | Digital output | - | PF2 | Digital output | - | PF3 | Digital output | - | PF4 | Digital output | - -
- -
Go to _Project Resources>System>Pins_. Select the Digital Input Buffer disabled option for PD5 and PD6 pins. -
- -
9. In the **Project Resources** tab, click the **Generate** button so that MCC will generate all the specified drivers and configurations. -
-
-
-
- -
10. After MCC Melody generates the project files with the configuration explained above, overwrite the content from the ```main.c``` file with this: - -```c -/* Number of pole pairs of a BLDC motor */ -#define MOTOR_PAIR_POLES 4 - -/* MOSFET switching frequency in Hz */ -#define F_SAMPLING 20000.0 - -/* uint16_t range mapping: 0 - 359.99 electrical degrees -> 0 - 65535 */ -#define DEGREES_TO_U16(DEG) (uint16_t)( (float)(DEG) * 65536.0 / 360.0 + 0.5) - -/* Speed conversion from RPM to LUT scrolling speed */ -#define RPM_TO_U16(RPM) (uint16_t)(((float)(RPM) * 65536.0 * (float)(MOTOR_PAIR_POLES)) / ((float)(F_SAMPLING) * 60.0) + 0.5) - -/* Sets the amplitude of the sine wave signals, and thus the scaling values of duty cycle in U.Q.1.15 format, ranging from 0 to 1.00 - * Duty cycle scaling is done in hardware using the hardware accelerator of TCE */ -#define AMP_TO_U16(X) (uint16_t)(32768.0*(X) + 0.5) - -/* Speed of the motor - 120 RPM */ -#define SPEED RPM_TO_U16(120) - -/* Amplitude of the sine wave - 10% */ -#define AMPLITUDE AMP_TO_U16(0.1) - - -#include "mcc_generated_files/system/system.h" - -typedef enum -{ - MUX_PHASE_A = (AC_MUXPOS_AINP5_gc | AC_MUXNEG_AINN1_gc), - MUX_PHASE_B = (AC_MUXPOS_AINP6_gc | AC_MUXNEG_AINN1_gc), - MUX_PHASE_C = (AC_MUXPOS_AINP3_gc | AC_MUXNEG_AINN1_gc), -} mux_t; - -/* LUT that is used to generate a sinusoidal drive */ -static const uint16_t sine_lookup_table[] = -{ - 16384, 16786, 17187, 17589, 17989, 18389, 18788, 19185, 19580, 19973, 20364, - 20753, 21140, 21523, 21903, 22280, 22653, 23023, 23389, 23750, 24107, 24459, 24807, - 25149, 25486, 25818, 26143, 26463, 26777, 27085, 27386, 27681, 27969, 28250, 28523, - 28790, 29049, 29300, 29543, 29779, 30006, 30226, 30437, 30639, 30833, 31018, 31194, - 31362, 31520, 31670, 31810, 31941, 32062, 32174, 32276, 32369, 32453, 32526, 32590, - 32644, 32689, 32723, 32748, 32763, 32768, 32763, 32748, 32723, 32689, 32644, 32590, - 32526, 32453, 32369, 32276, 32174, 32062, 31941, 31810, 31670, 31520, 31362, 31194, - 31018, 30833, 30639, 30437, 30226, 30006, 29779, 29543, 29300, 29049, 28790, 28523, - 28250, 27969, 27681, 27386, 27085, 26777, 26463, 26143, 25818, 25486, 25149, 24807, - 24459, 24107, 23750, 23389, 23023, 22653, 22280, 21903, 21523, 21140, 20753, 20364, - 19973, 19580, 19185, 18788, 18389, 17989, 17589, 17187, 16786, 16384, 15981, 15580, - 15178, 14778, 14378, 13979, 13582, 13187, 12794, 12403, 12014, 11627, 11244, 10864, - 10487, 10114, 9744, 9378, 9017, 8660, 8308, 7960, 7618, 7281, 6949, 6624, 6304, 5990, - 5682, 5381, 5086, 4798, 4517, 4244, 3977, 3718, 3467, 3224, 2988, 2761, 2541, 2330, - 2128, 1934, 1749, 1573, 1405, 1247, 1097, 957, 826, 705, 593, 491, 398, 314, 241, - 177, 123, 78, 44, 19, 4, 0, 4, 19, 44, 78, 123, 177, 241, 314, 398, 491, 593, 705, - 826, 957, 1097, 1247, 1405, 1573, 1749, 1934, 2128, 2330, 2541, 2761, 2988, 3224, - 3467, 3718, 3977, 4244, 4517, 4798, 5086, 5381, 5682, 5990, 6304, 6624, 6949, 7281, - 7618, 7960, 8308, 8660, 9017, 9378, 9744, 10114, 10487, 10864, 11244, 11627, 12014, - 12403, 12794, 13187, 13582, 13979, 14378, 14778, 15178, 15580, 15981 -}; - -/* Function that is called every 50 μs to update the drive */ -void Motor_Drive(void) -{ -/* Counters that scroll through the LUT at run-time. These counter are used to create the 120 degrees - * phase shift between each of the motor's phases */ - static uint16_t phase_a = DEGREES_TO_U16(0.0); - static uint16_t phase_b = DEGREES_TO_U16(120.0); - static uint16_t phase_c = DEGREES_TO_U16(240.0); - static const uint16_t speed = SPEED; - - /* Values that will be written in the CMP channels of TCE */ - uint16_t drive_a, drive_b, drive_c; - - /* Updating the counters */ - phase_a += speed; - phase_b += speed; - phase_c += speed; - - /* Select new variables from the LUT for each CMP channel */ - drive_a = sine_lookup_table[(phase_a >> 8)]; - drive_b = sine_lookup_table[(phase_b >> 8)]; - drive_c = sine_lookup_table[(phase_c >> 8)]; - - /* Update the values from CMP channels with new ones */ - TCE0_CompareChannels012BufferedSet(drive_a, drive_b, drive_c); -} - -/* Functions that switches the MUX to monitor all three phases at run-time */ -void Mux_Set(uint8_t mode) -{ - uint8_t temp; - temp = AC0.MUXCTRL; - temp &= ~(AC_MUXPOS_gm | AC_MUXNEG_gm); - temp |= mode; - AC0.MUXCTRL = temp; -} - -/* Function that is called during the enlarged dead time to read the BEMF state */ -void BEMF_Read(void) -{ - bool bemf_state; - static mux_t mux = MUX_PHASE_A; - - /* BEMF sampling point marked by an IO toggling */ - IO_PF4_SetHigh(); - bemf_state = ((AC0.STATUS & AC_CMPSTATE_bm) != 0 ); - IO_PF4_SetLow(); - - /* Switching AC0 MUX from one phase to another one */ - switch(mux) - { - case MUX_PHASE_A: if(bemf_state) {IO_PF1_SetHigh();} else {IO_PF1_SetLow();} mux = MUX_PHASE_B; break; - case MUX_PHASE_B: if(bemf_state) {IO_PF2_SetHigh();} else {IO_PF2_SetLow();} mux = MUX_PHASE_C; break; - case MUX_PHASE_C: if(bemf_state) {IO_PF3_SetHigh();} else {IO_PF3_SetLow();} mux = MUX_PHASE_A; break; - default: mux = MUX_PHASE_A; break; - } - - /* Update Analog Comparator MUX to monitor another phase of the motor */ - Mux_Set(mux); - - /* Update drive to keep the motor spinning */ - Motor_Drive(); -} - -int main(void) -{ - SYSTEM_Initialize(); - - /* Register the BEMF sampling function as a callback */ - TCE0_Compare3CallbackRegister(BEMF_Read); - - /* Enable hardware scaling accelerator after initialization to avoid messing up - * the timing for reading BEMF with CMP3 channel of TCE */ - TCE0_ScaleEnable(true); - - /* Set the Amplitude level */ - TCE0_AmplitudeSet(AMPLITUDE); - - while(1) - { - } -} -``` - -
11. Now the project can be built and run from MPLAB X IDE. At run time, while the motor is spinning, the BEMF from each phase of the motor is sampled with the AC and displayed using some output GPIO pins. It can be observed that the measured BEMF follows the Sinusoidal Drive signals of the motor's phases. - - ## Operation - - 1. Connect the board to the PC. - - 2. Open the ```BEMF_Acquisition_Demo.X``` or solution in MPLAB X IDE. - - 3. Right click the project and select Set as main project. - -
- - 4. Build the ```BEMF_Acquisition_Demo.X``` project by clicking **Clean and Build Project**. - -
- - 5. Click **Make and Program Device** to program the project to the board. - -
- -## Results - -Below are some logic analyzer captures, to help understand how the six PWM signals that generate the 3-phases sinusoidal drive look, and how the sampled BEMF follows the drive signals: - -
Sampling point of BEMF during dead time: -
- -
Sampled BEMF for one phase of the motor: -
- -
All three phases of the motor with their sampled BEMF signals. In this capture the phase signals are filtered with a hardware low pass filter to observe the sinusoidal drive: -
- -## Summary - -This project demonstrates how to use the TCE and WEX to generate PWM signals in Single-Ramp mode to drive a 3-phase BLDC or PMSM motor. Additionally, it shows how to measure BEMF during the dead-time period using the AC. This BEMF detection method cannot be used for applications with high dynamic load changes because the response is not fast enough. For this method to detect BEMF as clean as possible, the motor must spin at a minimum RPM speed of usually around 10-20% of the nominal speed of the motor. \ No newline at end of file diff --git a/README.md b/README.md index b4fb755..5004702 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,8 @@ [![MCHP](images/microchip.png)](https://www.microchip.com) -# BEMF Acquisition During Dead Time +## BEMF Acquisition During Dead Time -This repository contains an example of MPLAB® Code Configurator (MCC) Melody generated source code for the Timer/Counter Type E (TCE), Waveform Extension (WEX) and Analog Comparator (AC) peripherals of the AVR® EB family of devices. This document provides a description of an application, including an explanation of its functionality. - -* [BEMF Acquisition Demo:](BEMF_Acquisition_Demo) This use case shows a new method to detect and measure Back Electromotive Force (BEMF) in a Motor Control application for Brushless Direct Current Motors (BLDC) or Permanent Magnet Synchronous Motors (PMSM), that are driven with a Sinusoidal Drive. In a Sinusoidal Drive all three phases of the motor are driven constantly, and there are no floating phases, such as the 6-step block commutation in the Trapezoidal Drive. By increasing the duration of one dead time up to five times compared to the other one, this method can measure the BEMF using an AC peripheral. +This example shows how to set a Timer/Counter type E (TCE) and a Waveform Extension (WEX) instance to generate six complementary Pulse-Width Modulation (PWM) signals to spin a 3-phase Brushless Direct Current Motor (BLDC) or a Permanent Magnet Synchronous Motor (PMSM) with a Sinusoidal Drive. This example also configures the Analog Comparator (AC) peripheral to measure directly the Back Electromotive Force (BEMF), when the motor is spinning. The measurement window is one of the two dead time periods during a PWM cycle. This dead time period is increased to 2 µs to have a big enough acquisition window to detect clean BEMF, that is not influenced by the PWM driving signals. The other dead time period is kept at 500 ns. A full PWM cycle has 50 µs (which is the classic 20 KHz frequency of MOSFET switching, used in Motor Control applications). The motor is spinning using forced commutation in this example without any sort of synchronization or Closed Loop algorithms. This code example just highlights the new BEMF measurement method during dead time. The motor is spinning at a constant speed and at a constant amplitude that are not modified at run time, because it is not the scope of this application. ## Related Documentation @@ -33,4 +31,315 @@ More details and code examples on the AVR16EB32 can be found at the following li The AVR16EB32 Curiosity Nano Development Board is used along with the MPPB, AVR-EB Cnano to MPPB Adaptor Board, the BLDC Motor and a Voltage Power Supply. -
\ No newline at end of file +
+ +## Functionality + +
The peripheral clock, output port pins, TCE, WEX and AC are initialized and configured using the MPLAB X Code Configurator. At run-time, the driving sinewave signals are generated using a Lookup Table (LUT). The LUT is scrolled using three 16-bit counters, one for each phase. The drive is updated at every PWM cycle, once every 50 µs. The counters start from different values to ensure the 120 electrical degrees phase shift for the three phases. The BEMF is read once per PWM cycle as well. The counters increment is the actual motor's speed (LUT scrolling speed). The frequency of the sinewave signals is modified by increasing or decreasing the LUT scrolling speed. The amplitude of the sinewave signals is modified using TCE's hardware scaling accelerator. + +
At run-time the ```BEMF_Read()``` function is called in an Interrupt Service Routine (ISR). The ```BEMF_Read()``` function is registered as a callback on the TCE's CMP3 vector ISR. This function gets the output from the AC and sets an IO to high `1` logic if the value is one. If the value from the AC output is zero the IO is set to `0`, low logic. Every phase of the motor has an IO to show the sampled BEMF for the respective phase. PF1, PF2 and PF3 pins are used to show the sampled BEMF for the three phases of the motor. PF4 pin is used to mark the sampling moment of the BEMF during the long dead time. The AC has on the negative input the hardware reconstructed neutral phase of the motor. The AC has on the positive input the three phases of the motor, each one at a time, using a Multiplexor (MUX). The AC MUX is switched at every PWM cycle (whenever a new ISR occurs) to monitor a different phase. This means that each phase of the motor is monitored every 150 µs. The AC monitors phase A for 50 µs, switches to phase B for another 50 µs, and then to phase C for another 50 µs. After that, the process repeats itself over and over again. Another approach is to monitor one phase until a Zero-Cross of BEMF is detected, then switch to monitor another phase and so on. The second approach reduces the Zero-Cross Detection delay. + +## Function Called in Interrupt Service Routine + +```c +void BEMF_Read(void) +{ + bool bemf_state; + static mux_t mux = MUX_PHASE_A; + + /* BEMF sampling point marked by an IO toggling */ + IO_PF4_SetHigh(); + bemf_state = ((AC0.STATUS & AC_CMPSTATE_bm) != 0 ); + IO_PF4_SetLow(); + + /* Switching AC0 MUX from one phase to another one */ + switch(mux) + { + case MUX_PHASE_A: if(bemf_state) {IO_PF1_SetHigh();} else {IO_PF1_SetLow();} mux = MUX_PHASE_B; break; + case MUX_PHASE_B: if(bemf_state) {IO_PF2_SetHigh();} else {IO_PF2_SetLow();} mux = MUX_PHASE_C; break; + case MUX_PHASE_C: if(bemf_state) {IO_PF3_SetHigh();} else {IO_PF3_SetLow();} mux = MUX_PHASE_A; break; + default: mux = MUX_PHASE_A; break; + } + + /* Update Analog Comparator MUX to monitor another phase of the motor */ + Mux_Set(mux); + + /* Update drive to keep the motor spinning */ + Motor_Drive(); +} +``` + +## Analog Comparator MUX Setup + +
+ +## Application Flowchart + +
+ +
To generate this project using MPLAB X IDE and the MPLAB X Code Configurator (MCC Melody, MCC Clasic is not supported on this device), follow the next steps: + +
1. Open MPLAB X IDE and create a new project for the AVR16EB32 device. + +
2. Open MCC from the toolbar (more information on how to install the MCC plug-in can be found [here](https://onlinedocs.microchip.com/pr/GUID-1F7007B8-9A46-4D03-AEED-650357BA760D-en-US-6/index.html?GUID-D98198EA-93B9-45D2-9D96-C97DBCA55267)). + +
3. From the **MCC Content Manager** tab click the **Select MCC Melody** button and then click **Finish**.
+
+
+ +
4. Click _Project>Resources>System>CLKCTRL_, then do the following configuration: +
+
- Disable the Prescaler enable button +
+ +
5. To add the TCE module, go to _Device Resources>Drivers>Timer>TCE0_, then do the following configuration: +
+
- Module Enable: Must be enabled by default, if not just toggle the button (it turns blue if enabled) +
- Clock Selection: System clock (by default the divider must be 1 - System clock) +
- Counter Direction: UP +
- Waveform Generation Mode: Single-Slope PWM mode with overflow on TOP +
- Requested Period [s]: 0.00005 +
- Duty Cycle 0 [%]: 0 +
- Duty Cycle 1 [%]: 0 +
- Duty Cycle 2 [%]: 0 +
- Duty Cycle 3 [%]: 98.5 +
- Waveform Output n: Check the boxes from the Enable column for Waveform Output 0, 1, 2, 3 +
- Scale mode: CMP values are scaled from Center, 50% DC (duty cycle) +
- Scaled Writing to registers: Normal +
- Amplitude Control Enable: Toggle the button (it turns blue if enabled) +
- Amplitude Value: 0.1 +
- Generate ISR: Toggle the button (it turns blue if enabled) +
- Compare 3 Interrupt Enable: Toggle the button (it turns blue if enabled) +
+ +
6. To add the WEX module, go to _Device Resources>Drivers>WEX>WEX0_, then do the following configuration: +
+
- Input Matrix: Direct +
- Update Source: TCE (the update condition for the output signals will be dictated by TCE) +
- Override Settings: Check all the boxes from the Output Enable column for the Waveform Output [0-5] +
- Dead-time Insertion Channel 0 Enable: Toggle the button (it turns blue if enabled) +
- Dead-time Insertion Channel 1 Enable: Toggle the button (it turns blue if enabled) +
- Dead-time Insertion Channel 2 Enable: Toggle the button (it turns blue if enabled) +
- Requested Dead-time Low Side (μs) : 2 +
- Requested Dead-time High Side (μs) : 0.5 +
+ +
7. To add the AC module, go to _Device Resources>Drivers>AC>AC0_, then do the following configuration: +
+
- Enable: Toggle the button (it turns blue if enabled) +
- Positive Input MUX Selection: Positive Pin 5 +
- Negative Input MUX Selection: Negative Pin 1 +
- Output Pad Enable: Toggle the button (it turns blue if enabled) +
+ +
8. In the **Pin Grid View** tab check if the WEX_WO [0-5] pins are locked as outputs on PORTA. When the boxes from the Enable column in the Output Settings of WEX are checked, the pins are also locked. To change the PORT simply click a pin from another PORT in **Pin Grid View**. Check if PA7 pin is set as AC output. Check if PD4 and PD0 pins are set as inputs for AC. Also, another two pins are needed as inputs for AC for the other two phases of the motor. Click PD5 and PD6 and set them as inputs from _Pins -> GPIO_. Last, the pins that show the sampled BEMF and the sampling moment must be set as outputs from _Pins>GPIO_. These pins are PF1, PF2, PF3 and PF4. + + | Pin | Configuration | + | :---------------------: | :----------------: | + | PA0 | TCE and WEX WO0 | + | PA1 | TCE and WEX WO1 | + | PA2 | TCE and WEX WO2 | + | PA3 | TCE and WEX WO3 | + | PA4 | TCE and WEX WO4 | + | PA5 | TCE and WEX WO5 | + | PA7 | AC output | + | PD0 | AC negative input 1 | + | PD4 | AC positive input 5 | + | PD5 | AC positive input 6 | + | PD6 | AC positive input 3 | + | PF1 | Digital output | + | PF2 | Digital output | + | PF3 | Digital output | + | PF4 | Digital output | + +
+ +
Go to _Project Resources>System>Pins_. Select the Digital Input Buffer disabled option for PD5 and PD6 pins. +
+ +
9. In the **Project Resources** tab, click the **Generate** button so that MCC will generate all the specified drivers and configurations. +
+
+
+
+ +
10. After MCC Melody generates the project files with the configuration explained above, overwrite the content from the ```main.c``` file with this: + +```c +/* Number of pole pairs of a BLDC motor */ +#define MOTOR_PAIR_POLES 4 + +/* MOSFET switching frequency in Hz */ +#define F_SAMPLING 20000.0 + +/* uint16_t range mapping: 0 - 359.99 electrical degrees -> 0 - 65535 */ +#define DEGREES_TO_U16(DEG) (uint16_t)( (float)(DEG) * 65536.0 / 360.0 + 0.5) + +/* Speed conversion from RPM to LUT scrolling speed */ +#define RPM_TO_U16(RPM) (uint16_t)(((float)(RPM) * 65536.0 * (float)(MOTOR_PAIR_POLES)) / ((float)(F_SAMPLING) * 60.0) + 0.5) + +/* Sets the amplitude of the sine wave signals, and thus the scaling values of duty cycle in U.Q.1.15 format, ranging from 0 to 1.00 + * Duty cycle scaling is done in hardware using the hardware accelerator of TCE */ +#define AMP_TO_U16(X) (uint16_t)(32768.0*(X) + 0.5) + +/* Speed of the motor - 120 RPM */ +#define SPEED RPM_TO_U16(120) + +/* Amplitude of the sine wave - 10% */ +#define AMPLITUDE AMP_TO_U16(0.1) + + +#include "mcc_generated_files/system/system.h" + +typedef enum +{ + MUX_PHASE_A = (AC_MUXPOS_AINP5_gc | AC_MUXNEG_AINN1_gc), + MUX_PHASE_B = (AC_MUXPOS_AINP6_gc | AC_MUXNEG_AINN1_gc), + MUX_PHASE_C = (AC_MUXPOS_AINP3_gc | AC_MUXNEG_AINN1_gc), +} mux_t; + +/* LUT that is used to generate a sinusoidal drive */ +static const uint16_t sine_lookup_table[] = +{ + 16384, 16786, 17187, 17589, 17989, 18389, 18788, 19185, 19580, 19973, 20364, + 20753, 21140, 21523, 21903, 22280, 22653, 23023, 23389, 23750, 24107, 24459, 24807, + 25149, 25486, 25818, 26143, 26463, 26777, 27085, 27386, 27681, 27969, 28250, 28523, + 28790, 29049, 29300, 29543, 29779, 30006, 30226, 30437, 30639, 30833, 31018, 31194, + 31362, 31520, 31670, 31810, 31941, 32062, 32174, 32276, 32369, 32453, 32526, 32590, + 32644, 32689, 32723, 32748, 32763, 32768, 32763, 32748, 32723, 32689, 32644, 32590, + 32526, 32453, 32369, 32276, 32174, 32062, 31941, 31810, 31670, 31520, 31362, 31194, + 31018, 30833, 30639, 30437, 30226, 30006, 29779, 29543, 29300, 29049, 28790, 28523, + 28250, 27969, 27681, 27386, 27085, 26777, 26463, 26143, 25818, 25486, 25149, 24807, + 24459, 24107, 23750, 23389, 23023, 22653, 22280, 21903, 21523, 21140, 20753, 20364, + 19973, 19580, 19185, 18788, 18389, 17989, 17589, 17187, 16786, 16384, 15981, 15580, + 15178, 14778, 14378, 13979, 13582, 13187, 12794, 12403, 12014, 11627, 11244, 10864, + 10487, 10114, 9744, 9378, 9017, 8660, 8308, 7960, 7618, 7281, 6949, 6624, 6304, 5990, + 5682, 5381, 5086, 4798, 4517, 4244, 3977, 3718, 3467, 3224, 2988, 2761, 2541, 2330, + 2128, 1934, 1749, 1573, 1405, 1247, 1097, 957, 826, 705, 593, 491, 398, 314, 241, + 177, 123, 78, 44, 19, 4, 0, 4, 19, 44, 78, 123, 177, 241, 314, 398, 491, 593, 705, + 826, 957, 1097, 1247, 1405, 1573, 1749, 1934, 2128, 2330, 2541, 2761, 2988, 3224, + 3467, 3718, 3977, 4244, 4517, 4798, 5086, 5381, 5682, 5990, 6304, 6624, 6949, 7281, + 7618, 7960, 8308, 8660, 9017, 9378, 9744, 10114, 10487, 10864, 11244, 11627, 12014, + 12403, 12794, 13187, 13582, 13979, 14378, 14778, 15178, 15580, 15981 +}; + +/* Function that is called every 50 μs to update the drive */ +void Motor_Drive(void) +{ +/* Counters that scroll through the LUT at run-time. These counter are used to create the 120 degrees + * phase shift between each of the motor's phases */ + static uint16_t phase_a = DEGREES_TO_U16(0.0); + static uint16_t phase_b = DEGREES_TO_U16(120.0); + static uint16_t phase_c = DEGREES_TO_U16(240.0); + static const uint16_t speed = SPEED; + + /* Values that will be written in the CMP channels of TCE */ + uint16_t drive_a, drive_b, drive_c; + + /* Updating the counters */ + phase_a += speed; + phase_b += speed; + phase_c += speed; + + /* Select new variables from the LUT for each CMP channel */ + drive_a = sine_lookup_table[(phase_a >> 8)]; + drive_b = sine_lookup_table[(phase_b >> 8)]; + drive_c = sine_lookup_table[(phase_c >> 8)]; + + /* Update the values from CMP channels with new ones */ + TCE0_CompareChannels012BufferedSet(drive_a, drive_b, drive_c); +} + +/* Functions that switches the MUX to monitor all three phases at run-time */ +void Mux_Set(uint8_t mode) +{ + uint8_t temp; + temp = AC0.MUXCTRL; + temp &= ~(AC_MUXPOS_gm | AC_MUXNEG_gm); + temp |= mode; + AC0.MUXCTRL = temp; +} + +/* Function that is called during the enlarged dead time to read the BEMF state */ +void BEMF_Read(void) +{ + bool bemf_state; + static mux_t mux = MUX_PHASE_A; + + /* BEMF sampling point marked by an IO toggling */ + IO_PF4_SetHigh(); + bemf_state = ((AC0.STATUS & AC_CMPSTATE_bm) != 0 ); + IO_PF4_SetLow(); + + /* Switching AC0 MUX from one phase to another one */ + switch(mux) + { + case MUX_PHASE_A: if(bemf_state) {IO_PF1_SetHigh();} else {IO_PF1_SetLow();} mux = MUX_PHASE_B; break; + case MUX_PHASE_B: if(bemf_state) {IO_PF2_SetHigh();} else {IO_PF2_SetLow();} mux = MUX_PHASE_C; break; + case MUX_PHASE_C: if(bemf_state) {IO_PF3_SetHigh();} else {IO_PF3_SetLow();} mux = MUX_PHASE_A; break; + default: mux = MUX_PHASE_A; break; + } + + /* Update Analog Comparator MUX to monitor another phase of the motor */ + Mux_Set(mux); + + /* Update drive to keep the motor spinning */ + Motor_Drive(); +} + +int main(void) +{ + SYSTEM_Initialize(); + + /* Register the BEMF sampling function as a callback */ + TCE0_Compare3CallbackRegister(BEMF_Read); + + /* Enable hardware scaling accelerator after initialization to avoid messing up + * the timing for reading BEMF with CMP3 channel of TCE */ + TCE0_ScaleEnable(true); + + /* Set the Amplitude level */ + TCE0_AmplitudeSet(AMPLITUDE); + + while(1) + { + } +} +``` + +
11. Now the project can be built and run from MPLAB X IDE. At run time, while the motor is spinning, the BEMF from each phase of the motor is sampled with the AC and displayed using some output GPIO pins. It can be observed that the measured BEMF follows the Sinusoidal Drive signals of the motor's phases. + + ## Operation + + 1. Connect the board to the PC. + + 2. Open the ```BEMF_Acquisition_Demo.X``` or solution in MPLAB X IDE. + + 3. Right click the project and select Set as main project. + +
+ + 4. Build the ```BEMF_Acquisition_Demo.X``` project by clicking **Clean and Build Project**. + +
+ + 5. Click **Make and Program Device** to program the project to the board. + +
+ +## Results + +Below are some logic analyzer captures, to help understand how the six PWM signals that generate the 3-phases sinusoidal drive look, and how the sampled BEMF follows the drive signals: + +
Sampling point of BEMF during dead time: +
+ +
Sampled BEMF for one phase of the motor: +
+ +
All three phases of the motor with their sampled BEMF signals. In this capture the phase signals are filtered with a hardware low pass filter to observe the sinusoidal drive: +
+ +## Summary + +This project demonstrates how to use the TCE and WEX to generate PWM signals in Single-Ramp mode to drive a 3-phase BLDC or PMSM motor. Additionally, it shows how to measure BEMF during the dead-time period using the AC. This BEMF detection method cannot be used for applications with high dynamic load changes because the response is not fast enough. For this method to detect BEMF as clean as possible, the motor must spin at a minimum RPM speed of usually around 10-20% of the nominal speed of the motor. \ No newline at end of file