2019-02-04 10:50 AM
Hi. I'm using an MPU (6050), an encoder (AS5048A) and STM32F103. For the MPU I am using the I2C protocol, for the encoder (works through the pwm) the Timer2 and its interruption are used. The I2C only works if no encoder readings are being made. Is there any known conflict between I2C2 and TIM2?
Here is my code:
void init()
{
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB , ENABLE );
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_DeInit(GPIOB);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
I2C_InitTypeDef I2C_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
RCC_AHBPeriphClockCmd(RCC_APB2Periph_AFIO|RCC_APB2Periph_GPIOB, ENABLE);
// I2CG SCL and SDA configuration
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10| GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
I2C_DeInit(I2C2);
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = 400000;
I2C_InitStructure.I2C_OwnAddress1 = 0x00;
I2C_Cmd(I2C2, ENABLE);
I2C_Init(I2C2, &I2C_InitStructure);
while(I2C_GetFlagStatus(I2C2,I2C_FLAG_BUSY));
I2C_GenerateSTART(I2C2, ENABLE);
while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C2, 0xD2, I2C_Direction_Transmitter);
while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
I2C_SendData(I2C2,0x6B);
while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_SendData(I2C2,0x00);
while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_GenerateSTOP(I2C2, ENABLE);
while(I2C_GetFlagStatus(I2C2, I2C_FLAG_STOPF));
}
void ENCODER_PITCH(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA , ENABLE );
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, & GPIO_InitStructure);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
/* Enable the TIM2 global Interrupt */
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE );
TIM_ICInitTypeDef TIM_ICInitStructure;
TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; // Falling
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_ICInitStructure.TIM_ICFilter = 0x00;
TIM_PWMIConfig(TIM2, &TIM_ICInitStructure);
/* Select the TIM2 Input Trigger: TI2FP2 */
TIM_SelectInputTrigger(TIM2, TIM_TS_TI2FP2);
/* Select the slave Mode: Reset Mode */
TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset);
TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable);
/* TIM enable counter */
TIM_Cmd(TIM2, ENABLE);
/* Enable the CC2 Interrupt Request */
TIM_ITConfig(TIM2, TIM_IT_CC2, ENABLE);
}
void registos ()
{
u8 Buffer[14];
for(int i=0;i<14;i++)
{
Buffer[i]=recp(0x3B+i);
}
Acc.X = (u16)(Buffer[0] << 8) + Buffer[1];
Acc.Y = (u16)(Buffer[2] << 8) + Buffer[3];
Acc.Z = (u16)(Buffer[4] << 8) + Buffer[5];
Gyr.X = (u16)(Buffer[8] << 8) + Buffer[9];
Gyr.Y = (u16)(Buffer[10] << 8) + Buffer[11];
Gyr.Z = (u16)(Buffer[12] << 8) + Buffer[13];
}
u8 recp(u8 reg)
{
u8 valor;
I2C_ClearFlag(I2C2, I2C_FLAG_AF);
I2C_AcknowledgeConfig(I2C2, ENABLE);
I2C_GenerateSTART(I2C2, ENABLE); //Start condition to start communicating with the slave
while(!(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT)));
I2C_Send7bitAddress(I2C2,0xD2, I2C_Direction_Transmitter);
while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
I2C_SendData(I2C2,reg);
while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_GenerateSTART(I2C2, ENABLE); //Start condition to start communicating with the slave
while(!(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT)));
I2C_Send7bitAddress(I2C2,0xD2, I2C_Direction_Receiver); //scl pb11
while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_RECEIVED));
valor = I2C_ReceiveData(I2C2);
I2C_AcknowledgeConfig(I2C2, DISABLE);
I2C_GenerateSTOP(I2C2, ENABLE);
while(I2C_GetFlagStatus(I2C2, I2C_FLAG_STOPF));
return valor;
}
void TIM2_IRQHandler(void)
{
char str[50] = {};
uint16_t IC2Value;
float DutyCycle, Frequency;
RCC_ClocksTypeDef RCC_Clocks;
RCC_GetClocksFreq(&RCC_Clocks);
if(TIM_GetITStatus(TIM2, TIM_IT_CC2) == SET)
{
TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);
}
if(TIM_GetITStatus(TIM2, TIM_IT_CC1) == SET)
{
TIM_ClearITPendingBit(TIM2, TIM_IT_CC1);
}
IC2Value = TIM_GetCapture2(TIM2);
if (IC2Value != 0) {
DutyCycle = (float)(TIM_GetCapture1(TIM2) * 100) / IC2Value;
Frequency = (float) RCC_Clocks.SYSCLK_Frequency / IC2Value;
} else {
DutyCycle = 0;
Frequency = 0;
}
pitch = DutyCycle;
}
int main(void)
{
RCC_Config_HSI_PLL_Max(); // SYSCLK 20 MHZ - PLL
USART_INIT();
init();
ENCODER_PITCH();
while(1)
{
registos();
}
}
2019-02-04 11:30 AM
>>Is there any known conflict between I2C2 and TIM2?
Check the errata
The F1 remaps peripheral pins as a block, and yes there are conflicting combinations. USART RTS/CTS with CAN is one example, you needed to remap CAN off someplace else even when not used.
The F1 is an old design, newer designs have more flexible pin level mapping.