Created
January 8, 2014 08:13
-
-
Save technobly/8313449 to your computer and use it in GitHub Desktop.
SPARK CORE CUSTOM PWM FREQUENCY EXAMPLE
Define your own frequency! PWM Glitch issue fixed!!
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//----------------------------------------------- | |
// SPARK CORE CUSTOM PWM FREQUENCY EXAMPLE | |
//=============================================== | |
// Define your own frequency below! | |
// PWM Glitch issue fixed, only sets up PWM once, | |
// ... thereafter sets duty cycle. | |
// This allows true 0 - 100% PWM. | |
// Copy this into a new application at: | |
// https://www.spark.io/build and go nuts! | |
//----------------------------------------------- | |
// Technobly / BDub - Jan 8th, 2014 | |
//=============================================== | |
#define PWM_FREQ 1000 // in Hertz (SET YOUR FREQUENCY) | |
#define ANALOG_PIN A2 // potentiometer connected to analog pin A2 | |
uint16_t TIM_ARR = (uint16_t)(24000000 / PWM_FREQ) - 1; // Don't change! Calc's period. | |
int val = 0; // variable to store the read ADC value | |
void setup() { | |
pinMode(A0, OUTPUT); // sets the pin as output | |
pinMode(A1, OUTPUT); // sets the pin as output | |
pinMode(A4, OUTPUT); // sets the pin as output | |
pinMode(A5, OUTPUT); // sets the pin as output | |
pinMode(A6, OUTPUT); // sets the pin as output | |
pinMode(A7, OUTPUT); // sets the pin as output | |
pinMode(D0, OUTPUT); // sets the pin as output | |
pinMode(D1, OUTPUT); // sets the pin as output | |
} | |
void loop() { | |
// analogRead values go from 0 to 4095, analogWrite values from 0 to 255 | |
// read the input pin (0-4095) and scale it to 0-255 by dividing by 16. | |
val = analogRead(ANALOG_PIN) / 16; | |
// Write newly scaled value to A0, A1, A4, A5, A6, A7, D0 and D1. | |
analogWrite2(A0, val); | |
analogWrite2(A1, val); | |
analogWrite2(A4, val); | |
analogWrite2(A5, val); | |
analogWrite2(A6, val); | |
analogWrite2(A7, val); | |
analogWrite2(D0, val); | |
analogWrite2(D1, val); | |
delay(10); // wait 10 milliseconds | |
} | |
// User defined analogWrite() to gain control of PWM initialization | |
void analogWrite2(uint16_t pin, uint8_t value) { | |
TIM_OCInitTypeDef TIM_OCInitStructure; | |
if (pin >= TOTAL_PINS || PIN_MAP[pin].timer_peripheral == NULL) { | |
return; | |
} | |
// SPI safety check | |
if (SPI.isEnabled() == true && (pin == SCK || pin == MOSI || pin == MISO)) { | |
return; | |
} | |
// I2C safety check | |
if (Wire.isEnabled() == true && (pin == SCL || pin == SDA)) { | |
return; | |
} | |
// Serial1 safety check | |
if (Serial1.isEnabled() == true && (pin == RX || pin == TX)) { | |
return; | |
} | |
if (PIN_MAP[pin].pin_mode != OUTPUT && PIN_MAP[pin].pin_mode != AF_OUTPUT_PUSHPULL) { | |
return; | |
} | |
// Don't re-init PWM and cause a glitch if already setup, just update duty cycle and return. | |
if (PIN_MAP[pin].pin_mode == AF_OUTPUT_PUSHPULL) { | |
TIM_OCInitStructure.TIM_Pulse = (uint16_t)(value * (TIM_ARR + 1) / 255); | |
if (PIN_MAP[pin].timer_ch == TIM_Channel_1) { | |
PIN_MAP[pin].timer_peripheral-> CCR1 = TIM_OCInitStructure.TIM_Pulse; | |
} else if (PIN_MAP[pin].timer_ch == TIM_Channel_2) { | |
PIN_MAP[pin].timer_peripheral-> CCR2 = TIM_OCInitStructure.TIM_Pulse; | |
} else if (PIN_MAP[pin].timer_ch == TIM_Channel_3) { | |
PIN_MAP[pin].timer_peripheral-> CCR3 = TIM_OCInitStructure.TIM_Pulse; | |
} else if (PIN_MAP[pin].timer_ch == TIM_Channel_4) { | |
PIN_MAP[pin].timer_peripheral-> CCR4 = TIM_OCInitStructure.TIM_Pulse; | |
} | |
return; | |
} | |
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; | |
//PWM Frequency : PWM_FREQ (Hz) | |
uint16_t TIM_Prescaler = (uint16_t)(SystemCoreClock / 24000000) - 1; //TIM Counter clock = 24MHz | |
// TIM Channel Duty Cycle(%) = (TIM_CCR / TIM_ARR + 1) * 100 | |
uint16_t TIM_CCR = (uint16_t)(value * (TIM_ARR + 1) / 255); | |
// AFIO clock enable | |
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); | |
pinMode(pin, AF_OUTPUT_PUSHPULL); | |
// TIM clock enable | |
if (PIN_MAP[pin].timer_peripheral == TIM2) | |
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); | |
else if (PIN_MAP[pin].timer_peripheral == TIM3) | |
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); | |
else if (PIN_MAP[pin].timer_peripheral == TIM4) | |
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); | |
// Time base configuration | |
TIM_TimeBaseStructure.TIM_Period = TIM_ARR; | |
TIM_TimeBaseStructure.TIM_Prescaler = TIM_Prescaler; | |
TIM_TimeBaseStructure.TIM_ClockDivision = 0; | |
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; | |
TIM_TimeBaseInit(PIN_MAP[pin].timer_peripheral, & TIM_TimeBaseStructure); | |
// PWM1 Mode configuration | |
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; | |
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; | |
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; | |
TIM_OCInitStructure.TIM_Pulse = TIM_CCR; | |
if (PIN_MAP[pin].timer_ch == TIM_Channel_1) { | |
// PWM1 Mode configuration: Channel1 | |
TIM_OC1Init(PIN_MAP[pin].timer_peripheral, & TIM_OCInitStructure); | |
TIM_OC1PreloadConfig(PIN_MAP[pin].timer_peripheral, TIM_OCPreload_Enable); | |
} else if (PIN_MAP[pin].timer_ch == TIM_Channel_2) { | |
// PWM1 Mode configuration: Channel2 | |
TIM_OC2Init(PIN_MAP[pin].timer_peripheral, & TIM_OCInitStructure); | |
TIM_OC2PreloadConfig(PIN_MAP[pin].timer_peripheral, TIM_OCPreload_Enable); | |
} else if (PIN_MAP[pin].timer_ch == TIM_Channel_3) { | |
// PWM1 Mode configuration: Channel3 | |
TIM_OC3Init(PIN_MAP[pin].timer_peripheral, & TIM_OCInitStructure); | |
TIM_OC3PreloadConfig(PIN_MAP[pin].timer_peripheral, TIM_OCPreload_Enable); | |
} else if (PIN_MAP[pin].timer_ch == TIM_Channel_4) { | |
// PWM1 Mode configuration: Channel4 | |
TIM_OC4Init(PIN_MAP[pin].timer_peripheral, & TIM_OCInitStructure); | |
TIM_OC4PreloadConfig(PIN_MAP[pin].timer_peripheral, TIM_OCPreload_Enable); | |
} | |
TIM_ARRPreloadConfig(PIN_MAP[pin].timer_peripheral, ENABLE); | |
// TIM enable counter | |
TIM_Cmd(PIN_MAP[pin].timer_peripheral, ENABLE); | |
} |
I have a particle photon, but can't manage to make this code works. Here are the errors :
I'm a newbie with this board, and not much experimented with this kind of feature.
Maybe some const are no more available?
servo-frequency-2.cpp: In function 'void loop()':
servo-frequency-2.cpp:37:37: error: expected ';' before ')' token
pinMode(D1, OUTPUT); // sets the pin as output
^
servo-frequency-2.cpp: In function 'void analogWrite2(uint16_t, uint16_t)':
servo-frequency-2.cpp:96:26: error: 'RCC_APB2Periph_AFIO' was not declared in this scope
uint16_t TIM_Prescaler = (uint16_t)(SystemCoreClock / 24000000) - 1; //TIM Counter clock = 24MHz
^
make[1]: *** [../build/target/user/platform-6servo-frequency-2.o] Error 1
make: *** [user] Error 2
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I tried compiling the above code in https://build.particle.io/build
I got these errors:
Solution: I added the below line
STM32_Pin_Info* PIN_MAP = HAL_Pin_Map(); // Pointer required for highest access speed
I am unable to find which files needs to be included to remove this error
Could anyone of you help me for this?