I'm trying to generate a 2MHz PWM with a duty-cycle of 50%. My problem is that I can't clear the interrupt flag. Here is my code:
#include "includes.h"
TIM_TimeBaseInitTypeDef TIM1_InitStruncture;
TIM_TimeBaseInitTypeDef TIM3_InitStruncture;
TIM_OCInitTypeDef TIM3_OCInitStructure;
SPI_InitTypeDef SPI_InitStructure;
void Timer3_IRQHandler(void)
{
if(TIM_GetITStatus(TIM3, TIM_IT_CC3) != RESET)
{
TIM_ClearFlag(TIM3, TIM_IT_CC3);
//dummy code
++StatusReg;
}
}
void CLK_init()
{
//activez HSI
RCC_HSICmd(ENABLE);
//astepst sa se activeze HSI
while( RCC_GetFlagStatus( RCC_FLAG_HSIRDY) == RESET );
//setez HSI ca sursa de clock
RCC_SYSCLKConfig( RCC_SYSCLKSource_HSI );
//activez HSE
RCC_HSEConfig( RCC_HSE_ON );
//astept sa se termine secventa de activare
while( RCC_GetFlagStatus( RCC_FLAG_HSERDY) == RESET );
//setez HSE (8MHz) ca input py PLL
//setez factotul de multiplicare 9
RCC_PLLConfig( RCC_PLLSource_HSE_Div1, RCC_PLLMul_9 );
//activez PLL-ul
RCC_PLLCmd(ENABLE);
//astept sa se termine secventa de activare
while( RCC_GetFlagStatus( RCC_FLAG_PLLRDY) == RESET );
#ifdef EMB_FLASH
// 5. Init Embedded Flash
// Zero wait state, if 0 < HCLK 24 MHz
// One wait state, if 24 MHz < HCLK 56 MHz
// Two wait states, if 56 MHz < HCLK 72 MHz
// Flash wait state
FLASH_SetLatency(FLASH_Latency_2);
// Half cycle access
FLASH_HalfCycleAccessCmd(FLASH_HalfCycleAccess_Disable);
// Prefetch buffer
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
#endif // EMB_FLASH
//setez iesirea de la PLL ca sursa de CLK
RCC_SYSCLKConfig( RCC_SYSCLKSource_PLLCLK );
}
void Port_C_Enable()
{
//GPIO_InitTypeDef GPIOC_InitStructure;
//resetez portul C (just in case)
RCC->APB2RSTR |= RCC_APB2RSTR_IOPCRST;
RCC->APB2RSTR &= ~RCC_APB2RSTR_IOPCRST;
//activez CLK-ul pentru portul C
RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;
/*
GPIOC_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIOC_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIOC_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOC, &GPIOC_InitStructure);
*/
}
void Timer3_Init()
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//reset Timer3 (just in case)
//RCC->APB1RSTR |= RCC_APB1RSTR_TIM3RST;
//RCC->APB1RSTR &= ~RCC_APB1RSTR_TIM3RST;
//give clock to Timer-ul 3
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
//frequency 2Mhz
TIM3_InitStruncture.TIM_Period = 36;
TIM3_InitStruncture.TIM_Prescaler = 0;
TIM3_InitStruncture.TIM_ClockDivision = 0;//TIM_CKD_DIV1;
TIM3_InitStruncture.TIM_CounterMode = TIM_CounterMode_CenterAligned3;
TIM_TimeBaseInit(TIM3, &TIM3_InitStruncture);
TIM_ITConfig(TIM3, TIM_IT_CC3, ENABLE);
TIM_Cmd(TIM3, ENABLE);
//dutycicle 50%
TIM3_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
TIM3_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM3_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM3_OCInitStructure.TIM_Pulse = 18;
TIM_OC3Init(TIM3, &TIM3_OCInitStructure);
TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);
TIM_ARRPreloadConfig(TIM3, ENABLE);
TIM_Cmd(TIM3, ENABLE);
}
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/*GPIOB Configuration: TIM3 channel1, 2, 3 and 4
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;*/
//GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_PinRemapConfig(GPIO_FullRemap_TIM3, ENABLE);
/* GPIOA Configuration:TIM3 Channel1, 2, 3 and 4 as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
void NVIC_init(void)
{
// NVIC init
#ifndef EMB_FLASH
/* Set the Vector Table base location at 0x20000000 */
NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
#else /* VECT_TAB_FLASH */
/* Set the Vector Table base location at 0x08000000 */
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
#endif
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
}
void SPI_init()
{
SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 0;
SPI_Init(SPI2, &SPI_InitStructure);
}
void main(void)
{
#ifdef DEBUG
debug();
#endif
// NVIC_SETPRIMASK();
CLK_init();
NVIC_init();
Port_C_Enable();
GPIO_Configuration();
//Timer1_Init();
Timer3_Init();
TIM_Cmd(TIM1, ENABLE);
unsigned int j=0;
while(1)
{
//dummy code
++j;
if(j == 0xff)
{
j=0;
}
}
}
Can anyone tell me why the CCR3 (Capture/Compare Register 3 Flag) stays high?
Thanks.
Pay attention to not mixing the following:
TIM_ClearFlag which shall be used together with TIM_FLAG_CC1
TIM_ClearITPendingBit which shall be used together with TIM_IT_CC1
as far as I understand. Otherwise you could have some masks which avoid to flag to be set.
Thanks aamxip for your answer.
I found the problem. It seems that the configuration is correct but i don't have enough time to execute the ISR(interrupt service routine). Once every 36 CLK's a new interrupt is generated and it takes me somewhere around 30 instructions or more only to enter in the ISR.
After more research i found out that i don't really need that frequency and i adopted a different approach, bit-banging.
Related
I capture input PWM signal from AURORA9x using 3 timers (TIM4_CH1, TIM3_CH1, TIM2_CH1). All works great except TIM2_CH1. I can't to fix that issue for 3 days. May be some of You came across to this problem.
Here code for three timers. Configuration for all timers are same, but TIM2 doesn't work
#include "stm32f10x.h"
#include "stm32f10x_rcc.h"
#include "can.h"
#include "main.h"
void TIM4_Config(void);
void TIM3_Config(void);
void TIM2_Config(void);
uint32_t DataCapture_TIM4=0,
DataCapture_TIM3=0,
DataCapture_TIM2=0;
Timer Configuration for capturing mode for TIM4_CH1
void TIM4_Config(void)
{
TIM_TimeBaseInitTypeDef TIM_Time_user;
GPIO_InitTypeDef port;
TIM_ICInitTypeDef TIM_ICInit_user;
NVIC_InitTypeDef NVIC_InitStructure2;
// TIM4 clock enable
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
// GPIOB clock enable
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
// TIM4 channel_1 configuration : PB6
port.GPIO_Pin = GPIO_Pin_6;
port.GPIO_Mode = GPIO_Mode_IN_FLOATING;
port.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOB, &port);
// Connect TIM pin to AF2
// Enable the TIM4 global Ymtirrupt
NVIC_InitStructure2.NVIC_IRQChannel = TIM4_IRQn;
NVIC_InitStructure2.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure2.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure2.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure2);
// Time base configuration
TIM_Time_user.TIM_Period = PERIOD;
TIM_Time_user.TIM_Prescaler = PRESCALER;
TIM_Time_user.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_Time_user.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM4, &TIM_Time_user);
//Capture configuration
TIM_ICInit_user.TIM_Channel = TIM_Channel_1;
TIM_ICInit_user.TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM_ICInit_user.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_ICInit_user.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_ICInit_user.TIM_ICFilter = 0x0;
//Inicialize our structure for capture signal
TIM_PWMIConfig(TIM4, &TIM_ICInit_user);
//input trigger
TIM_SelectInputTrigger(TIM4, TIM_TS_TI1FP1);
TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_Reset);
// Select the slave Mode: Reset Mode
TIM_SelectMasterSlaveMode(TIM4,TIM_MasterSlaveMode_Enable);
// Enable the TIM4 Counter
TIM4->CR1 |= TIM_CR1_CEN;
// Enable the CC1 Interrupt request
TIM4->DIER |= TIM_IT_CC1;
}
Interrupt handler for TIM4_CH1
void TIM4_IRQHandler(void)
{
if (TIM4->SR & TIM_SR_CC1IF )
{
DataCapture_TIM4 = TIM4->CCR2;
}
}
Capture mode for TIM3_Ch1
void TIM3_Config(void)
{
TIM_TimeBaseInitTypeDef TIM_Time_user;
GPIO_InitTypeDef port;
TIM_ICInitTypeDef TIM_ICInit_user1;
NVIC_InitTypeDef NVIC_InitStructure1;
// TIM4 clock enable
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
// GPIOB clock enable
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
// TIM channel1 confikurotion : PA6
port.GPIO_Pin = GPIO_Pin_6;
port.GPIO_Mode = GPIO_Mode_IN_FLOATING;///////////////////////////////
port.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOA, &port);
// Enable the TIM3 global interrupt
NVIC_InitStructure1.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure1.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure1.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure1.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure1);
// Time base configuration
TIM_Time_user.TIM_Period = PERIOD;
TIM_Time_user.TIM_Prescaler = PRESCALER;
TIM_Time_user.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_Time_user.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_Time_user);
//
TIM_ICInit_user1.TIM_Channel = TIM_Channel_1;
TIM_ICInit_user1.TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM_ICInit_user1.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_ICInit_user1.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_ICInit_user1.TIM_ICFilter = 0x0;
//
TIM_PWMIConfig(TIM3, &TIM_ICInit_user1);
//input trigger
TIM_SelectInputTrigger(TIM3, TIM_TS_TI1FP1);
TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset);
// Select the slave Mode: Reset Mode
TIM_SelectMasterSlaveMode(TIM3,TIM_MasterSlaveMode_Enable);
// Enable the TIM3 Counter
TIM3->CR1 |= TIM_CR1_CEN;
// Enable the CC1 Intirrupt Request
TIM3->DIER |= TIM_IT_CC1;
}
Interrupt handler for TIM3_CH1
void TIM3_IRQHandler(void)
{
if (TIM3->SR & TIM_SR_CC1IF )
{
DataCapture_TIM3 = TIM3->CCR2;
}
}
A problem is HERE for Capturing mode for TIM2_Ch1
void TIM2_Config(void)
{
TIM_TimeBaseInitTypeDef TIM_Time_user;
GPIO_InitTypeDef port;
TIM_ICInitTypeDef TIM_ICInit_user;
NVIC_InitTypeDef NVIC_InitStructure2;
// TIM4 clock enable
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
// GPIOB clock enable
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
// TIM2 channel_1 configuration : PA0
port.GPIO_Pin = GPIO_Pin_0;
port.GPIO_Mode = GPIO_Mode_IN_FLOATING;
port.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOA, &port);
// Enable the TIM2 global Interrupt
NVIC_InitStructure2.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure2.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure2.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure2.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure2);
// Time base configuration
TIM_Time_user.TIM_Period = PERIOD;
TIM_Time_user.TIM_Prescaler = PRESCALER;
TIM_Time_user.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_Time_user.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_Time_user);
//
TIM_ICInit_user.TIM_Channel = TIM_Channel_1;
TIM_ICInit_user.TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM_ICInit_user.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_ICInit_user.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_ICInit_user.TIM_ICFilter = 0x0;
//
TIM_PWMIConfig(TIM2, &TIM_ICInit_user);
//input trigger
TIM_SelectInputTrigger(TIM2, TIM_TS_TI1FP1);
TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset);
// Select the slave Mode: Reset Mode
TIM_SelectMasterSlaveMode(TIM2,TIM_MasterSlaveMode_Enable);
// Enable the TIM2 Counter
TIM2->CR1 |= TIM_CR1_CEN;
// Enable the CC1 Interrupt Request
TIM2->DIER |= TIM_IT_CC1;
}
Interrupt handler for TIM2_CH1
void TIM2_IRQHandler(void)
{
if (TIM2->SR & TIM_SR_CC1IF )
{
DataCapture_TIM2 = TIM2->CCR2;
}
}
Sorry I cann't add comment.You can check your setting register values in debug mode and check different between your work and CubeMx setting to find problem
As an alternative answer, I recommend you to try CubeMX.
It's a code generator for STM32 that can help you quickly write STM32 low level driver.
I have smt32l1xx board and this code below is not working. Debugger shows pinA5 is set, but diode connected to this pin is still not lightening. I dont know why. Even i add delay after setting bit it is not working. diode is connected to PA5 and GND on board.
#include <stm32l1xx.h>
#define ENABLE 1
#define DISABLE 0
void TIM2_IRQHandler() //interrupt
{
if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)
{
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
if (GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_5))
GPIO_ResetBits(GPIOA, GPIO_Pin_5); //LED OFF
else
GPIO_SetBits(GPIOA, GPIO_Pin_5); //LED ON <- im here and still nothing
}
}
int main(void)
{
/* gpio init struct */
GPIO_InitTypeDef gpio;
TIM_TimeBaseInitTypeDef tim;
NVIC_InitTypeDef nvic;
/* reset rcc */
RCC_DeInit();
RCC_APB2PeriphClockCmd(RCC_AHBENR_GPIOAEN, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
GPIO_StructInit(&gpio);
/* use pin 0 */
gpio.GPIO_Pin = GPIO_Pin_5;
/* mode: output */
gpio.GPIO_Mode = GPIO_Mode_OUT;
/* apply configuration */
GPIO_Init(GPIOA, &gpio);
TIM_TimeBaseStructInit(&tim); //timer
tim.TIM_CounterMode = TIM_CounterMode_Up;
tim.TIM_Prescaler = 64000 - 1;
tim.TIM_Period = 1000 - 1;
TIM_TimeBaseInit(TIM2, &tim);
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
TIM_Cmd(TIM2, ENABLE);
nvic.NVIC_IRQChannel = TIM2_IRQn; //interrupt
nvic.NVIC_IRQChannelPreemptionPriority = 0;
nvic.NVIC_IRQChannelSubPriority = 0;
nvic.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&nvic);
while (1)
{
}
/* never reached */
return 0;
}
To make sure that your hardware is properly initialized, you should use STM32CubeMX.
It seems that the GPIOA clock is on the AHB bus, however you call RCC_APB2PeriphClockCmd which is for APB2. So try to use the equivalent for AHB something like RCC_AHBPeriphClockCmd
I am using an STM32F100RB at the moment and I am trying to read a value from a potentiometer and to display it through the PWM signal. The problem I have is where I am connecting them I think. The PWM signal is generated through this code:
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
uint32_t Prescaler, Period;
/* Enable GPIO clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
/* Enable TIM clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
/* Configure TIM1_CH1 as alternate function push-pull */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; // No point in overdriving
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Both these must ultimately fit in 16-bit, ie 1..65536 */
Prescaler = (SystemCoreClock / 20000); // System -> 20 KHz
Period = 2000; // 20 KHz -> 1 Hz
/* Extra caution required with TIM1/TIM8 full function timers, to initialize ALL fields */
/* Time base configuration */
TIM_TimeBaseStructure.TIM_Prescaler = (uint16_t)(Prescaler - 1);
TIM_TimeBaseStructure.TIM_Period = (uint16_t)(Period - 1);
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // Where do those stairs go? They go up!
TIM_TimeBaseStructure.TIM_ClockDivision = 0; // Not used
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; // Not used
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
/* PWM1 Mode configuration: Channel1 */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_Pulse = (uint16_t)(Period / ADC1ConvertedValue[0]); // 50%
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
TIM_OC1Init(TIM1, &TIM_OCInitStructure);
/* TIM1 enable counter */
TIM_Cmd(TIM1, ENABLE);
/* TIM1 Main Output Enable */
TIM_CtrlPWMOutputs(TIM1, ENABLE);
while (1)
{
}
The PWM output works fine, and it displays what it should display. The problem comes with the ADC, where something seems not to work as it should (the code is from the manufacturer website), and this is the full code.
#include "stm32f10x.h"
//#include "stm32f10x_conf.h"
#include "stm32f10x_usart.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_tim.h"
#include "stm32f10x_adc.h"
#include "stm32f10x_dma.h"
#include "stm32f10x_flash.h"
#define ADC1_DR_Address ((uint32_t)0x4001244C)
#define BufferLenght 4
ADC_InitTypeDef ADC_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
uint16_t ADC1ConvertedValue[BufferLenght];
ErrorStatus HSEStartUpStatus;
void RCC_Configuration(void);
void GPIO_Configuration(void);
RCC_Configuration();
GPIO_Configuration();
/* DMA1 channel1 configuration ---------------------------------------------*/
DMA_DeInit(DMA1_Channel1);
DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADC1ConvertedValue;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = BufferLenght;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
/* Enable DMA1 channel1 */
DMA_Cmd(DMA1_Channel1, ENABLE);
/* ADC1 configuration ------------------------------------------------------*/
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = BufferLenght;
ADC_Init(ADC1, &ADC_InitStructure);
/* ADC1 regular channel11, channel14, channel16 and channel17 configurations */
ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 1, ADC_SampleTime_41Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_17, 2, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 3, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 4, ADC_SampleTime_1Cycles5);
/* Enable ADC1 DMA */
ADC_DMACmd(ADC1, ENABLE);
/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
/* Enable TempSensor and Vrefint channels: channel16 and Channel17 */
ADC_TempSensorVrefintCmd(ENABLE);
/* Enable ADC1 reset calibaration register */
ADC_ResetCalibration(ADC1);
/* Check the end of ADC1 reset calibration register */
while(ADC_GetResetCalibrationStatus(ADC1));
/* Start ADC1 calibaration */
ADC_StartCalibration(ADC1);
/* Check the end of ADC1 calibration */
while(ADC_GetCalibrationStatus(ADC1));
/* Start ADC1 Software Conversion */
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
/* Test on Channel 1 DMA1_FLAG_TC flag */
while(!DMA_GetFlagStatus(DMA1_FLAG_TC1));
/* Clear Channel 1 DMA1_FLAG_TC flag */
DMA_ClearFlag(DMA1_FLAG_TC1);
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
uint32_t Prescaler, Period;
/* Enable GPIO clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
/* Enable TIM clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
/* Configure TIM1_CH1 as alternate function push-pull */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; // No point in overdriving
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Both these must ultimately fit in 16-bit, ie 1..65536 */
Prescaler = (SystemCoreClock / 20000); // System -> 20 KHz
Period = 2000; // 20 KHz -> 1 Hz
/* Extra caution required with TIM1/TIM8 full function timers, to initialize ALL fields */
/* Time base configuration */
TIM_TimeBaseStructure.TIM_Prescaler = (uint16_t)(Prescaler - 1);
TIM_TimeBaseStructure.TIM_Period = (uint16_t)(Period - 1);
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // Where do those stairs go? They go up!
TIM_TimeBaseStructure.TIM_ClockDivision = 0; // Not used
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; // Not used
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
/* PWM1 Mode configuration: Channel1 */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_Pulse = (uint16_t)(Period / ADC1ConvertedValue[0]); // 50%
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
TIM_OC1Init(TIM1, &TIM_OCInitStructure);
/* TIM1 enable counter */
TIM_Cmd(TIM1, ENABLE);
/* TIM1 Main Output Enable */
TIM_CtrlPWMOutputs(TIM1, ENABLE);
while (1)
{
}
}
/**
* #brief Configures the different system clocks.
* #param None
* #retval None
*/
void RCC_Configuration(void)
{
/* RCC system reset(for debug purpose) */
RCC_DeInit();
/* Enable HSE */
RCC_HSEConfig(RCC_HSE_ON);
/* Wait till HSE is ready */
HSEStartUpStatus = RCC_WaitForHSEStartUp();
if(HSEStartUpStatus == SUCCESS)
{
/* Enable Prefetch Buffer */
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
/* Flash 2 wait state */
FLASH_SetLatency(FLASH_Latency_2);
/* HCLK = SYSCLK */
RCC_HCLKConfig(RCC_SYSCLK_Div1);
/* PCLK2 = HCLK */
RCC_PCLK2Config(RCC_HCLK_Div1);
/* PCLK1 = HCLK/2 */
RCC_PCLK1Config(RCC_HCLK_Div2);
/* ADCCLK = PCLK2/4 */
RCC_ADCCLKConfig(RCC_PCLK2_Div4);
#ifndef STM32F10X_CL
/* PLLCLK = 8MHz * 7 = 56 MHz */
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_7);
#else
/* Configure PLLs *********************************************************/
/* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */
RCC_PREDIV2Config(RCC_PREDIV2_Div5);
RCC_PLL2Config(RCC_PLL2Mul_8);
/* Enable PLL2 */
RCC_PLL2Cmd(ENABLE);
/* Wait till PLL2 is ready */
while (RCC_GetFlagStatus(RCC_FLAG_PLL2RDY) == RESET)
{}
/* PLL configuration: PLLCLK = (PLL2 / 5) * 7 = 56 MHz */
RCC_PREDIV1Config(RCC_PREDIV1_Source_PLL2, RCC_PREDIV1_Div5);
RCC_PLLConfig(RCC_PLLSource_PREDIV1, RCC_PLLMul_7);
#endif
/* Enable PLL */
RCC_PLLCmd(ENABLE);
/* Wait till PLL is ready */
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
{
}
/* Select PLL as system clock source */
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
/* Wait till PLL is used as system clock source */
while(RCC_GetSYSCLKSource() != 0x08)
{
}
}
/* Enable DMA1 clock */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
/* Enable peripheral clocks --------------------------------------------------*/
/* Enable ADC1 and GPIOC clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
}
/**
* #brief Configures the different GPIO ports.
* #param None
* #retval None
*/
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Configure PC.01 and PC.04 (Channel11 and Channel14) as analog input -----*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOC, &GPIO_InitStructure);
}
I am combining those two parts of code at the point where I should divide the value that TIM_Pulse is assigned:
TIM_OCInitStructure.TIM_Pulse = (uint16_t)(Period / ADC1ConvertedValue[0]);
I am a newcome in the embedded programming, and I just started playing with this board and the goal I want to achieve is to set the Pulse length according to the potentiometer value.
Thank you in advance,
Alex.
The modified code looks like this:
#include "stm32f10x_conf.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_adc.h"
#include "stm32f10x_tim.h"
double x = 0;
GPIO_InitTypeDef myGPIO;
ADC_InitTypeDef myADC;
void adc_config()
{
//ADC
myGPIO.GPIO_Pin = GPIO_Pin_6; //setat pe pin6
myGPIO.GPIO_Mode = GPIO_Mode_AIN; //setare ca analog
GPIO_Init(GPIOA, &myGPIO); //set to A6
RCC_ADCCLKConfig (RCC_PCLK2_Div6); //ceas pentru ADC (max 14MHz, 72/6=12MHz)
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); //ceas ADC
//configurare parametrii ADC
myADC.ADC_Mode = ADC_Mode_Independent;
myADC.ADC_ScanConvMode = DISABLE;
myADC.ADC_ContinuousConvMode = ENABLE;
myADC.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
myADC.ADC_DataAlign = ADC_DataAlign_Right;
myADC.ADC_NbrOfChannel = 1;
ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 1, ADC_SampleTime_55Cycles5); //PA6 as Input
ADC_Init(ADC1, &myADC);
//enable
ADC_Cmd(ADC1, ENABLE);
ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1));
ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1));
ADC_Cmd(ADC1, ENABLE);
}
int getPot(void)
{
return ADC_GetConversionValue(ADC1);
}
//configurare pini I/O
void GPIO_config(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
//LED-pinC9
GPIO_StructInit(&myGPIO);
myGPIO.GPIO_Pin = GPIO_Pin_9;
myGPIO.GPIO_Mode = GPIO_Mode_Out_PP;
myGPIO.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOC, &myGPIO);
}
int main(void)
{
GPIO_config(); //configurare pini
adc_config(); //configurare ADC
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
uint32_t Prescaler, Period;
/*!< At this stage the microcontroller clock setting is already configured,
this is done through SystemInit() function which is called from startup
file (startup_stm32f10x_xx.s) before to branch to application main.
To reconfigure the default setting of SystemInit() function, refer to
system_stm32f10x.c file
*/
/* Enable GPIO clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
/* Enable TIM clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
/* Configure TIM1_CH1 as alternate function push-pull */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; // No point in overdriving
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Both these must ultimately fit in 16-bit, ie 1..65536 */
Prescaler = (SystemCoreClock / 200000); // System -> 20 KHz
Period = 2000; // 20 KHz -> 1 Hz
/* Extra caution required with TIM1/TIM8 full function timers, to initialize ALL fields */
/* Time base configuration */
TIM_TimeBaseStructure.TIM_Prescaler = (uint16_t)(Prescaler - 1);
TIM_TimeBaseStructure.TIM_Period = (uint16_t)(Period - 1);
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // Where do those stairs go? They go up!
TIM_TimeBaseStructure.TIM_ClockDivision = 0; // Not used
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; // Not used
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
while(1)
{
x = getPot()*3.3/4096; //obtinere valoare analog si convertirea in volti, 12bit ADC
/* PWM1 Mode configuration: Channel1 */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_Pulse = (uint16_t)(Period / x); // 50%
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
TIM_OC1Init(TIM1, &TIM_OCInitStructure);
/* TIM1 enable counter */
TIM_Cmd(TIM1, ENABLE);
/* TIM1 Main Output Enable */
TIM_CtrlPWMOutputs(TIM1, ENABLE);
if(x > 2)
{
GPIO_WriteBit(GPIOC, GPIO_Pin_9, Bit_SET);//pornire Led
}
else {
GPIO_WriteBit(GPIOC, GPIO_Pin_9, Bit_RESET);//oprire Led
}
}
}
Thanks to #Olaf.
I'm new with the stm32f407 discovery board and I'm trying to make 4 signals which I can control phase shift and dutycycle. The thing is, when i set my timer on PWM mode I can't control phase shift between channel_1 and channel_2. I know I have to use interrupts but I can't figure out what i should code inside it. I would be grateful if you could help me.
Here is my code, I use one interrupt which switches on/off a LED every some time (the delay is not well synchronized yet).
/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_rcc.h"
#include "misc.h"
#include "stm32f4xx_tim.h"
#include "stm32f4xx_usart.h"
#include "delay.h"
/* Private typedef -----------------------------------------------------------*/
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
/* Private define ------------------------------------------------------------*/
#define frequency 42500
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
int Prescaler = 0;
int Period = 84000000 / frequency; // ~42.5KHz
int pulse_width;
/* Private function prototypes -----------------------------------------------*/
void GPIO_Config(void);
void PWM_Config(void);
void PWM_SetDC(int channel,int dutycycle);
void Delay(__IO int nCount);
void LED_Config(void);
/* Private functions ---------------------------------------------------------*/
void TIM2_IRQHandler(void)
{
if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET)
{
Delay(10000000);
GPIO_ToggleBits(GPIOD, GPIO_Pin_15);
TIM_ClearITPendingBit(TIM2, TIM_IT_CC1);
}
}
/**
* Main program
*/
int main(void)
{
/* GPIO Configuration */
GPIO_Config();
LED_Config();
/* PWM Configuration */
PWM_Config();
PWM_SetDC(1,80);
PWM_SetDC(2,40);
PWM_SetDC(3,0);
PWM_SetDC(4,0);
while (1)
{
}
}
/**
* Configure the TIM2 Output Channels.
*/
void GPIO_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Enable the TIM2 global Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* TIM2 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
/* GPIOA clock enable */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA , ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
/* GPIOC Configuration: TIM2 CH1 (PA0), TIM2 CH2 (PA1), TIM2 CH3 (PA2), TIM2 CH4 (PA3) */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Connect TIM2 pins to AF2 */
GPIO_PinAFConfig(GPIOA, GPIO_PinSource0, GPIO_AF_TIM2);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_TIM2);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_TIM2);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_TIM2);
}
void PWM_Config(void)
{
/* Time base configuration */
TIM_TimeBaseStructure.TIM_Period = Period - 1;
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
TIM_ARRPreloadConfig(TIM2, ENABLE);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
/* PWM1 Mode configuration: Channel1 */
TIM_OCInitStructure.TIM_Pulse = 0;
TIM_OC1Init(TIM2, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable);
////////////////////////* TIM INTERRUPT enable *////////////////////////////
TIM_ITConfig(TIM2, TIM_IT_CC1, ENABLE);
////////////////////////////////////////////////////////////////////////////
/* PWM1 Mode configuration: Channel2 */
// TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 0;
TIM_OC2Init(TIM2, &TIM_OCInitStructure);
TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable);
/* PWM1 Mode configuration: Channel3 */
// TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 0;
TIM_OC3Init(TIM2, &TIM_OCInitStructure);
TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable);
/* PWM1 Mode configuration: Channel4 */
// TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 0;
TIM_OC4Init(TIM2, &TIM_OCInitStructure);
TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Enable);
/* TIM2 enable counter */
TIM_Cmd(TIM2, ENABLE);
}
void PWM_SetDC(int channel,int dutycycle)
{
if (dutycycle <= 100 && dutycycle >= 0)
{
pulse_width=(Period*dutycycle)/100;
if (channel == 1)
{
TIM2->CCR1 = pulse_width;
}
else if (channel == 2)
{
TIM2->CCR2 = pulse_width;
}
else if (channel == 3)
{
TIM2->CCR3 = pulse_width;
}
else
{
TIM2->CCR4 = pulse_width;
}
}
}
void LED_Config(void)
{
/* GPIOD Peripheral clock enable */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
/* Configure PD12, PD13, PD14 and PD15 in output push-pull mode */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13| GPIO_Pin_14| GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOD, &GPIO_InitStructure);
}
/* Delay Function.
* nCount:specifies the Delay time length.
*/
void Delay(__IO int nCount)
{
while(nCount--)
{
}
}
I think I can Help you if you make you Question a bit clear..
As for as I can understand your Question:-> I think you want 2 PWM's with Phase shift?
so if you want simple phase shift between two pwm simply use this Let's say if you want a delay of 1ms. -> you have to use two different timers then..
TIM_Cmd(TIM2, ENABLE);
Delay(1000);
TIM_Cmd(TIM3, ENABLE);
I am working with the following evaluation board: SZWB-sail, STM32f103VET6 KIT v3.1
I want to use the stm32f103 usart in synchronous mode, and I used
STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Examples\USART\Synchronous
I modified the code in an attempt to use USART2/SPI1, as opposed to the working code provided via STMicro, which uses USART1/SPI1.
The README for this example states that:
"USARTy and SPIy can be USART1 and SPI1 or USART2 and SPI3, depending on the STMicroelectronics EVAL board you are using."
Despite this, I attempted to physically connect USART2 Tx/Rx/Ck pins (PA2,PA3,PA4) to SPI1 SCK/MISO/MOSI (PA5,PA6,PA7). Is there a software reason for why this won't work? Or might it be hardware connections on the eval board?
Here is my code:
int main(void)
{
SystemInit();
Init_NVIC();
/* System Clocks Configuration */
RCC_Configuration();
/* Configure the GPIO ports */
GPIO_Configuration();
SPI_Configuration();
USART_Configuration();
while(NbrOfDataToRead2--)
{
USART2_Send_Byte(TxBuffer1[TxCounter1++]);
while(USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET)
{
}
while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET)
{
}
RxBuffer2[RxCounter2++] = SPI_I2S_ReceiveData(SPI1);
}
USART2_Receive_Byte();
while(NbrOfDataToRead1--)
{
while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE)== RESET)
{
}
SPI_I2S_SendData(SPI1, TxBuffer2[TxCounter2++]);
USART2_Send_Byte(DYMMY_BYTE);
while(USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET)
{
}
while(USART_GetFlagStatus(USART2, USART_FLAG_RXNE) == RESET)
{
}
RxBuffer1[RxCounter1++] = USART2_Receive_Byte();
}
TransferStatus1 = Buffercmp(TxBuffer1, RxBuffer2, TxBufferSize1);
TransferStatus2 = Buffercmp(TxBuffer2, RxBuffer1, TxBufferSize2);
while(1)
{
}
}
void Init_NVIC(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
#ifdef VECT_TAB_RAM
NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
#else
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
#endif
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void RCC_Configuration(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE );
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1 , ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 , ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2 , ENABLE);
}
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure1,GPIO_InitStructure2;
GPIO_InitTypeDef GPIO_InitStructure3,GPIO_InitStructure4,GPIO_InitStructure5,GPIO_InitStructure6;
/* Configure USART1 Rx as input floating */
GPIO_InitStructure1.GPIO_Pin =GPIO_Pin_10;
GPIO_InitStructure1.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure1.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure1);
/* Configure USART1 Tx as alternate function push-pull */
GPIO_InitStructure2.GPIO_Pin =GPIO_Pin_9;
GPIO_InitStructure2.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure2.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure2);
/* Configure USART2 Rx as input floating */
GPIO_InitStructure3.GPIO_Pin =GPIO_Pin_3;
GPIO_InitStructure3.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure3.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure3);
/* Configure USART2 Tx as alternate function push-pull */
GPIO_InitStructure4.GPIO_Pin =GPIO_Pin_2;
GPIO_InitStructure4.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure4.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure4);
/* Configure USART2 Ck as alternate function push-pull */
GPIO_InitStructure5.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure5.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure5.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure5);
/* Configure SPI1 pins: SCK, MISO and MOSI */
GPIO_InitStructure6.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_Init(GPIOA, &GPIO_InitStructure6);
}
void USART_Configuration(void)
{
USART_InitTypeDef USART_InitStructure1,USART_InitStructure2;
USART_ClockInitTypeDef USART_ClkInitStructure;
USART_InitStructure1.USART_BaudRate = 115200;
USART_InitStructure1.USART_WordLength =USART_WordLength_8b ;
USART_InitStructure1.USART_StopBits = USART_StopBits_1;
USART_InitStructure1.USART_Parity = USART_Parity_No;
USART_InitStructure1.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure1.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
/* Configure USART1 */
USART_Init(USART1,&USART_InitStructure1);
//USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
/* Enable the USART1 */
USART_Cmd(USART1,ENABLE);
USART_ClkInitStructure.USART_Clock=USART_Clock_Enable;
USART_ClkInitStructure.USART_CPOL=USART_CPOL_High;
USART_ClkInitStructure.USART_CPHA=USART_CPHA_2Edge;
USART_ClkInitStructure.USART_LastBit=USART_LastBit_Enable;
USART_ClockInit(USART2, &USART_ClkInitStructure);
USART_InitStructure2.USART_BaudRate = 115200;
USART_InitStructure2.USART_WordLength =USART_WordLength_8b ;
USART_InitStructure2.USART_StopBits = USART_StopBits_1;
USART_InitStructure2.USART_Parity = USART_Parity_No;
USART_InitStructure2.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure2.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
/* Configure USART2 */
USART_Init(USART2,&USART_InitStructure2);
//USART_ITConfig(USART2,USART_IT_RXNE,ENABLE);
/* Enable the USART2 */
USART_Cmd(USART2,ENABLE);
}
void SPI_Configuration(void)
{
SPI_InitTypeDef SPI_InitStructure;
SPI_StructInit(&SPI_InitStructure);
SPI_I2S_DeInit(SPI1);
/* SPIy Config */
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Slave;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_LSB;
/* Configure SPIy */
SPI_Init(SPI1, &SPI_InitStructure);
SPI_I2S_ITConfig(SPI1,SPI_I2S_IT_RXNE,ENABLE);
/* SPIy enable */
SPI_Cmd(SPI1, ENABLE);
}
You are mixing polling mode with interrupt mode. This SPI configuration code is intended for SPI interrupt mode. Hence, SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) should not be used, because this is a function intended for Polling-Mode.
Instead, I believe you can use SPI_I2S_GetITStatus(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT); in conjunction with SPI_I2S_ReceiveData(SPI_TypeDef* SPIx) and SPI_I2S_ClearITPendingBit(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT) (to clear any potential Error pending bits, just in-case).
Also, you might want to post your USART2_Send_Byte() code so we know what exactly it's doing, and whether it's calling any other functions...but go ahead and try this first to see if it fixes your problem.
SPI1 conflicts with USART2 synchronization mode.
SPI2 conflicts with USART3 synchronization mode.
There is no conflict between SPI1/2 and USART1 synchronization modes.