2017-07-10 1 views
1

J'expérimente avec du code générateur VGA par Artekit, au https://www.artekit.eu/vga-output-using-a-36-pin-stm32/. Ce code génère un signal PWM pour HSYNC en utilisant le canal TIM2 2, qui est sorti sur le port PA1. Tout cela fonctionne correctement. Maintenant, je voudrais remapper TIM2 de sorte que le signal PWM est remappé sur la broche PB3. Après avoir appelé GPIO_PinRemapConfig(GPIO_FullRemap_TIM2, ENABLE), le signal PWM n'apparaît plus sur PA1 mais n'apparaît pas sur PB3 bien que toutes les interruptions de minuterie continuent à fonctionner normalement. Qu'est-ce que je rate?STM32F103 Minuteur remappage de fonction

configuration RCC est la suivante:

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); 
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); 
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_SPI1 | RCC_APB2Periph_TIM1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE); 

code correspondant est ci-dessous.

GPIO_InitTypeDef GPIO_InitStructure; 
NVIC_InitTypeDef nvic; 
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; 
TIM_OCInitTypeDef TIM_OCInitStructure; 
u32 TimerPeriod = 0; 
u16 Channel1Pulse = 0, Channel2Pulse = 0, Channel3Pulse = 0; 

// Remap PA1 -> PB3 
GPIO_PinRemapConfig(GPIO_FullRemap_TIM2, ENABLE); 

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; 
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; 
GPIO_Init(GPIOA, &GPIO_InitStructure); 

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; 
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; 
GPIO_Init(GPIOB, &GPIO_InitStructure); 

TimerPeriod = 2048; 
Channel1Pulse = 144;  /* HSYNC */ 
Channel2Pulse = 352;   /* HSYNC + BACK PORCH */ 

TIM_TimeBaseStructure.TIM_Prescaler = 0; 
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; 
TIM_TimeBaseStructure.TIM_Period = TimerPeriod; 
TIM_TimeBaseStructure.TIM_ClockDivision = 0; 
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; 
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); 

TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; 
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; 
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; 
TIM_OCInitStructure.TIM_Pulse = Channel1Pulse; 
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; 
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High; 
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset; 
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Set; 

TIM_OC1Init(TIM1, &TIM_OCInitStructure); 

TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Inactive; 
TIM_OCInitStructure.TIM_Pulse = Channel2Pulse; 
TIM_OC2Init(TIM1, &TIM_OCInitStructure); 

/* TIM1 counter enable and output enable */ 
TIM_CtrlPWMOutputs(TIM1, ENABLE); 

/* Select TIM1 as Master */ 
TIM_SelectMasterSlaveMode(TIM1, TIM_MasterSlaveMode_Enable); 
TIM_SelectOutputTrigger(TIM1, TIM_TRGOSource_Update); 

TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Gated); 
TIM_SelectInputTrigger(TIM2, TIM_TS_ITR0); 

TimerPeriod = 625;  /* Vertical lines */ 
Channel2Pulse = 2;  /* Sync pulse */ 
Channel3Pulse = 24;  /* Sync pulse + Back porch */ 
TIM_TimeBaseStructure.TIM_Prescaler = 0; 
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; 
TIM_TimeBaseStructure.TIM_Period = TimerPeriod; 
TIM_TimeBaseStructure.TIM_ClockDivision = 0; 
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; 

TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); 

TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; 
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; 
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; 
TIM_OCInitStructure.TIM_Pulse = Channel2Pulse; 
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; 
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High; 
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset; 
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Set; 
TIM_OC2Init(TIM2, &TIM_OCInitStructure); 

TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Inactive; 
TIM_OCInitStructure.TIM_Pulse = Channel3Pulse; 
TIM_OC3Init(TIM2, &TIM_OCInitStructure); 

/* TIM2 counter enable and output enable */ 
TIM_CtrlPWMOutputs(TIM2, ENABLE); 

/* Interrupt TIM2 */ 
nvic.NVIC_IRQChannel = TIM2_IRQn; 
nvic.NVIC_IRQChannelPreemptionPriority = 1; 
nvic.NVIC_IRQChannelSubPriority = 0; 
nvic.NVIC_IRQChannelCmd = ENABLE; 

NVIC_Init(&nvic); 
TIM_ITConfig(TIM2, TIM_IT_CC3, ENABLE); 

/* Interrupt TIM1 */ 
nvic.NVIC_IRQChannel = TIM1_CC_IRQn; 
nvic.NVIC_IRQChannelPreemptionPriority = 1; 
nvic.NVIC_IRQChannelSubPriority = 0; 
nvic.NVIC_IRQChannelCmd = ENABLE; 

NVIC_Init(&nvic); 
TIM_ITConfig(TIM1, TIM_IT_CC2, ENABLE); 

TIM_Cmd(TIM2, ENABLE); 
TIM_Cmd(TIM1, ENABLE); 
+0

le signal est toujours sur pa1? C'est assez haut niveau de choses hal, mais regarde soit remap complète ou remappage partiel 0b01 devrait mettre timer2 channel2 sur pb3. –

+0

ahh recherche pb3 dans les docs, pb3 est utilisé pour jtag/swd regardez le registre SWJ_CFG/bits ... changez-les en 0b010 afin que vous puissiez toujours avoir la fonctionnalité SWD. –

+0

même registre AFIO_MAPR qui contrôle les broches de fonction alternative TIM2 –

Répondre

1

Merci @old_timer, ça m'a mis sur la bonne voie. SWO est activé par défaut, qui est sur PB3 et doit être désactivé.

GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); 
GPIO_PinRemapConfig(GPIO_FullRemap_TIM2, ENABLE); 

fait l'affaire. Les deux remappages doivent être faits séparément, leur combinaison ne fonctionne pas.