Using STM32 Timer - timer

I am working on the timer of STM32. I need two pulses like in the picture.
Frequency of CLK is 50 kHz and frequency of SI is 381.67 Hz. I need the SI to go low before the rising edge of next clock pulse but in the logic analyzer of Keil I saw the SI was in a different position relatively to CLK for each pulse, like shown on below picture. How can I fix it?
void Init_TIMER(void)
{
TIM_TimeBaseInitTypeDef TIM_BaseInitStructure2, TIM_BaseInitStructure3, TIM_BaseInitStructure4;
TIM_OCInitTypeDef TIM_OCInitStructure2, TIM_OCInitStructure3;
TIM_DeInit(TIM2);
TIM_DeInit(TIM3);
TIM_DeInit(TIM4);
TIM_InternalClockConfig(TIM2);
TIM_InternalClockConfig(TIM3);
TIM_InternalClockConfig(TIM4);
/************************************************/
/********TIMER2**********************************/
/************************************************/
TIM_BaseInitStructure2.TIM_Period = 180; //180/9000000=..ms 50KHZ
TIM_BaseInitStructure2.TIM_Prescaler = 7; //SYSCLK=72M, TIM1_CLK=72/8=9MHz
TIM_BaseInitStructure2.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_BaseInitStructure2.TIM_CounterMode = TIM_CounterMode_Up;
//TIM_BaseInitStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM2, & TIM_BaseInitStructure2);
TIM_ClearFlag(TIM2, TIM_FLAG_Update);
TIM_OCInitStructure2.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure2.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure2.TIM_Pulse = 90;
TIM_OCInitStructure2.TIM_OCPolarity = TIM_OCPolarity_Low;
TIM_OC2Init(TIM2, & TIM_OCInitStructure2);
TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable);
/*****************************************************/
/********TIMER3***************************************/
/*****************************************************/
TIM_BaseInitStructure3.TIM_Period = 23580; //23580/9000000=... ms 381.67HZ 50KHZ/131=381.67HZ
TIM_BaseInitStructure3.TIM_Prescaler = 7; //SYSCLK=72M, TIM1_CLK=72/8=9MHz
TIM_BaseInitStructure3.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_BaseInitStructure3.TIM_CounterMode = TIM_CounterMode_Up;
//TIM_BaseInitStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM3, & TIM_BaseInitStructure3);
TIM_ClearFlag(TIM3, TIM_FLAG_Update);
TIM_OCInitStructure3.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure3.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure3.TIM_Pulse = 50;
TIM_OCInitStructure3.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC2Init(TIM3, & TIM_OCInitStructure3);
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);
/********************************************************/
/********TIMER4 to make sampling frequency **************/
/*******************************************************/
TIM_BaseInitStructure4.TIM_Period = 90; //90/9000000=0.01ms 100KHZ
TIM_BaseInitStructure4.TIM_Prescaler = 7; //SYSCLK=72M, TIM1_CLK=72/8=9MHz
TIM_BaseInitStructure4.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_BaseInitStructure4.TIM_CounterMode = TIM_CounterMode_Up;
//TIM_BaseInitStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM4, & TIM_BaseInitStructure4);
TIM_ARRPreloadConfig(TIM4, DISABLE);
TIM_ClearFlag(TIM4, TIM_FLAG_Update);
/**********************************************/
TIM_ARRPreloadConfig(TIM2, ENABLE);
TIM_Cmd(TIM2, ENABLE);
TIM_ARRPreloadConfig(TIM3, ENABLE);
TIM_Cmd(TIM3, ENABLE);
TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);
TIM_Cmd(TIM4, ENABLE);
}
void GPIO_Configuration()
{
GPIO_InitTypeDef GPIO_InitStructure;
/*PA1 TIM2_CH2*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, & GPIO_InitStructure);
/*PA7 TIM3_CH2*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, & GPIO_InitStructure);
}

I had similar project where I had used taos TSL1402R matrix.
Instead of timer I used an SPI with circular DMA.
DMA buffer was 0x0, 0x0.....0x0, 0x1.
SI was connected to SPI MISO,
And CLK was connected to SPI_CLK.
Hope this will help.

Related

program freezes when calling I2C write function

Board : STM32F4 Discovery
I am having troubles initializing I2C, i think! When the program reaches I2C_write function it hangs! I am trying to communicate with a temp&hum sensor HDC1080 from TI. The hardware is ok, i've been testing it with cubeMX and HAL libraries and it works ok!
I have a saleae logic analyzer hooked up to PB8(SCL) and PB9(SDA) , there's no activity!
I removed the init_usart part thinking that maybe they are interffering because they share the same port (GPIOB).
void init_usart(void)
{
//enable AHB1 peripheral clock
RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOB, ENABLE);
//Init GPIOB
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_USART1);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_USART1);
//Enable USART peripheral clock
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
//Init usart
USART_InitTypeDef USART_InitStruct;
USART_InitStruct.USART_BaudRate = 57600;
USART_InitStruct.USART_WordLength = USART_WordLength_8b;
USART_InitStruct.USART_StopBits = USART_StopBits_1;
USART_InitStruct.USART_Parity = USART_Parity_No ;
USART_InitStruct.USART_Mode = USART_Mode_Tx;
USART_InitStruct.USART_HardwareFlowControl =
USART_HardwareFlowControl_None;
USART_Init(USART1, &USART_InitStruct);
USART_Cmd(USART1, ENABLE);
}
void InitializeI2C()
{
RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOB, ENABLE);
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9; // 8=SCL 9=SDA
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStruct.GPIO_OType = GPIO_OType_OD;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_I2C1);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_I2C1);
/* enable APB1 peripheral clock for I2C1*/
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1 , ENABLE);
I2C_InitTypeDef I2C_InitStruct;
I2C_InitStruct.I2C_ClockSpeed = 100000;
I2C_InitStruct.I2C_Mode = I2C_Mode_I2C;
I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStruct.I2C_OwnAddress1 = 0x01;
I2C_InitStruct.I2C_Ack = I2C_Ack_Enable;
I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_Init(I2C1, &I2C_InitStruct);
I2C_Cmd(I2C1, ENABLE);
}
void I2C_write( uint8_t HW_address, uint8_t addr, uint8_t data)
{
I2C_GenerateSTART(I2C1, ENABLE);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C1, HW_address, I2C_Direction_Transmitter);
while (!I2C_CheckEvent(I2C1,
I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
I2C_SendData(I2C1, addr);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_SendData(I2C1, data);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_GenerateSTOP(I2C1, ENABLE);
while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
}
int main(void)
{
init_usart()
InitializeI2C();
while (1)
{
delay_div(50);
I2C_write( 0x40 << 1 , 0x01, 0x00); //here it stops!!!
}
One possible problem: You are using uninitialised data.
From your code:
I2C_InitTypeDef I2C_InitStruct;
I2C_InitStruct.I2C_ClockSpeed = 100000;
//I2C_InitStruct.I2C_Mode = I2C_Mode_I2C;
I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStruct.I2C_OwnAddress1 = 0x01;
I2C_InitStruct.I2C_Ack = I2C_Ack_Enable;
I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_Init(I2C1, &I2C_InitStruct);
At least I2C_Mode is not initialised here, and you cannot assume the value to be 0. It will just be whatever is on the stack at that time.
You either want to memset the struct to 0, or implicitly initialise other members to zero when declaring:
I2C_InitTypeDef I2C_InitStruct = {
.I2C_ClockSpeed = 100000,
//.I2C_Mode = I2C_Mode_I2C,
.I2C_DutyCycle = I2C_DutyCycle_2,
.I2C_OwnAddress1 = 0x01,
.I2C_Ack = I2C_Ack_Enable,
.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit,
};
I2C_Init(I2C1, &I2C_InitStruct);
My temp & hum sensor is dead! I2C init is fine, tried it with an i2c oled display and i can see activity on the bus!
Just a short and final update!!! Bear with me, please!
My temp&hum sensor (HDC1080) was ok! After spending 40 minutes soldering wires to a new sensor (the pins are 0.4mm) i discovered that this was also not working.
Nothing changed in terms of hardware from my succesfull initial test that i did using the HAL library, breadboard with 2 x 10k (that's what i had) pull-up resistors, 3V power supply from stm32 discovery board.
It seems that for unknown reasons the HAL test was working with those two 10k pull-ups but the SP library wasn't. Since my SSD1306 oled display comes on a pcb with 4.7k resistors already mounted i was able to discover that i can communicate with both the temp&hum sensor and display.
Final conclusion , pull-up resistors was my problem in the end!

stm32 SPI + DMA

I try to send data with SPI using DMA channel. When I send without DMA everything is OK, but with DMA sth is wrong. When I debug my program SPI DR register is always 0. I would like to use dma circular mode to send my array all the time. There is my code
GPIO INIT:
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(SPI_PERIPH_CLOCK, ENABLE);
RCC_AHBPeriphClockCmd(GPIO_PERIPH_CLOCK, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
GPIO_PinAFConfig(GPIOB, AF_PIN_SOURCE, GPIO_AF);
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_DOWN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
SPI INIT
SPI_I2S_DeInit(SPI1);
SPI_InitTypeDef SPI_InitStructure;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx;
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_32;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI1, &SPI_InitStructure);
SPI_Cmd(SPI1, ENABLE);
DMA INIT:
DMA_InitTypeDef dma;
DMA_DeInit(DMA1_Channel1);
DMA_StructInit(&dma);
dma.DMA_PeripheralBaseAddr = (uint32_t)&SPI1->DR;
dma.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
dma.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
dma.DMA_MemoryBaseAddr = (uint32_t)spi_tx_buffer;
dma.DMA_MemoryInc = DMA_MemoryInc_Enable;
dma.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
dma.DMA_DIR = DMA_DIR_PeripheralDST;
dma.DMA_BufferSize = BUFFERSIZE;
dma.DMA_Mode = DMA_Mode_Circular;
dma.DMA_M2M = DMA_M2M_Disable;
DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 6;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
DMA_Init(DMA1_Channel1, &dma);
SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx, ENABLE);
DMA_Cmd(DMA1_Channel1, ENABLE);
simple main
int main(void) {
periph_init();
while (1) {
for(int j=0; j<10000000; j++){
j++;
j--;
}
}
return 0;
}
What I'm doing wrong?
As I mentioned in comments, your SPI has no connection with DMA1_Channel1. According to this data sheet, you should use DMA1_Channel3.

STM32F4 multiple SPI_I2S_GetFlagStatus crashes the program

I'm trying to implement a simple http server on my stm32F411RE nucleo board from here, but of course I've run into some problems - so far, I managed to narrow the current one to the fact, that after about 20 calls to
SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE); My program crashes. By crash, I mean goes to the Infinite Loop defined in the startup file, reason being "Program received signal SIGINT, Interrupt."
My spi is initialised like that:
void SPI1_Init(void){
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable SPI1 and GPIOA clocks */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
//SCK, MISO, MOSI
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//CS
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//CS down
GPIO_SetBits(GPIOA, GPIO_Pin_2);
SPI_InitTypeDef SPI_InitStructure;
/* SPI1 configuration */
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
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_4;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI1, &SPI_InitStructure);
/* Enable SPI1 */
SPI_Cmd(SPI1, ENABLE);
}
after the initialization, I do this:
for(tmpCnt = 0; tmpCnt < 100; tmpCnt++){
SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE);
}
and it crashes after about 20 iterations. I am using the standard peripheral library, and System Workbench with all stock settings of compiler and everything else. At the moment nothing is connected to the SPI pins, could that be the problem?
calling
(SPI1->SR) instead of SPI_I2S_GetFlagStatus
has the same effect so I guess that the problem lies withing reading the register. Why could that be? I'm really stuck at the moment, so any help would be appreciated.
EDIT:
Ok, it turns out that I missed a bit of code that seems to cause this behaviour - before the SPi1->SR calls, I also had this function called:
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */
SysTick->LOAD = ticks - 1; /* set reload register */
NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Systick Interrupt */
SysTick->VAL = 0; /* Load the SysTick Counter Value */
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
return (0); /* Function successful */
}
why does it break the SPI1->SR access? could there be anything else wrong? My main function:
int main(void)
{
int tmpCnt = 0;
int rev = 0;
//uint16_t writedat = 22;
RCC_Init();
SPI1_Init();
//SysTick_Config(1000);
for(tmpCnt = 0; tmpCnt < 50; tmpCnt++){
SPI1->SR ;
}
enc28j60Init((unsigned char *)enc28j60_MAC);
//simple_server();
rev = enc28j60getrev();
return rev;
}
RCC_Init does not seem to change anything in the behaviour of the SPI1->SR.
As before, any advice would be welcome.

STM32F1 timer share for PWM and interrupt

i'm implementing a project using stm32f101cb microcontroller. I understand that this control have 3 timer in it. TIM2 and TIM4 had been set to encoder mode to capture 2 rotary encoder.
I'm now left me the only timer TIM3, I would to ask is there possible for me to set TIM3 to PWM mode and at the same time doing the normal timer interrupt? I could not find it in reference manual or programming manual.
Thanks!
It should be possible. I'm doing it for an STM32F091RC I've developed an application for where I'm controlling LED:s with PWM and generating a timer update interrupt (counter reset) with the same timer peripheral.
Here's some of my configuration code:
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
/* LED_TIM clock enable */
RCC_APB1PeriphClockCmd(TIM_LED_RCC, ENABLE);
/* LED_PORT Configuration: Channel 1, 2, 3 as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = LED_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(LED_PORT, &GPIO_InitStructure);
GPIO_PinAFConfig(LED_PORT, LED_PIN_SOURCE, LED_TIM_AF);
/* Enable the TIM global Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = LED_TIM_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* Time Base configuration */
TIM_TimeBaseStructure.TIM_Prescaler = LED_TIM_PSC;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_Period = 0xFFFF; // Max 0xFFFF
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
/* Channel 1 Configuration in PWM mode */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
TIM_OCInitStructure.TIM_Pulse = LED_INIT_PULSE;
TIM_OC1Init(LED_TIM, &TIM_OCInitStructure); // Init Channel 1
TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Disable);
/* TIM IT enable */
TIM_ITConfig(LED_TIM, TIM_IT_Update, ENABLE); // Enable interrupts for LED_TIM
/* LED_TIM counter enable */
TIM_Cmd(LED_TIM, ENABLE);
/* LED_TIM Main Output Enable */
TIM_CtrlPWMOutputs(LED_TIM, ENABLE);
Should be very similar for your device. If everything works correctly, you should be getting interrupts in your TIM3_IRQHandler ISR
void TIM3_IRQHandler(void)
{
if (TIM_GetITStatus(LED_TIM, TIM_IT_Update) != RESET)
{
TIM_ClearITPendingBit(LED_TIM, TIM_IT_Update);
// Do ISR stuff here!
}
}

STM32F407 SPI reciveing only 0xFF (255) or 0

Recently I have been trying to receive a data from my STM32F407 motion sensor. I have the following code:
uint8_t SPI1_Read(){
GPIO_ResetBits(GPIOA, GPIO_Pin_4); // CS low
while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE)==RESET){}
SPI_I2S_SendData(SPI1, 0x00);
while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE)==RESET){}
return SPI_I2S_ReceiveData(SPI1);
}
void SPI1_Write(uint8_t data){
while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE)==RESET){}
SPI_I2S_SendData(SPI1, data);
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET){}
SPI_I2S_ReceiveData(SPI1);
}
volatile static int vrednost, vrednost1, vrednost2;
int main(void)
{
// Vkljuci driver za GPIOD
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
// Nastavi registre za LED diode
GPIO_InitTypeDef inicializacijskaStruktura;
inicializacijskaStruktura.GPIO_Mode = GPIO_Mode_OUT;
inicializacijskaStruktura.GPIO_OType = GPIO_OType_PP;
inicializacijskaStruktura.GPIO_PuPd = GPIO_PuPd_NOPULL;
inicializacijskaStruktura.GPIO_Speed = GPIO_Speed_100MHz;
inicializacijskaStruktura.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_Init(GPIOD, &inicializacijskaStruktura);
SPI_and_GPIO_Init();
// init
SPI1_Write(0x20);
SPI1_Write(0x47);
SPI1_Write(0x0F);
SPI1_Write(0xBC);
while(1)
{
SPI1_Write(0x20);
vrednost=SPI1_Read();
SPI1_Write(0x24);
vrednost1=SPI1_Read();
SPI1_Write(0x28);
vrednost2=SPI1_Read();
if(vrednost<122){
GPIO_SetBits(GPIOD, GPIO_Pin_12);
}
else{
GPIO_ResetBits(GPIOD, GPIO_Pin_12);
}
if(vrednost1<122)
GPIO_SetBits(GPIOD, GPIO_Pin_13);
else
GPIO_ResetBits(GPIOD, GPIO_Pin_13);
if(vrednost2<122)
GPIO_SetBits(GPIOD, GPIO_Pin_14);
else
GPIO_ResetBits(GPIOD, GPIO_Pin_14);
}
}
void SPI_and_GPIO_Init(){
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable the SPI periph */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
/* Enable SCK, MOSI and MISO GPIO clocks */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA , ENABLE);
/* Enable CS GPIO clock */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
/* SPI pins configuration */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* SPI configuration -------------------------------------------------------*/
SPI_I2S_DeInit(SPI1);
SPI_InitTypeDef SPI_InitStructure;
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
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_4;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
/* Enable SPI1 */
SPI_SSOutputCmd(SPI1, ENABLE);
SPI_Cmd(SPI1, ENABLE);
/* Configure GPIO PIN for Lis Chip select */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOE, &GPIO_InitStructure);
/* Deselect : Chip Select high */
GPIO_SetBits(GPIOE, GPIO_Pin_3);
}
Upper code works fine, but the problem is that always when I try to read motion sensor, i get 0xFF or in another words 255. I read data by sending dummy text and then read data.
I have been also given an advice to set Slave Select pin (SS) to zero, but I don't know how to do that.
Does anybody know?
To hazard a guess - typically with SPI, SS is driven low (enable) at the start of each write/read then driven high (disable) at the end of each write/read to indicate end of transmission. Without pulling out the board, that's what I'd bet on.
If that's not it - ST is pretty good at providing examples. The source code on their product page includes an example using their MEMs accelerometer (Utilities/STM32F4-Discovery/stm32f4_discovery_lis302dl.c/.h).

Resources