Three phase sinusoidal PWM example for the STM32L432 Nucleo

Dependencies:   mbed

main.cpp

Committer:
f3d
Date:
2019-12-02
Revision:
1:581901598cda
Parent:
0:88449c646fbd

File content as of revision 1:581901598cda:

#include "mbed.h"
#include <stm32l432xx.h>
#include "sine.h"
/*
For register definitions see here:
https://github.com/ARMmbed/mbed-os/blob/master/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L432xC/device/stm32l432xx.h
*/

// Using the MBED libraries to configure the PWM outputs (its easier than 
// calculating all of the register contents by hand)
PwmOut  PhaATop(PA_8); 
PwmOut  PhaBTop(PA_9); 
PwmOut  PhaCTop(PA_10); 
PwmOut  PhaABottom(PA_7); 
PwmOut  PhaBBottom(PB_0); 
PwmOut  PhaCBottom(PB_1); 
DigitalIn Slow(D4);
DigitalIn Fast(D5);
DigitalOut myled(LED1);
#define MAX_DELTA 500
volatile int Delta=0;
int AIndex=0;
int BIndex=90;
int CIndex=180;
void TimerISR(void)
{   
    TIM1->ARR = 270+Delta;
    int Offset=Delta/2;
    TIM1->CCR1 = sine_table[AIndex]+Offset;
    TIM1->CCR2 = sine_table[BIndex]+Offset;
    TIM1->CCR3 = sine_table[CIndex]+Offset;
    AIndex++;
    if (AIndex >= PWM_STEPS)
        AIndex = 0;
    BIndex++;
    if (BIndex >= PWM_STEPS)
        BIndex = 0;
    CIndex++;
    if (CIndex >= PWM_STEPS)
        CIndex = 0;


    TIM1->SR &= ~0x3f; // ack the interrupt    
}
void initTimer1()
{    
    
    TIM1->CR1 = 0; // make sure Counter is disabled before changing configuration
    TIM1->CR2 = 0;
    TIM1->ARR = 270;
    TIM1->PSC = 21;
    TIM1->CCR1 = 135; // 50% duty
    TIM1->CCR2 = 135; // 50% duty
    TIM1->CCR3 = 135; // 50% duty
    //// Enable complimentary outputs on channels 1 to 3
    //TIM1->CCER = (1 << 0) + (1 << 2) + (1 << 4) + (1 << 6) + (1 << 8) + (1<<10);
    TIM1->CCER = (1 << 0) +  (1 << 4) + (1 << 8);
    TIM1->SR = 0;      // Clear flags.    
    //TIM1->BDTR &= ~(0xff);
    //TIM1->BDTR |= (127); // set dead time to 127 clock cycles
    // Set up the interrupt handler
    TIM1->DIER = 1; // Want update interrupt
    NVIC_SetVector(TIM1_UP_TIM16_IRQn,(uint32_t) TimerISR);   
    NVIC_EnableIRQ(TIM1_UP_TIM16_IRQn);
    __enable_irq();   // enable interrupts 
    TIM1->CR1 |= 1; // enable counter

}

int main() {    
    initTimer1();
    while(1) {

        if ( (Slow == 0) || (Fast == 0) )
        {
            // user pressed a button so light up an LED
            myled = 1;
            if (Slow == 0)
            {
                int NextDelta = Delta;
                NextDelta = NextDelta + 10;
                if (NextDelta > MAX_DELTA)
                    NextDelta = MAX_DELTA;
                Delta = NextDelta;
            }
            if (Fast == 0)
            {
                int NextDelta = Delta;
                NextDelta = NextDelta - 10;
                if (NextDelta < 0)
                    NextDelta = 0;
                Delta = NextDelta;
            }
            
        }
        else
        {
            myled = 0;
        }
        wait(0.1); // slow down loop to avoid bounces
    }
}