cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F407 comms to thermopile

paul23
Associate II
Posted on March 13, 2015 at 10:36

Hi,

I am trying to interface to the Heimann 16x16 sensor but having issue with the timings and synchronization. There is only one bi-directional data line as shown in the pinouts below.The device acts as a master spi device when the CONT line is 1 and the data is transmitted continuously. When the CONT line is 0, the device becomes a slave device and release the control of the clock and data line. The code use for setting the the STM32 device to a slave device is shown below.

SPI_InitTypeDef spi_init_struct;
NVIC_InitTypeDef nvic_init_struct;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(GPIOB, &GPIO_InitStruct);

GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_14;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_SPI2);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_SPI2);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
SPI_StructInit(&spi_init_struct);
spi_init_struct.SPI_Direction = SPI_Direction_1Line_Rx;
spi_init_struct.SPI_Mode = SPI_Mode_Slave;
spi_init_struct.SPI_DataSize = SPI_DataSize_8b;
spi_init_struct.SPI_CPOL = SPI_CPOL_Low;
spi_init_struct.SPI_CPHA = SPI_CPHA_1Edge;
spi_init_struct.SPI_NSS = SPI_NSS_Soft;
spi_init_struct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64;
spi_init_struct.SPI_FirstBit = SPI_FirstBit_MSB;
spi_init_struct.SPI_CRCPolynomial = 0;
SPI_Init(SPI2, &spi_init_struct);
/* Configure the SPI interrupt priority */
nvic_init_struct.NVIC_IRQChannel = SPI2_IRQn;
nvic_init_struct.NVIC_IRQChannelPreemptionPriority = 0;
nvic_init_struct.NVIC_IRQChannelSubPriority = 0;
nvic_init_struct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&nvic_init_struct);
/* Enable SPI */
SPI_Cmd(SPI2, ENABLE);
SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_RXNE, ENABLE);
SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_ERR, ENABLE);
SPI_Cmd(SPI2, ENABLE);

To set the clock for the sensor, the code is shown below.

TIM_TimeBaseInitTypeDef TIM_BaseStruct;
GPIO_InitTypeDef GPIO_InitStruct;
/* Clock for GPIOD */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
/* Alternating functions for pins */
GPIO_PinAFConfig(GPIOD, GPIO_PinSource13, GPIO_AF_TIM4);
/* Set pins */
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(GPIOD, &GPIO_InitStruct);
/* Enable clock for TIM4 */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
TIM_BaseStruct.TIM_Prescaler = 0;
/* Count up */
TIM_BaseStruct.TIM_CounterMode = TIM_CounterMode_Up;
//TIM_BaseStruct.TIM_Period = 83; /* 10kHz PWM */
TIM_BaseStruct.TIM_Period = 63; 
/* 10kHz PWM */
//TIM_BaseStruct.TIM_Period = 41; /* 10kHz PWM */
TIM_BaseStruct.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_BaseStruct.TIM_RepetitionCounter = 0;
/* Initialize TIM4 */
TIM_TimeBaseInit(TIM4, &TIM_BaseStruct);
/* Start count on TIM4 */
TIM_Cmd(TIM4, ENABLE);
TIM_OCInitTypeDef TIM_OCStruct;
/* Common settings */
/* PWM mode 2 = Clear on compare match */
/* PWM mode 1 = Set on compare match */
TIM_OCStruct.TIM_OCMode = TIM_OCMode_PWM2;
TIM_OCStruct.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCStruct.TIM_OCPolarity = TIM_OCPolarity_Low;
//TIM_OCStruct.TIM_Pulse = 20; /* 50% duty cycle */
//TIM_OCStruct.TIM_Pulse = 43; /* 50% duty cycle */
TIM_OCStruct.TIM_Pulse = 32; 
/* 50% duty cycle */
TIM_OC2Init(TIM4, &TIM_OCStruct);
TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable);

The SPI interrupt is shown below. The data is sent to the PC via the USART.

void
SPI2_IRQHandler(
void
)
{
/* SPI in Slave Receiver mode--------------------------------------- */
if
(SPI_I2S_GetITStatus(SPI2, SPI_I2S_IT_RXNE) == SET)
{
newData = SPI_I2S_ReceiveData(SPI2);
Queue_Push(&thermopileQueue, &newData);
}
/* SPI Error interrupt--------------------------------------- */
if
(SPI_I2S_GetITStatus(SPI2, SPI_I2S_IT_OVR) == SET)
{
SPI_I2S_ReceiveData(SPI2);
SPI_I2S_GetITStatus(SPI2, SPI_I2S_IT_OVR);
} 
}

0690X00000605FoQAI.png Read Register 0690X00000605FAQAY.png The logic analyser capture below shows the address increment. 0690X00000605FFQAY.png 0690X00000605GDQAY.png Can anyone see anything wrong with the code and why the data is not sync? Paul
1 REPLY 1
paul23
Associate II
Posted on March 13, 2015 at 10:40

I have also tried using an gpio interrupt to read the data but still not correct.

EXTI_InitTypeDef EXTI_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
/* Set pins */
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_14;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(GPIOB, &GPIO_InitStruct);
/* Tell system that you will use PB10 for EXTI_Line10 */
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOB, EXTI_PinSource10);
/* PB10 is connected to EXTI_Line10 */
EXTI_InitStruct.EXTI_Line = EXTI_Line10;
/* Enable interrupt */
EXTI_InitStruct.EXTI_LineCmd = ENABLE;
/* Interrupt mode */
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
/* Triggers on rising and falling edge */
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising;
/* Add to EXTI */
EXTI_Init(&EXTI_InitStruct);
/* Add IRQ vector to NVIC */
/* PB10 is connected to EXTI_Line10, which has EXTI15_10_IRQn vector */
NVIC_InitStruct.NVIC_IRQChannel = EXTI15_10_IRQn;
/* Set priority */
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x00;
/* Set sub priority */
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x00;
/* Enable interrupt */
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
/* Add to NVIC */
NVIC_Init(&NVIC_InitStruct);

And the interrupt below.

void
EXTI15_10_IRQHandler(
void
)
{
if
(EXTI_GetITStatus(EXTI_Line10) != RESET)
{
EXTI_ClearITPendingBit(EXTI_Line10);
if
(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14)) 
{
newData |= 1 << bitshift;
}
else
{
newData &= ~(1 << bitshift);
}
if
(bitshift == 0)
{
// Add to ring buffer
bitshift = 7;
Queue_Push(&thermopileQueue, &newData);
}
bitshift--;
}
}