Last active
March 11, 2017 03:36
-
-
Save thetooth/a4a5adb4cc8bad29565b8336b4c5716e to your computer and use it in GitHub Desktop.
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
// NUCLEO-F401RE DMA Driven PWM - Not good for school or work assignments. | |
// Copyright (C) 2015 [email protected], All Rights Reserved | |
#include "stm32f4xx.h" | |
#define PWM_ELEMENTS 100 | |
const u32 PWM_Buffer[PWM_ELEMENTS] = { // Sine Table | |
0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 50, 53, 56, | |
58, 61, 63, 66, 68, 70, 72, 75, 77, 79, 80, 82, 84, 86, 87, 89, 90, 91, 92, 94, | |
95, 96, 96, 97, 98, 98, 99, 99, 99, 99,100, 99, 99, 99, 99, 98, 98, 97, 96, 96, | |
95, 94, 92, 91, 90, 89, 87, 86, 84, 82, 80, 79, 77, 75, 72, 70, 68, 66, 63, 61, | |
58, 56, 53, 50, 48, 45, 42, 39, 36, 33, 30, 27, 24, 21, 18, 15, 12, 9, 6, 3 }; | |
/**************************************************************************************/ | |
void RCC_Configuration(void) | |
{ | |
/* GPIOA clock enable */ | |
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); | |
/* DMA1 clock enable */ | |
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE); | |
/* TIM2 clock enable */ | |
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); | |
} | |
/**************************************************************************************/ | |
void GPIO_Configuration(void) | |
{ | |
GPIO_InitTypeDef GPIO_InitStructure; | |
/* GPIO Configuration */ | |
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; | |
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; | |
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; | |
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; | |
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; | |
GPIO_Init(GPIOA, &GPIO_InitStructure); | |
/* Connect TIM2 pins to AF */ | |
GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_TIM2); // PA5 TIM2_CH1 | |
} | |
/**************************************************************************************/ | |
void DMA_Configuration(void) | |
{ | |
DMA_InitTypeDef DMA_InitStruct; | |
/* TIM2_UP - DMA1, Channel 3, Stream 1 */ | |
DMA_InitStruct.DMA_Channel = DMA_Channel_3; | |
DMA_InitStruct.DMA_BufferSize = PWM_ELEMENTS; | |
DMA_InitStruct.DMA_DIR = DMA_DIR_MemoryToPeripheral; | |
DMA_InitStruct.DMA_Mode = DMA_Mode_Circular; | |
DMA_InitStruct.DMA_FIFOMode = DMA_FIFOMode_Disable; | |
DMA_InitStruct.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; | |
DMA_InitStruct.DMA_Memory0BaseAddr = (uint32_t)&PWM_Buffer[0]; | |
DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; | |
DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable; | |
DMA_InitStruct.DMA_MemoryBurst = DMA_MemoryBurst_Single; | |
DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&TIM2->CCR1; | |
DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; | |
DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable; | |
DMA_InitStruct.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; | |
DMA_InitStruct.DMA_Priority = DMA_Priority_Medium; | |
DMA_Init(DMA1_Stream1, &DMA_InitStruct); | |
/* Enabling DMA */ | |
DMA_Cmd(DMA1_Stream1, ENABLE); | |
} | |
/**************************************************************************************/ | |
void TIM2_Configuration(void) | |
{ | |
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; | |
TIM_OCInitTypeDef TIM_OCInitStructure; | |
TIM_TimeBaseStructure.TIM_Prescaler = (SystemCoreClock / 10000) - 1; // 10 KHz tick | |
TIM_TimeBaseStructure.TIM_Period = 100-1; // 0..99, 100 Hz period | |
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; | |
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; | |
TIM_TimeBaseStructure.TIM_RepetitionCounter = 1; | |
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); | |
/* Channel 1 configuration (PA.5) */ | |
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; | |
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; | |
TIM_OCInitStructure.TIM_Pulse = 50; // 50% | |
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; | |
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset; | |
TIM_OC1Init(TIM2, &TIM_OCInitStructure); | |
/* Associating DMA and TIM2 Update (DMA1 Channel 3, Stream 1) */ | |
TIM_DMACmd(TIM2, TIM_DMA_Update, ENABLE); | |
/* Turning on TIM2 and PWM outputs */ | |
TIM_Cmd(TIM2, ENABLE); | |
} | |
/**************************************************************************************/ | |
int main(void) | |
{ | |
RCC_Configuration(); | |
GPIO_Configuration(); | |
DMA_Configuration(); | |
TIM2_Configuration(); | |
while(1); | |
} | |
/**************************************************************************************/ | |
#ifdef USE_FULL_ASSERT | |
/** | |
* @brief Reports the name of the source file and the source line number | |
* where the assert_param error has occurred. | |
* @param file: pointer to the source file name | |
* @param line: assert_param error line source number | |
* @retval None | |
*/ | |
void assert_failed(uint8_t* file, uint32_t line) | |
{ | |
/* User can add his own implementation to report the file name and line number, | |
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ | |
/* Infinite loop */ | |
while (1) | |
{ | |
} | |
} | |
#endif | |
/**************************************************************************************/ |
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
// NUCLEO-F401RE IRQ Driven PWM - Not good for school or work assignments. | |
// Copyright (C) 2015 [email protected], All Rights Reserved | |
#include "stm32f4xx.h" | |
#define PWM_ELEMENTS 100 | |
const u32 PWM_Buffer[PWM_ELEMENTS] = { // Sine Table | |
0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 50, 53, 56, | |
58, 61, 63, 66, 68, 70, 72, 75, 77, 79, 80, 82, 84, 86, 87, 89, 90, 91, 92, 94, | |
95, 96, 96, 97, 98, 98, 99, 99, 99, 99,100, 99, 99, 99, 99, 98, 98, 97, 96, 96, | |
95, 94, 92, 91, 90, 89, 87, 86, 84, 82, 80, 79, 77, 75, 72, 70, 68, 66, 63, 61, | |
58, 56, 53, 50, 48, 45, 42, 39, 36, 33, 30, 27, 24, 21, 18, 15, 12, 9, 6, 3 }; | |
/**************************************************************************************/ | |
void RCC_Configuration(void) | |
{ | |
/* GPIOA clock enable */ | |
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); | |
/* TIM2 clock enable */ | |
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); | |
} | |
/**************************************************************************************/ | |
void GPIO_Configuration(void) | |
{ | |
GPIO_InitTypeDef GPIO_InitStructure; | |
/* GPIO Configuration */ | |
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; | |
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; | |
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; | |
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; | |
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; | |
GPIO_Init(GPIOA, &GPIO_InitStructure); | |
/* Connect TIM2 pins to AF */ | |
GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_TIM2); // PA5 TIM2_CH1 | |
} | |
/**************************************************************************************/ | |
void NVIC_Configuration(void) | |
{ | |
NVIC_InitTypeDef NVIC_InitStructure; | |
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; | |
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; | |
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; | |
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; | |
NVIC_Init(&NVIC_InitStructure); | |
} | |
/**************************************************************************************/ | |
void TIM2_Configuration(void) | |
{ | |
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; | |
TIM_OCInitTypeDef TIM_OCInitStructure; | |
TIM_TimeBaseStructure.TIM_Prescaler = (SystemCoreClock / 10000) - 1; // 10 KHz tick | |
TIM_TimeBaseStructure.TIM_Period = 100-1; // 0..99, 100 Hz period | |
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; | |
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; | |
TIM_TimeBaseStructure.TIM_RepetitionCounter = 1; | |
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); | |
/* Channel 1 configuration (PA.5) */ | |
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; | |
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; | |
TIM_OCInitStructure.TIM_Pulse = 50; // 50% | |
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; | |
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset; | |
TIM_OC1Init(TIM2, &TIM_OCInitStructure); | |
/* Enable TIM2 Update Interrupt */ | |
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); | |
/* Turning on TIM2 and PWM outputs */ | |
TIM_Cmd(TIM2, ENABLE); | |
} | |
/**************************************************************************************/ | |
void TIM2_IRQHandler(void) // Per Keil forum example, modified to suit | |
{ | |
static int index = 0; | |
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) | |
{ | |
TIM_ClearITPendingBit(TIM2, TIM_IT_Update); | |
TIM2->CCR1 = PWM_Buffer[index]; | |
index = (index + 1) % PWM_ELEMENTS; | |
} | |
} | |
/**************************************************************************************/ | |
int main(void) | |
{ | |
RCC_Configuration(); | |
GPIO_Configuration(); | |
NVIC_Configuration(); | |
TIM2_Configuration(); | |
while(1); | |
} | |
/**************************************************************************************/ | |
#ifdef USE_FULL_ASSERT | |
/** | |
* @brief Reports the name of the source file and the source line number | |
* where the assert_param error has occurred. | |
* @param file: pointer to the source file name | |
* @param line: assert_param error line source number | |
* @retval None | |
*/ | |
void assert_failed(uint8_t* file, uint32_t line) | |
{ | |
/* User can add his own implementation to report the file name and line number, | |
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ | |
/* Infinite loop */ | |
while (1) | |
{ | |
} | |
} | |
#endif | |
/**************************************************************************************/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment