Skip to content

Instantly share code, notes, and snippets.

@Sperryfreak01
Forked from technobly/SparkPWM.cpp
Last active April 6, 2017 09:10
Show Gist options
  • Save Sperryfreak01/a4282fce7c64f44036ae to your computer and use it in GitHub Desktop.
Save Sperryfreak01/a4282fce7c64f44036ae to your computer and use it in GitHub Desktop.
//-----------------------------------------------
// 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 PWM_RES 4095 // Enter desired steps count (255/1023/2047/4095/8191/16383/32767/65535)
#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, uint16_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) / PWM_RES);
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) / PWM_RES);
// 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);
}2
@YetiWilson
Copy link

In this version there seems to be problems.
Line 37: val = analogRead(ANALOG_PIN) / 16 ); \either an extra ) or a missing ).
Line 54: First use of PIN_MAP array, but has not been defined. I wonder if this was defined in your previous code that you had before it was pared down to just be the PWM frequency changer?
Line 96: RCC_APB2Periph_AFIO no declared in this scope
Line 144: There is a random 2 at the end of the code? :-)

Well, it looks like my learning curve may have been the problem here. I was trying to use this code on photon which has a different chip! Sorry about that...

@Sperryfreak01
Copy link
Author

Its been a while I'll have to load it up and see whats up. Sorry about that, dont delete the 2 bad things will happen...very bad things...:)

@0xDBFB7
Copy link

0xDBFB7 commented Mar 4, 2016

I'm late, but adding

STM32_Pin_Info* PIN_MAP = HAL_Pin_Map();

Will solve the pin map issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment