This program outputs a 50Hz complimentary Sinusoidal PWM signal on PA8 and PB13 on the STM32 Nucleo F103 board. The switching speed is 10kHz. The program uses a mix of mbed functions and/ direct register writes. It makes use of a lookup table generated in Octave (Thanks Richard Hayes) and interrupts to update the duty cycle.

Dependencies:   mbed

Committer:
f3d
Date:
Mon Dec 07 15:38:21 2015 +0000
Revision:
0:d2382fd0cc1a
First commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
f3d 0:d2382fd0cc1a 1 // This program outputs a 50Hz complimentary Sinusoidal PWM signal on PA8 and PB13.
f3d 0:d2382fd0cc1a 2 // The switching speed is 10kHz. The program uses a mix of mbed functions and
f3d 0:d2382fd0cc1a 3 // direct register writes. It makes use of a lookup table generated in Octave (Thanks Richard Hayes)
f3d 0:d2382fd0cc1a 4 // and interrupts to update the duty cycle.
f3d 0:d2382fd0cc1a 5 #include "mbed.h"
f3d 0:d2382fd0cc1a 6 // Define some bitmasks
f3d 0:d2382fd0cc1a 7 #define BIT0 (1 << 0)
f3d 0:d2382fd0cc1a 8 #define BIT1 (1 << 1)
f3d 0:d2382fd0cc1a 9 #define BIT2 (1 << 2)
f3d 0:d2382fd0cc1a 10 #define BIT3 (1 << 3)
f3d 0:d2382fd0cc1a 11 #define BIT4 (1 << 4)
f3d 0:d2382fd0cc1a 12 #define BIT5 (1 << 5)
f3d 0:d2382fd0cc1a 13 #define BIT6 (1 << 6)
f3d 0:d2382fd0cc1a 14 #define BIT7 (1 << 7)
f3d 0:d2382fd0cc1a 15 #define BIT8 (1 << 8)
f3d 0:d2382fd0cc1a 16 #define BIT9 (1 << 9)
f3d 0:d2382fd0cc1a 17 #define BIT10 (1 << 10)
f3d 0:d2382fd0cc1a 18 #define BIT11 (1 << 11)
f3d 0:d2382fd0cc1a 19 #define BIT12 (1 << 12)
f3d 0:d2382fd0cc1a 20 #define BIT13 (1 << 13)
f3d 0:d2382fd0cc1a 21 #define BIT14 (1 << 14)
f3d 0:d2382fd0cc1a 22 #define BIT15 (1 << 15)
f3d 0:d2382fd0cc1a 23 #define BIT16 (1 << 16)
f3d 0:d2382fd0cc1a 24 #define BIT17 (1 << 17)
f3d 0:d2382fd0cc1a 25 #define BIT18 (1 << 18)
f3d 0:d2382fd0cc1a 26 #define BIT19 (1 << 19)
f3d 0:d2382fd0cc1a 27 #define BIT20 (1 << 20)
f3d 0:d2382fd0cc1a 28 #define BIT21 (1 << 21)
f3d 0:d2382fd0cc1a 29 #define BIT22 (1 << 22)
f3d 0:d2382fd0cc1a 30 #define BIT23 (1 << 23)
f3d 0:d2382fd0cc1a 31 #define BIT24 (1 << 24)
f3d 0:d2382fd0cc1a 32 #define BIT25 (1 << 25)
f3d 0:d2382fd0cc1a 33 #define BIT26 (1 << 26)
f3d 0:d2382fd0cc1a 34 #define BIT27 (1 << 27)
f3d 0:d2382fd0cc1a 35 #define BIT28 (1 << 28)
f3d 0:d2382fd0cc1a 36 #define BIT29 (1 << 29)
f3d 0:d2382fd0cc1a 37 #define BIT30 (1 << 30)
f3d 0:d2382fd0cc1a 38 #define BIT31 (1 << 31)
f3d 0:d2382fd0cc1a 39 DigitalOut myled(LED1);
f3d 0:d2382fd0cc1a 40 const int duties[]={\
f3d 0:d2382fd0cc1a 41 50,51,53,54,56,57,59,60,62,63,65,66,68,69,71,72,74, \
f3d 0:d2382fd0cc1a 42 75,76,78,79,80,81,83,84,85,86,87,88,89,90,91,92,93,\
f3d 0:d2382fd0cc1a 43 93,94,95,95,96,97,97,98,98,98,99,99,99,99,99,99,100,\
f3d 0:d2382fd0cc1a 44 99,99,99,99,99,99,98,98,98,97,97,96,95,95,94,93,93,\
f3d 0:d2382fd0cc1a 45 92,91,90,89,88,87,86,85,84,83,81,80,79,78,76,75,74,\
f3d 0:d2382fd0cc1a 46 72,71,69,68,66,65,63,62,60,59,57,56,54,53,51,49,48,\
f3d 0:d2382fd0cc1a 47 46,45,43,42,40,39,37,36,34,33,31,30,28,27,25,24,23,\
f3d 0:d2382fd0cc1a 48 21,20,19,18,16,15,14,13,12,11,10,9,8,7,6,6,5,4,4,3,\
f3d 0:d2382fd0cc1a 49 2,2,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,2,2,3,4,4,\
f3d 0:d2382fd0cc1a 50 5,6,6,7,8,9,10,11,12,13,14,15,16,18,19,20,21,23,24,\
f3d 0:d2382fd0cc1a 51 25,27,28,30,31,33,34,36,37,39,40,42,43,45,46,48\
f3d 0:d2382fd0cc1a 52 };
f3d 0:d2382fd0cc1a 53 /*
f3d 0:d2382fd0cc1a 54 Pin mappings for Timer 1 (the advanced timer with deadtime)
f3d 0:d2382fd0cc1a 55 From: https://developer.mbed.org/users/mbed_official/code/mbed-src/file/a11c0372f0ba/targets/hal/TARGET_STM/TARGET_STM32F1/TARGET_NUCLEO_F103RB/PeripheralPins.c
f3d 0:d2382fd0cc1a 56 {PA_8, PWM_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, 0)}, // TIM1_CH1 - Default
f3d 0:d2382fd0cc1a 57 {PA_9, PWM_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, 0)}, // TIM1_CH2 - Default
f3d 0:d2382fd0cc1a 58 {PA_10, PWM_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, 0)}, // TIM1_CH3 - Default
f3d 0:d2382fd0cc1a 59 {PB_13, PWM_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, 0)}, // TIM1_CH1N - Default
f3d 0:d2382fd0cc1a 60 {PB_14, PWM_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, 0)}, // TIM1_CH2N - Default
f3d 0:d2382fd0cc1a 61 {PB_15, PWM_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, 0)}, // TIM1_CH3N - Default
f3d 0:d2382fd0cc1a 62
f3d 0:d2382fd0cc1a 63 */
f3d 0:d2382fd0cc1a 64 // Use mbed to configure the relevant pins as PWM outputs;
f3d 0:d2382fd0cc1a 65 PwmOut PhaATop(PA_8);
f3d 0:d2382fd0cc1a 66 PwmOut PhaABtm(PB_13); // This should be the complement of PA_8
f3d 0:d2382fd0cc1a 67 AnalogIn Pot(A0);
f3d 0:d2382fd0cc1a 68 volatile float PotValue;
f3d 0:d2382fd0cc1a 69 void init(void);
f3d 0:d2382fd0cc1a 70 int main() {
f3d 0:d2382fd0cc1a 71
f3d 0:d2382fd0cc1a 72 init();
f3d 0:d2382fd0cc1a 73 while(1) {
f3d 0:d2382fd0cc1a 74 myled = 1; // LED is ON
f3d 0:d2382fd0cc1a 75 wait(0.1); // 200 ms
f3d 0:d2382fd0cc1a 76 myled = 0; // LED is OFF
f3d 0:d2382fd0cc1a 77 wait(0.1); // 1 sec
f3d 0:d2382fd0cc1a 78 PotValue = Pot;
f3d 0:d2382fd0cc1a 79 }
f3d 0:d2382fd0cc1a 80 }
f3d 0:d2382fd0cc1a 81 int index=0;
f3d 0:d2382fd0cc1a 82 void TimerISR()
f3d 0:d2382fd0cc1a 83 {
f3d 0:d2382fd0cc1a 84 TIM1->SR &= ~0x3f; // ack the interrupt
f3d 0:d2382fd0cc1a 85 TIM1->CCR1=duties[index++]; // get the next duty
f3d 0:d2382fd0cc1a 86 if (index > 199)
f3d 0:d2382fd0cc1a 87 index = 0;
f3d 0:d2382fd0cc1a 88 }
f3d 0:d2382fd0cc1a 89 void init()
f3d 0:d2382fd0cc1a 90 {
f3d 0:d2382fd0cc1a 91
f3d 0:d2382fd0cc1a 92 RCC->APB2ENR |= BIT2+BIT3; // enable GPIOA and GPIOB
f3d 0:d2382fd0cc1a 93 RCC->APB2ENR |= BIT11; // enable TIM1
f3d 0:d2382fd0cc1a 94
f3d 0:d2382fd0cc1a 95 GPIOA->CRH |= BIT3+BIT0; // PA8 output, alternate function
f3d 0:d2382fd0cc1a 96 GPIOB->CRH |= BIT23+BIT20; // PB13 output, alternate function
f3d 0:d2382fd0cc1a 97
f3d 0:d2382fd0cc1a 98 TIM1->CR2 = 0;
f3d 0:d2382fd0cc1a 99 TIM1->DIER = BIT0; // Want update interrupt
f3d 0:d2382fd0cc1a 100 NVIC_SetVector(TIM1_UP_IRQn,(uint32_t) TimerISR);
f3d 0:d2382fd0cc1a 101 NVIC_EnableIRQ(TIM1_UP_IRQn);
f3d 0:d2382fd0cc1a 102 TIM1->SR = 0; // Clear flags.
f3d 0:d2382fd0cc1a 103 TIM1->CCMR1= BIT6+BIT5+BIT4;
f3d 0:d2382fd0cc1a 104 TIM1->CCER = BIT2+BIT0;
f3d 0:d2382fd0cc1a 105 TIM1->ARR = 100; // 1MHz = base clock freq. Divide by 100 to get 10kHz.
f3d 0:d2382fd0cc1a 106 TIM1->CCR1 = 10; // Low inital duty
f3d 0:d2382fd0cc1a 107 TIM1->CR1 |= BIT0; //enable counter
f3d 0:d2382fd0cc1a 108 __enable_irq(); // enable interrupts
f3d 0:d2382fd0cc1a 109
f3d 0:d2382fd0cc1a 110 }