void PWD_Config(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;//定时器初始化结构 TIM_ICInitTypeDef TIM_ICInitStructure; //通道输入初始化结构 GPIO_InitTypeDef GPIO_InitStructure; //浮动输入方式 GPIO_InitStructure.GPIO_Pin = /* GPIO_Pin_0 | */GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; GPIO_Init(GPIOB, &GPIO_InitStructure); //输出初始化 TIM_TimeBaseStructure.TIM_Period = 65535; //周期 TIM_TimeBaseStructure.TIM_Prescaler = 720; //时钟分频 TIM_TimeBaseStructure.TIM_ClockDivision = 0; //时钟分割 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//模式 TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);//基本初始化 TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //捕捉初始化 TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling;//下降沿 TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;//管脚与寄存器对应关系 TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;//分频器 TIM_ICInitStructure.TIM_ICFilter = 0x4; //滤波设置,经历几个周期跳变认定波形稳定0x0~0xF TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;//通道选择 // TIM_ICInit(TIM2, &TIM_ICInitStructure); //初始化 TIM_ICInit(TIM4, &TIM_ICInitStructure); //初始化 TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;//通道选择 TIM_ICInit(TIM2, &TIM_ICInitStructure); //初始化 TIM_ICInitStructure.TIM_Channel = TIM_Channel_3;//通道选择 TIM_ICInit(TIM2, &TIM_ICInitStructure); //初始化 TIM_ICInitStructure.TIM_Channel = TIM_Channel_4;//通道选择 TIM_ICInit(TIM2, &TIM_ICInitStructure); //初始化 TIM_SelectInputTrigger(TIM2, TIM_TS_TI1FP1); //选择时钟触发源 TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset);//触发方式 TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable); //启动定时器的被动触发 TIM_ITConfig(TIM2, /*TIM_IT_CC1|*/TIM_IT_CC2|TIM_IT_CC3|TIM_IT_CC4, ENABLE); //打开中断 TIM_SelectInputTrigger(TIM4, TIM_TS_TI1F_ED); //选择时钟触发源 TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_Reset);//触发方式 TIM_SelectMasterSlaveMode(TIM4, TIM_MasterSlaveMode_Enable); //启动定时器的被动触发 TIM_ITConfig(TIM4, TIM_IT_CC1, ENABLE); //打开中断 TIM_Cmd(TIM2, ENABLE); //启动TIM2 TIM_Cmd(TIM4, ENABLE); }
// Here I use the tim15 as the COM trigger for tim1 // TIM15 can use DMA channel 5 to update it's pre-load values void init_tim15(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //NVIC_InitTypeDef NVIC_InitStructure; TIM_TimeBaseStructure.TIM_Period = 200-1;// 50Hz 0xFFFF; TIM_TimeBaseStructure.TIM_Prescaler = 1000; //Down to 48K//(uint16_t) (SystemCoreClock / 24000000) - 1; TIM_TimeBaseStructure.TIM_ClockDivision = 0x0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM15, &TIM_TimeBaseStructure); /* Select the Master Slave Mode */ TIM_SelectMasterSlaveMode(TIM15, TIM_MasterSlaveMode_Enable); /* Master Mode selection */ TIM_SelectOutputTrigger(TIM15, TIM_TRGOSource_Update); //NVIC_InitStructure.NVIC_IRQChannel = TIM15_IRQn; //NVIC_InitStructure.NVIC_IRQChannelPriority = 1; //NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //NVIC_Init(&NVIC_InitStructure); //TIM_ITConfig(TIM15, TIM_IT_Update, ENABLE); // enable tim15 //TIM_Cmd(TIM15, ENABLE); }
void config_tim3( void ) { NVIC_InitTypeDef NVIC_InitStructure; TIM_ICInitTypeDef TIM_ICInitStructure; /* Enable the TIM3 global Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); TIM_ICStructInit( &TIM_ICInitStructure ); TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; TIM_ICInitStructure.TIM_ICFilter = 0x0; TIM_PWMIConfig(TIM3, &TIM_ICInitStructure); /* Select the TIM3 Input Trigger: TI2FP1 */ TIM_SelectInputTrigger(TIM3, TIM_TS_TI1FP1); /* Select the slave Mode: Reset Mode */ TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset); /* Enable the Master/Slave Mode */ TIM_SelectMasterSlaveMode(TIM3, TIM_MasterSlaveMode_Enable); /* TIM enable counter */ TIM_Cmd(TIM3, ENABLE); /* Enable the CC1 Interrupt Request */ TIM_ITConfig(TIM3, TIM_IT_CC1, ENABLE); }
void Freq_Meter_Init(void) { /* TIM Configuration */ TIM_Config(); /* TIM4 configuration: PWM Input mode ------------------------ The external signal is connected to TIM4 CH2 pin (PB.07), The Rising edge is used as active edge, The TIM4 CCR2 is used to compute the frequency value The TIM4 CCR1 is used to compute the duty cycle value ------------------------------------------------------------ */ TIM_ICInitStructure.TIM_Channel = TIM_Channel_2; TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; TIM_ICInitStructure.TIM_ICFilter = 0x0; TIM_PWMIConfig(TIM4, &TIM_ICInitStructure); /* Select the TIM4 Input Trigger: TI2FP2 */ TIM_SelectInputTrigger(TIM4, TIM_TS_TI2FP2); /* Select the slave Mode: Reset Mode */ TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_Reset); TIM_SelectMasterSlaveMode(TIM4,TIM_MasterSlaveMode_Enable); /* TIM enable counter */ TIM_Cmd(TIM4, ENABLE); /* Enable the CC2 Interrupt Request */ TIM_ITConfig(TIM4, TIM_IT_CC2, ENABLE); }
void TIM4_Init(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_ICInitTypeDef TIM_ICInitStructure; GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; /* TIM4 clock enable */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); /* GPIOB clock enable */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); /* TIM4 chennel2 configuration : PB.07 */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; 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(GPIOB, &GPIO_InitStructure); /* Connect TIM pin to AF2 */ GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_TIM4); TIM_TimeBaseStructure.TIM_Period = 0xffff; //设置自动重装载寄存期的值 TIM_TimeBaseStructure.TIM_Prescaler =83; //设置用来作为TIMx时钟频率除数的预分频值 1Mhz的计数频率 TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV4; //设置时钟分割:TDTS = Tck_tim TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式 TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位 TIM_ICInitStructure.TIM_Channel = TIM_Channel_2; TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV4; TIM_ICInitStructure.TIM_ICFilter = 0x0; TIM_PWMIConfig(TIM4, &TIM_ICInitStructure); /* Select the TIM4 Input Trigger: TI2FP2 */ TIM_SelectInputTrigger(TIM4, TIM_TS_TI2FP2); /* Select the slave Mode: Reset Mode */ TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_Reset); TIM_SelectMasterSlaveMode(TIM4,TIM_MasterSlaveMode_Enable); /* TIM enable counter */ TIM_Cmd(TIM4, ENABLE); /* Enable the CC2 Interrupt Request */ /* Enable the TIM4 global Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); }
// 计时器设置为PWM捕获器,此时只能捕获1路 // eg: TIM5, CH2, 捕获PA1 void Timer::mode_pwm_input(PinTypedef p) { Pin pin(p); // 函数调用后变量就消失了 uint8_t tmp = this->GPIO_AF_TIM(this->TIM); // 看看tmp有没有问题 pin.mode_pwm_input(tmp); NVIC_InitTypeDef NVIC_InitStructure; // 中断初始化器 NVIC_InitStructure.NVIC_IRQChannel = this->IRQn; // 低频高优先级原则,20mS的捕获中断设为最高优先级 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // IRQ 通道使能 NVIC_Init(&NVIC_InitStructure); // 时钟预分频 TIM_TimeBaseInitTypeDef TIM_TimeBaseStructrue; // 计时器分频初始化器 TIM_TimeBaseStructrue.TIM_Prescaler = PRESCALER; TIM_TimeBaseStructrue.TIM_Prescaler = PRESCALER; switch (this->TIM_No) { case (1): case (8): case (9): case (10): case (11): { TIM_TimeBaseStructrue.TIM_Prescaler = PRESCALER_APB2; break; } } TIM_TimeBaseStructrue.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructrue.TIM_Period = PERIOD; TIM_TimeBaseStructrue.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInit(this->TIM, &TIM_TimeBaseStructrue); // 设置TIM5 CH2 pin为外部信号输入 // CCR2测频率 // CCR1测占空比 TIM_ICInitTypeDef TIM_ICInitStructure; // 计时器模块初始化器 TIM_ICInitStructure.TIM_Channel = TIM_Channel_2; // input channel 2 TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; // 上升沿中断 TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; // map IC1 to TI1 TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; // 输入分频,不分频 TIM_ICInitStructure.TIM_ICFilter = 0x00; //滤波设置,经历几个周期跳变认定波形稳定0x0~0xF TIM_PWMIConfig(this->TIM, &TIM_ICInitStructure); /* Select the TIM5 Input Trigger: TI2FP2 */ TIM_SelectInputTrigger(this->TIM, TIM_TS_TI2FP2); TIM_SelectSlaveMode(this->TIM,TIM_SlaveMode_Reset);//TIM从模式:触发信号的上升沿重新初始化计数器和触发寄存器的更新事件 TIM_SelectMasterSlaveMode(this->TIM,TIM_MasterSlaveMode_Enable); //启动定时器的被动触发 TIM_Cmd(this->TIM, ENABLE); // run TIM5 // 设置中断ISR为PWM Input模式中断 // this->set_IRQHandler(Timer::PWM_Input_Handler_Dispatch); if ((TIM_No==1)||(TIM_No==8)) TIM_ITConfig(this->TIM, TIM_IT_Update, ENABLE); // 打开中断,不要 else TIM_ITConfig(this->TIM, TIM_IT_CC2, ENABLE); // 打开中断,TIM_IT_Update不要 }
//timer 1 void pwmInit(void) { GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; TIM_ICInitTypeDef TIM_ICInitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; pwmSetConstants(); // TIM1 channel 1 pin (PA.08) configuration GPIO_InitStructure.GPIO_Pin = PWM_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(PWM_PORT, &GPIO_InitStructure); // Enable the TIM1 global Interrupt NVIC_InitStructure.NVIC_IRQChannel = PWM_IRQ; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_Prescaler = (PWM_CLK_DIVISOR-1); TIM_TimeBaseStructure.TIM_Period = 0xffff; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(PWM_TIM, &TIM_TimeBaseStructure); TIM_ICInitStructure.TIM_Channel = PWM_CHANNEL; TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; TIM_ICInitStructure.TIM_ICFilter = 0x0; TIM_PWMIConfig(PWM_TIM, &TIM_ICInitStructure); // Select the TIM Input Trigger: TI1FP1 // 滤波后的定时器输入1(TI1FP1) TIM_SelectInputTrigger(PWM_TIM, TIM_TS_TI1FP1); // Select the slave Mode: Reset Mode TIM_SelectSlaveMode(PWM_TIM, TIM_SlaveMode_Reset);//复位模式 // Enable the Master/Slave Mode TIM_SelectMasterSlaveMode(PWM_TIM, TIM_MasterSlaveMode_Enable); // TIM enable counter TIM_Cmd(PWM_TIM, ENABLE); pwmIsrAllOn(); }
/** * @brief Main program * @param None * @retval None */ int main(void) { /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup files (startup_stm32f40_41xxx.s/startup_stm32f427_437xx.s/startup_stm32f429_439xx.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f4xx.c file */ /* TIM Configuration */ TIM_Config(); /* --------------------------------------------------------------------------- TIM4 configuration: PWM Input mode In this example TIM4 input clock (TIM4CLK) is set to 2 * APB1 clock (PCLK1), since APB1 prescaler is different from 1. TIM4CLK = 2 * PCLK1 PCLK1 = HCLK / 4 => TIM4CLK = HCLK / 2 = SystemCoreClock /2 External Signal Frequency = TIM4 counter clock / TIM4_CCR2 in Hz. External Signal DutyCycle = (TIM4_CCR1*100)/(TIM4_CCR2) in %. --------------------------------------------------------------------------- */ TIM_ICInitStructure.TIM_Channel = TIM_Channel_2; TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; TIM_ICInitStructure.TIM_ICFilter = 0x0; TIM_PWMIConfig(TIM4, &TIM_ICInitStructure); /* Select the TIM4 Input Trigger: TI2FP2 */ TIM_SelectInputTrigger(TIM4, TIM_TS_TI2FP2); /* Select the slave Mode: Reset Mode */ TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_Reset); TIM_SelectMasterSlaveMode(TIM4,TIM_MasterSlaveMode_Enable); /* TIM enable counter */ TIM_Cmd(TIM4, ENABLE); /* Enable the CC2 Interrupt Request */ TIM_ITConfig(TIM4, TIM_IT_CC2, ENABLE); while (1); }
/*采用PA.0 作为外部脉冲计数*/ void pulse_init( void ) { GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; TIM_ICInitTypeDef TIM_ICInitStructure; /* TIM5 clock enable */ RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM5, ENABLE ); /* GPIOA clock enable */ RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOA, ENABLE ); /* TIM5 chennel1 configuration : PA.0 */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; 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 TIM pin to AF0 */ GPIO_PinAFConfig( GPIOA, GPIO_PinSource0, GPIO_AF_TIM5 ); /* Enable the TIM5 global Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init( &NVIC_InitStructure ); TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; TIM_ICInitStructure.TIM_ICFilter = 0x0; TIM_PWMIConfig( TIM5, &TIM_ICInitStructure ); /* Select the TIM5 Input Trigger: TI1FP1 */ TIM_SelectInputTrigger( TIM5, TIM_TS_TI1FP1 ); /* Select the slave Mode: Reset Mode */ TIM_SelectSlaveMode( TIM5, TIM_SlaveMode_Reset ); TIM_SelectMasterSlaveMode( TIM5, TIM_MasterSlaveMode_Enable ); /* TIM enable counter */ TIM_Cmd( TIM5, ENABLE ); /* Enable the CC2 Interrupt Request */ TIM_ITConfig( TIM5, TIM_IT_CC2, ENABLE ); }
/** * @brief Main program * @param None * @retval None */ int main(void) { /*!< 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 */ /* System Clocks Configuration */ RCC_Configuration(); /* NVIC configuration */ NVIC_Configuration(); /* Configure the GPIO ports */ GPIO_Configuration(); /* TIM3 configuration: PWM Input mode ------------------------ The external signal is connected to TIM3 CH2 pin (PA.01), The Rising edge is used as active edge, The TIM3 CCR2 is used to compute the frequency value The TIM3 CCR1 is used to compute the duty cycle value ------------------------------------------------------------ */ TIM_ICInitStructure.TIM_Channel = TIM_Channel_2; TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; TIM_ICInitStructure.TIM_ICFilter = 0x0; TIM_PWMIConfig(TIM3, &TIM_ICInitStructure); /* Select the TIM3 Input Trigger: TI2FP2 */ TIM_SelectInputTrigger(TIM3, TIM_TS_TI2FP2); /* Select the slave Mode: Reset Mode */ TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset); /* Enable the Master/Slave Mode */ TIM_SelectMasterSlaveMode(TIM3, TIM_MasterSlaveMode_Enable); /* TIM enable counter */ TIM_Cmd(TIM3, ENABLE); /* Enable the CC2 Interrupt Request */ TIM_ITConfig(TIM3, TIM_IT_CC2, ENABLE); while (1); }
void TIM2_PWMINPUT_INIT(u16 arr,u16 psc) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //TIM??????? NVIC_InitTypeDef NVIC_InitStructure; //???? TIM_ICInitTypeDef TIM2_ICInitStructure; //TIM2 PWM????? GPIO_InitTypeDef GPIO_InitStructure; //IO?????? RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //Open TIM2 clock // RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //open gpioB clock RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE); //??GPIO???AFIO???????? GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE); //??JTAG GPIO_PinRemapConfig(GPIO_FullRemap_TIM2, ENABLE); //Timer2????? TIM2_CH2->PB3 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; //GPIO 3 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //???? ???? GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); TIM_TimeBaseStructure.TIM_Period = arr; //??????????????????????????? TIM_TimeBaseStructure.TIM_Prescaler =psc; //??????TIMx??????????? TIM_TimeBaseStructure.TIM_ClockDivision = 0; //??????:TDTS = Tck_tim TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM?????? TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //??TIM_TimeBaseInitStruct?????????TIMx??????? /*???????*/ NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); TIM2_ICInitStructure.TIM_Channel = TIM_Channel_2; TIM2_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; TIM2_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; TIM2_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; TIM2_ICInitStructure.TIM_ICFilter = 0x3; //Filter:?? TIM_PWMIConfig(TIM2, &TIM2_ICInitStructure); //PWM???? TIM_SelectInputTrigger(TIM2, TIM_TS_TI2FP2); //??????? TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset); //????????? TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable);//?????????? TIM_ITConfig(TIM2, TIM_IT_CC2|TIM_IT_Update, ENABLE); //???? TIM_ClearITPendingBit(TIM2, TIM_IT_CC2|TIM_IT_Update); //??????? TIM_Cmd(TIM2, ENABLE); }
//-------------------------------------------------------------- // interne Funktion // Init vom Timer //-------------------------------------------------------------- void P_ICPWM_InitTIM(void) { TIM_ICInitTypeDef TIM_ICInitStructure; // Clock enable RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); // Vorteiler einstellen TIM_PrescalerConfig(TIM2, ICPWM_TIM2_PRESCALE, TIM_PSCReloadMode_Immediate); if(ICPWM_TIM2.CHANNEL==1) { // Channel 1 TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; TIM_ICInitStructure.TIM_ICFilter = 0x0; TIM_PWMIConfig(TIM2, &TIM_ICInitStructure); // input Trigger TIM_SelectInputTrigger(TIM2, TIM_TS_TI1FP1); } if(ICPWM_TIM2.CHANNEL==2) { // Channel 2 TIM_ICInitStructure.TIM_Channel = TIM_Channel_2; TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; TIM_ICInitStructure.TIM_ICFilter = 0x0; TIM_PWMIConfig(TIM2, &TIM_ICInitStructure); // input Trigger TIM_SelectInputTrigger(TIM2, TIM_TS_TI2FP2); } // Slave-Mode (Reset) TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset); TIM_SelectMasterSlaveMode(TIM2,TIM_MasterSlaveMode_Enable); // Timer enable TIM_Cmd(TIM2, ENABLE); }
void TIM2_Init(void) { TIM_ICInitTypeDef TIM_ICInitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE); TIM_ICInitStructure.TIM_Channel = TIM_Channel_2; TIM_ICInitStructure.TIM_ICFilter = 0x00; TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; TIM_PWMIConfig(TIM2,&TIM_ICInitStructure); TIM_SelectInputTrigger(TIM2,TIM_TS_TI2FP2); TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset); TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable); TIM_Cmd(TIM2, ENABLE); }
/******************************************************************************** * FunctionName: MyTIM1CaptureInit * * Description : * * Parameters : * * Returns : *******************************************************************************/ void MyTIM1CaptureInit(void) { GPIO_InitTypeDef GPIO_InitStructure; TIM_ICInitTypeDef TIM_ICInitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE); TIM_InternalClockConfig(TIM1); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); /** * 计数0-0xFFFF,分频71。则周期为1S,溢出一次时间为1uS*0xFFFF=65ms */ TIM_TimeBaseInitStructure.TIM_Period = 0xFFFF; // 计数周期 TIM_TimeBaseInitStructure.TIM_Prescaler = 71; // 72MHz / (71+1) = 1000KHz = 1M -->1uS TIM_TimeBaseInitStructure.TIM_ClockDivision = 0; TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; // 上升计数 TIM_TimeBaseInit(TIM1, &TIM_TimeBaseInitStructure); TIM_ITConfig(TIM1, TIM_IT_Update, DISABLE); // 禁止溢出中断 TIM_ClearFlag(TIM1, TIM_FLAG_Update); TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; // 通道1输入捕获 TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling; // 下降沿触发 TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; // 每次检测到都触发一次捕获 TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; // TI1被连接到IC1 TIM_ICInitStructure.TIM_ICFilter = 0x0; TIM_PWMIConfig(TIM1, &TIM_ICInitStructure); TIM_SelectInputTrigger(TIM1, TIM_TS_TI1FP1); // 选择触发信号 TIM_SelectSlaveMode(TIM1, TIM_SlaveMode_Reset); // 选中触发信号的下降沿重新初始化计数器并触发寄存器更新 TIM_SelectMasterSlaveMode(TIM1, TIM_MasterSlaveMode_Enable); // 使能主从模式 TIM_ITConfig(TIM1, TIM_IT_CC1, DISABLE); TIM_ClearFlag(TIM1, TIM_FLAG_CC1); TIM_Cmd(TIM1, ENABLE); TIM_ITConfig(TIM1, TIM_IT_CC1, ENABLE); }
void Tim1_cfg1() { TIM_ICInitTypeDef TIM_ICInitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; /* TIM3 configuration: PWM Input mode ------------------------ The external signal is connected to TIM4 CH2 pin (PB.07), The Rising edge is used as active edge, The TIM4 CCR2 is used to compute the frequency value The TIM4 CCR1 is used to compute the duty cycle value ------------------------------------------------------------ */ TIM_ICInitStructure.TIM_Channel = TIM_Channel_2; TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; TIM_ICInitStructure.TIM_ICFilter = 0x0; TIM_PWMIConfig(TIM1, &TIM_ICInitStructure); TIM_TimeBaseStructure.TIM_Period = 0xFFFF; //周期0~FFFF TIM_TimeBaseStructure.TIM_Prescaler = 32-1; //时钟分频,分频数为4分频(尽可以测0~2.7ms的脉宽,故仅适用于舵机信号解码) TIM_TimeBaseStructure.TIM_ClockDivision = 0; //时钟分割 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//模式 TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);//基本初始化 /* Select the TIM3 Input Trigger: TI2FP2 */ TIM_SelectInputTrigger(TIM1, TIM_TS_TI2FP2);//设置IC2为中断触发源,这个导致一个定时器只能捕捉1个PWM /* Select the slave Mode: Reset Mode */ TIM_SelectSlaveMode(TIM1, TIM_SlaveMode_Reset); /* Enable the Master/Slave Mode */ TIM_SelectMasterSlaveMode(TIM1, TIM_MasterSlaveMode_Enable); /* TIM enable counter */ TIM_Cmd(TIM1, ENABLE); /* Enable the CC2 Interrupt Request */ TIM_ITConfig(TIM1, TIM_IT_CC2, ENABLE); }
void us_ticker_init(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; if (us_ticker_inited) return; us_ticker_inited = 1; // Enable Timers clock RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); // Time base configuration // TIM1 is used as "master", "TIM4" as "slave". TIM4 is clocked by TIM1. TIM_TimeBaseStructure.TIM_Period = 0xFFFF; TIM_TimeBaseStructure.TIM_Prescaler = (uint16_t)(SystemCoreClock / 1000000) - 1; // 1 µs tick TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); // Master timer configuration TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 0; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(TIM1, &TIM_OCInitStructure); TIM_SelectMasterSlaveMode(TIM1, TIM_MasterSlaveMode_Enable); TIM_SelectOutputTrigger(TIM1, TIM_TRGOSource_Update); // Slave timer configuration TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_Gated); TIM_SelectInputTrigger(TIM4, TIM_TS_ITR0); // Enable timers TIM_Cmd(TIM4, ENABLE); TIM_Cmd(TIM1, ENABLE); }
/** * @brief Configure the TIM IRQ Handler. * @param None * @retval None */ static void TIM_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; TIM_ICInitTypeDef TIM_ICInitStructure; /* TIM2 clock enable */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); /* GPIOB clock enable */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE); /* TIM2 chennel2 configuration : PB.03 */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; 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_UP ; GPIO_Init(GPIOB, &GPIO_InitStructure); /* Connect TIM pin to AF2 */ GPIO_PinAFConfig(GPIOB, GPIO_PinSource3, GPIO_AF_2); /* Enable the TIM2 global Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /* --------------------------------------------------------------------------- TIM2 configuration: PWM Input mode The external signal is connected to TIM2 CH2 pin (PB.03) TIM2 CCR2 is used to compute the frequency value TIM2 CCR1 is used to compute the duty cycle value In this example TIM2 input clock (TIM2CLK) is set to APB1 clock (PCLK1), since APB1 prescaler is set to 1. TIM2CLK = PCLK1 = HCLK = SystemCoreClock External Signal Frequency = SystemCoreClock / TIM2_CCR2 in Hz. External Signal DutyCycle = (TIM2_CCR1*100)/(TIM2_CCR2) in %. Note: SystemCoreClock variable holds HCLK frequency and is defined in system_stm32f0xx.c file. Each time the core clock (HCLK) changes, user had to call SystemCoreClockUpdate() function to update SystemCoreClock variable value. Otherwise, any configuration based on this variable will be incorrect. --------------------------------------------------------------------------- */ TIM_ICInitStructure.TIM_Channel = TIM_Channel_2; TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; TIM_ICInitStructure.TIM_ICFilter = 0x0; 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); }
/** * @brief Initialize the RC5 decoder module ( Time range) * @param None * @retval None */ void RC5_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; TIM_ICInitTypeDef TIM_ICInitStructure; /* Clock Configuration for TIMER */ RCC_APB1PeriphClockCmd(IR_TIM_CLK , ENABLE); /* Enable Button GPIO clock */ RCC_AHBPeriphClockCmd(IR_GPIO_PORT_CLK , ENABLE); /* Pin configuration: input floating */ GPIO_InitStructure.GPIO_Pin = IR_GPIO_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(IR_GPIO_PORT, &GPIO_InitStructure); GPIO_PinAFConfig( IR_GPIO_PORT,IR_GPIO_SOURCE,GPIO_AF_2); /* Enable the TIM global Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = IR_TIM_IRQn ; NVIC_InitStructure.NVIC_IRQChannelPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /* TIMER frequency input */ TIM_PrescalerConfig(IR_TIM, TIM_PRESCALER, TIM_PSCReloadMode_Immediate); TIM_ICStructInit(&TIM_ICInitStructure); /* TIM configuration */ TIM_ICInitStructure.TIM_Channel = IR_TIM_Channel; TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling; TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; TIM_ICInitStructure.TIM_ICFilter = 0x0; TIM_PWMIConfig(IR_TIM, &TIM_ICInitStructure); /* Timer Clock */ TIMCLKValueKHz = TIM_GetCounterCLKValue()/1000; /* Select the TIM Input Trigger: TI2FP2 */ TIM_SelectInputTrigger(IR_TIM, TIM_TS_TI2FP2); /* Select the slave Mode: Reset Mode */ TIM_SelectSlaveMode(IR_TIM, TIM_SlaveMode_Reset); /* Enable the Master/Slave Mode */ TIM_SelectMasterSlaveMode(IR_TIM, TIM_MasterSlaveMode_Enable); /* Configures the TIM Update Request Interrupt source: counter overflow */ TIM_UpdateRequestConfig(IR_TIM, TIM_UpdateSource_Regular); RC5TimeOut = TIMCLKValueKHz * RC5_TIME_OUT_US/1000; /* Set the TIM auto-reload register for each IR protocol */ IR_TIM->ARR = RC5TimeOut; /* Clear update flag */ TIM_ClearFlag(IR_TIM, TIM_FLAG_Update); /* Enable TIM Update Event Interrupt Request */ TIM_ITConfig(IR_TIM, TIM_IT_Update, ENABLE); /* Enable the CC2/CC1 Interrupt Request */ TIM_ITConfig(IR_TIM, TIM_IT_CC2, ENABLE); /* Enable the CC2/CC1 Interrupt Request */ TIM_ITConfig(IR_TIM, TIM_IT_CC1, ENABLE); /* Enable the timer */ TIM_Cmd(IR_TIM, ENABLE); if (CECDemoStatus == 0) { /* Set the LCD Back Color */ LCD_SetBackColor(LCD_COLOR_RED); /* Set the LCD Text Color */ LCD_SetTextColor(LCD_COLOR_GREEN); LCD_DisplayStringLine(LCD_LINE_0, " STM320518-EVAL "); LCD_DisplayStringLine(LCD_LINE_1, " RC5 InfraRed Demo "); LCD_SetBackColor(LCD_COLOR_BLUE); /* Set the LCD Text Color */ LCD_SetTextColor(LCD_COLOR_WHITE); } /* Bit time range */ RC5MinT = (RC5_T_US - RC5_T_TOLERANCE_US) * TIMCLKValueKHz / 1000; RC5MaxT = (RC5_T_US + RC5_T_TOLERANCE_US) * TIMCLKValueKHz / 1000; RC5Min2T = (2 * RC5_T_US - RC5_T_TOLERANCE_US) * TIMCLKValueKHz / 1000; RC5Max2T = (2 * RC5_T_US + RC5_T_TOLERANCE_US) * TIMCLKValueKHz / 1000; /* Default state */ RC5_ResetPacket(); }
static void config_tim1( void ) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; TIM_BDTRInitTypeDef TIM_BDTRInitStructure; uint16_t TimerPeriod = 0; uint16_t Channel1Pulse = 0, Channel2Pulse = 0, Channel3Pulse = 0, Channel4Pulse = 0; /* Compute the value to be set in ARR register to generate signal frequency at 16 Khz */ //TimerPeriod = (SystemCoreClock / 16000) - 1; // In center aligned mode, counts up and down, so * 2. // TimerPeriod = (84000000 / ( 2 * 14000 )) - 1; TimerPeriod = 1000; /* Compute CCR1 value to generate a duty cycle at 50% for channel 1 */ //Channel1Pulse = (uint16_t) (((uint32_t) 5 * (TimerPeriod - 1)) / 10); Channel1Pulse = 500; /* Compute CCR2 value to generate a duty cycle at 25% for channel 2 */ //Channel2Pulse = (uint16_t) (((uint32_t) 25 * (TimerPeriod - 1)) / 100); Channel2Pulse = 250; /* Compute CCR3 value to generate a duty cycle at 12.5% for channel 3 */ //Channel3Pulse = (uint16_t) (((uint32_t) 125 * (TimerPeriod - 1)) / 1000); Channel3Pulse = 125; // pulse sent to other timer to trigger ADC; // 97 steps from 999 -> 999-97 = 902 Channel4Pulse = 902; /* Time Base configuration */ TIM_TimeBaseStructInit( &TIM_TimeBaseStructure ); // 14 MHz / 1000 steps == 14 kHz TIM_TimeBaseStructure.TIM_Prescaler = PRESCALER; //TIM_TimeBaseStructure.TIM_Prescaler = 65535; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_CenterAligned2; TIM_TimeBaseStructure.TIM_Period = TimerPeriod; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); /* Channel 1, 2 and 3 Configuration in PWM mode */ TIM_OCStructInit( &TIM_OCInitStructure ); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; 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_Low; TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset; TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Set; TIM_OC1Init(TIM1, &TIM_OCInitStructure); TIM_OCInitStructure.TIM_Pulse = Channel2Pulse; TIM_OC2Init(TIM1, &TIM_OCInitStructure); TIM_OCInitStructure.TIM_Pulse = Channel3Pulse; TIM_OC3Init(TIM1, &TIM_OCInitStructure); TIM_OCStructInit( &TIM_OCInitStructure ); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle; TIM_OCInitStructure.TIM_Pulse = Channel4Pulse; TIM_OC4Init(TIM1, &TIM_OCInitStructure); /* Automatic Output enable, Break, dead time and lock configuration*/ TIM_BDTRStructInit( &TIM_BDTRInitStructure ); TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable; TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable; TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1; TIM_BDTRInitStructure.TIM_DeadTime = 11; TIM_BDTRInitStructure.TIM_Break = TIM_Break_Enable; TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_Low; TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable; TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure); TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable); TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable); TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable); /* Master Mode selection and TRGO update output */ TIM_SelectOutputTrigger(TIM1, TIM_TRGOSource_OC4Ref); TIM_SelectMasterSlaveMode(TIM1, TIM_MasterSlaveMode_Enable); /* TIM1 counter enable */ TIM_Cmd(TIM1, ENABLE); /* Main Output Enable */ TIM_CtrlPWMOutputs(TIM1, ENABLE); }
/** * @brief Main program * @param None * @retval None */ int main(void) { /*!< 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 */ /* System Clocks Configuration */ RCC_Configuration(); /* Configure the GPIO ports */ GPIO_Configuration(); /* Timers synchronisation in cascade mode with an external trigger ----- 1/TIM1 is configured as Master Timer: - Toggle Mode is used - The TIM1 Enable event is used as Trigger Output 2/TIM1 is configured as Slave Timer for an external Trigger connected to TIM1 TI2 pin (TIM1 CH2 configured as input pin): - The TIM1 TI2FP2 is used as Trigger Input - Rising edge is used to start and stop the TIM1: Gated Mode. 3/TIM3 is slave for TIM1 and Master for TIM4, - Toggle Mode is used - The ITR1(TIM1) is used as input trigger - Gated mode is used, so start and stop of slave counter are controlled by the Master trigger output signal(TIM1 enable event). - The TIM3 enable event is used as Trigger Output. 4/TIM4 is slave for TIM3, - Toggle Mode is used - The ITR2(TIM3) is used as input trigger - Gated mode is used, so start and stop of slave counter are controlled by the Master trigger output signal(TIM3 enable event). * For Low-density, Medium-density, High-density and Connectivity line devices: The TIMxCLK is fixed to 72 MHZ, the Prescaler is equal to 2 so the TIMx clock counter is equal to 24 MHz. The Three Timers are running at: TIMx frequency = TIMx clock counter/ 2*(TIMx_Period + 1) = 162.1 KHz. * For Low-Density Value line and Medium-Density Value line devices: The TIMxCLK is fixed to 24 MHz, the Prescaler is equal to 2 so the TIMx clock counter is equal to 8 MHz. TIMx frequency = TIMx clock counter/ 2*(TIMx_Period + 1) = 54 KHz. The starts and stops of the TIM1 counters are controlled by the external trigger. The TIM3 starts and stops are controlled by the TIM1, and the TIM4 starts and stops are controlled by the TIM3. -------------------------------------------------------------------- */ /* Time base configuration */ TIM_TimeBaseStructure.TIM_Period = 73; TIM_TimeBaseStructure.TIM_Prescaler = 2; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_Period = 73; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_Period = 73; TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); /* Master Configuration in Toggle Mode */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 64; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(TIM1, &TIM_OCInitStructure); /* TIM1 Input Capture Configuration */ TIM_ICInitStructure.TIM_Channel = TIM_Channel_2; TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; TIM_ICInitStructure.TIM_ICFilter = 0; TIM_ICInit(TIM1, &TIM_ICInitStructure); /* TIM1 Input trigger configuration: External Trigger connected to TI2 */ TIM_SelectInputTrigger(TIM1, TIM_TS_TI2FP2); TIM_SelectSlaveMode(TIM1, TIM_SlaveMode_Gated); /* Select the Master Slave Mode */ TIM_SelectMasterSlaveMode(TIM1, TIM_MasterSlaveMode_Enable); /* Master Mode selection: TIM1 */ TIM_SelectOutputTrigger(TIM1, TIM_TRGOSource_Enable); /* Slaves Configuration: Toggle Mode */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OC1Init(TIM3, &TIM_OCInitStructure); TIM_OC1Init(TIM4, &TIM_OCInitStructure); /* Slave Mode selection: TIM3 */ TIM_SelectInputTrigger(TIM3, TIM_TS_ITR0); TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Gated); /* Select the Master Slave Mode */ TIM_SelectMasterSlaveMode(TIM3, TIM_MasterSlaveMode_Enable); /* Master Mode selection: TIM3 */ TIM_SelectOutputTrigger(TIM3, TIM_TRGOSource_Enable); /* Slave Mode selection: TIM4 */ TIM_SelectInputTrigger(TIM4, TIM_TS_ITR2); TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_Gated); /* TIM1 Main Output Enable */ TIM_CtrlPWMOutputs(TIM1, ENABLE); /* TIM enable counter */ TIM_Cmd(TIM1, ENABLE); TIM_Cmd(TIM3, ENABLE); TIM_Cmd(TIM4, ENABLE); while (1) {} }
/******************************************************************************* * Function Name : AutoClockCalibration * Description : Calibration of External crystal oscillator auto(through Timer peripheral) * Input : None * Output : None * Return : None *******************************************************************************/ void AutoClockCalibration(void) { RCC_ClocksTypeDef ClockValue; u16 u16_TimerPrescalerValue=0x0003; u16 u16_CountWait; u16 u16_DeviationInteger; u32 u32_CalibrationTimer; float f32_Deviation; TIM_ICInitTypeDef TIM_ICInitStructure; TIM_DeInit(TIM2); BKP_TamperPinCmd(DISABLE); BKP_RTCOutputConfig(BKP_RTCOutputSource_CalibClock); /* TIM2 configuration: PWM Input mode ------------------------ The external signal is connected to TIM2 CH2 pin (PA.01), The Rising edge is used as active edge, The TIM2 CCR2 is used to compute the frequency value The TIM2 CCR1 is used to compute the duty cycle value ------------------------------------------------------------ */ TIM_PrescalerConfig(TIM2,u16_TimerPrescalerValue,TIM_PSCReloadMode_Immediate); TIM_ICInitStructure.TIM_Channel = TIM_Channel_2; TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; TIM_ICInitStructure.TIM_ICFilter = 0x00; TIM_PWMIConfig(TIM2, &TIM_ICInitStructure); TIM_ICInit(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); /* Enable the Master/Slave Mode */ TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable); /* TIM enable u16_Counter */ TIM_Cmd(TIM2, ENABLE); /* Wait for 2 seconds */ u32_CalibrationTimer = RTC_GetCounter(); while((RTC_GetCounter() - u32_CalibrationTimer) < 2) { } RCC_GetClocksFreq(&ClockValue); u32_TimerFrequency=(ClockValue.PCLK1_Frequency * 2)/(u16_TimerPrescalerValue+1); /* Enable the CC2 Interrupt Request */ TIM_ITConfig(TIM2, TIM_IT_CC2, ENABLE); /* Wait for 2 seconds */ u32_CalibrationTimer = RTC_GetCounter(); while((RTC_GetCounter() - u32_CalibrationTimer) < 2) { } if(!(TIM_GetFlagStatus(TIM2, TIM_FLAG_CC1))) /* There is no signal at the timer TIM2 peripheral input */ { } else { /* Calulate Deviation in ppm using the formula : Deviation in ppm = (Deviation from 511.968/511.968)*1 million*/ if(f32_Frequency > 511.968) { f32_Deviation=((f32_Frequency-511.968)/511.968)*1000000; } else { f32_Deviation=((511.968-f32_Frequency)/511.968)*1000000; } u16_DeviationInteger = (u16)f32_Deviation; if(f32_Deviation >= (u16_DeviationInteger + 0.5)) { u16_DeviationInteger = ((u16)f32_Deviation)+1; } u16_CountWait=0; /* Frequency deviation in ppm should be les than equal to 121 ppm*/ if(u16_DeviationInteger <= 121) { while(u16_CountWait<128) { if(u8_CalibrationPpm[u16_CountWait] == u16_DeviationInteger) break; u16_CountWait++; } BKP_SetRTCCalibrationValue(u16_CountWait); u16_CountWait=u16_CountWait/10; u16_CountWait=u16_CountWait/10; if(u16_CountWait>0) { } } else /* Frequency deviation in ppm is more than 121 ppm, hence calibration can not be done */ { } } BKP_RTCOutputConfig(BKP_RTCOutputSource_None); TIM_ITConfig(TIM2, TIM_IT_CC2, DISABLE); TIM_Cmd(TIM2, DISABLE); TIM_DeInit(TIM2); u32_CalibrationTimer=RTC_GetCounter(); /* Wait for 2 seconds */ while((RTC_GetCounter() - u32_CalibrationTimer) < 5) { } //MenuInit(); }
void init_pwm(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_Period = (SYSTEM_FREQ/PWM_FREQ) - 1; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); TIM_OCInitStructure.TIM_OCMode = TIM_ForcedAction_InActive; // We may disable these output after initialize TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Disable; TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; TIM_OCInitStructure.TIM_Pulse = GET_DUTY(0); // 5% TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low; TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Set; TIM_OC1Init(TIM1, &TIM_OCInitStructure); //TIM_OCInitStructure.TIM_Pulse = GET_DUTY(30); // 5% TIM_OC2Init(TIM1, &TIM_OCInitStructure); //TIM_OCInitStructure.TIM_Pulse = GET_DUTY(10); // 5% TIM_OC3Init(TIM1, &TIM_OCInitStructure); // TIM4 CH4 is used to triggrt the ADC TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = GET_DUTY(1); // 5% TIM_OC4Init(TIM1, &TIM_OCInitStructure); //TIM_ForcedOC1Config(TIM1, TIM_ForcedAction_InActive); //TIM_ForcedOC2Config(TIM1, TIM_ForcedAction_InActive); //TIM_ForcedOC3Config(TIM1, TIM_ForcedAction_InActive); TIM1->BDTR |= (TIM_OSSRState_Enable | TIM_OSSIState_Enable); GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_2); GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_2); GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_2); GPIO_PinAFConfig(GPIOA, GPIO_PinSource11, GPIO_AF_2); GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_2); GPIO_PinAFConfig(GPIOB, GPIO_PinSource0, GPIO_AF_2); GPIO_PinAFConfig(GPIOB, GPIO_PinSource1, GPIO_AF_2); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_7; 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_UP ; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1; GPIO_Init(GPIOB, &GPIO_InitStructure); // We need update the timer settings by COM event // In this case, TIM15 and TIM17 can be used as COM trigger TIM_CCPreloadControl(TIM1, ENABLE); // Select TIM15 as the trigger TIM_SelectInputTrigger(TIM1, TIM_TS_ITR0); TIM_SelectMasterSlaveMode(TIM1, TIM_MasterSlaveMode_Enable); TIM_SelectCOM(TIM1, ENABLE); // Sometimes I will use the update event to trigger the ADC TIM_SelectOutputTrigger(TIM1, TIM_TRGOSource_Update); NVIC_InitStructure.NVIC_IRQChannel = TIM1_BRK_UP_TRG_COM_IRQn; NVIC_InitStructure.NVIC_IRQChannelPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn; NVIC_InitStructure.NVIC_IRQChannelPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); TIM_ITConfig(TIM1, TIM_IT_COM, ENABLE); //TIM_ITConfig(TIM1, TIM_IT_CC4, ENABLE); TIM_Cmd(TIM1, ENABLE); /* TIM1 Main Output Enable */ TIM_CtrlPWMOutputs(TIM1, ENABLE); //set_duty(1199); // close all channel //pwm_force_output(2,2,2); init_tim15(); }
/** * @brief Main program * @param None * @retval None */ int main(void) { /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup files (startup_stm32f40_41xxx.s/startup_stm32f427_437xx.s/startup_stm32f429_439xx.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f4xx.c file */ /* TIM2/3/4 Configuration */ TIM_Config(); /* Timers synchronisation in cascade mode ------------------------------------ 1/TIM2 is configured as Master Timer: - PWM Mode is used - The TIM2 Update event is used as Trigger Output 2/TIM3 is slave for TIM2 and Master for TIM4, - PWM Mode is used - The ITR1(TIM2) is used as input trigger - Gated mode is used, so start and stop of slave counter are controlled by the Master trigger output signal(TIM2 update event). - The TIM3 Update event is used as Trigger Output. 3/TIM4 is slave for TIM3, - PWM Mode is used - The ITR2(TIM3) is used as input trigger - Gated mode is used, so start and stop of slave counter are controlled by the Master trigger output signal(TIM3 update event). In this example TIM2 input clock (TIM2CLK) is set to 2 * APB1 clock (PCLK1), since APB1 prescaler is different from 1. TIM2CLK = 2 * PCLK1 PCLK1 = HCLK / 4 => TIM2CLK = HCLK / 2 = SystemCoreClock /2 The Master Timer TIM2 is running at TIM2 counter clock: TIM2 frequency = (TIM2 counter clock)/ (TIM2 period + 1) = 328.125 KHz and the duty cycle = TIM2_CCR1/(TIM2_ARR + 1) = 25%. The TIM3 is running: - At (TIM2 frequency)/ (TIM3 period + 1) = 82.02 KHz and a duty cycle equal to TIM3_CCR1/(TIM3_ARR + 1) = 25% The TIM4 is running: - At (TIM3 frequency)/ (TIM4 period + 1) = 20.5 KHz and a duty cycle equal to TIM4_CCR1/(TIM4_ARR + 1) = 25% Note: SystemCoreClock variable holds HCLK frequency and is defined in system_stm32f4xx.c file. Each time the core clock (HCLK) changes, user had to call SystemCoreClockUpdate() function to update SystemCoreClock variable value. Otherwise, any configuration based on this variable will be incorrect. --------------------------------------------------------------------------- */ /* Time base configuration */ TIM_TimeBaseStructure.TIM_Period = 255; TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_Period = 3; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_Period = 3; TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); /* Master Configuration in PWM1 Mode */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 64; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(TIM2, &TIM_OCInitStructure); /* Select the Master Slave Mode */ TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable); /* Master Mode selection */ TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update); /* Slaves Configuration: PWM1 Mode */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 1; TIM_OC1Init(TIM3, &TIM_OCInitStructure); TIM_OC1Init(TIM4, &TIM_OCInitStructure); /* Slave Mode selection: TIM3 */ TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Gated); TIM_SelectInputTrigger(TIM3, TIM_TS_ITR1); /* Select the Master Slave Mode */ TIM_SelectMasterSlaveMode(TIM3, TIM_MasterSlaveMode_Enable); /* Master Mode selection: TIM3 */ TIM_SelectOutputTrigger(TIM3, TIM_TRGOSource_Update); /* Slave Mode selection: TIM4 */ TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_Gated); TIM_SelectInputTrigger(TIM4, TIM_TS_ITR2); /* TIM enable counter */ TIM_Cmd(TIM3, ENABLE); TIM_Cmd(TIM2, ENABLE); TIM_Cmd(TIM4, ENABLE); while (1) { } }
void osdCoreInit(void) { GPIO_InitTypeDef gpio; TIM_TimeBaseInitTypeDef tim; NVIC_InitTypeDef nvic; DMA_InitTypeDef dma; SPI_InitTypeDef spi; TIM_OCInitTypeDef timoc; EXTI_InitTypeDef EXTI_InitStructure; // OSD mask Pins GPIO_StructInit(&gpio); gpio.GPIO_Pin = GPIO_Pin_6; // SPI1 MISO gpio.GPIO_Mode = GPIO_Mode_AF; gpio.GPIO_OType = GPIO_OType_PP; gpio.GPIO_Speed = GPIO_Speed_50MHz; gpio.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOA, &gpio); GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1); GPIO_StructInit(&gpio); gpio.GPIO_Pin = GPIO_Pin_5; // SPI1 CLK slave gpio.GPIO_Mode = GPIO_Mode_AF; gpio.GPIO_OType = GPIO_OType_PP; gpio.GPIO_Speed = GPIO_Speed_100MHz; gpio.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOA, &gpio); GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1); //OSD level pins gpio.GPIO_Pin = GPIO_Pin_2; // SPI2_MISO gpio.GPIO_Mode = GPIO_Mode_AF; gpio.GPIO_OType = GPIO_OType_PP; gpio.GPIO_Speed = GPIO_Speed_50MHz; gpio.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOC, &gpio); GPIO_PinAFConfig(GPIOC, GPIO_PinSource2, GPIO_AF_SPI2); gpio.GPIO_Pin = GPIO_Pin_13; // SPI2_SCK gpio.GPIO_Mode = GPIO_Mode_AF; gpio.GPIO_OType = GPIO_OType_PP; gpio.GPIO_Speed = GPIO_Speed_100MHz; gpio.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOB, &gpio); GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_SPI2); // HSYNC captrue timer: Start counting at HSYNC and start pixel timer after at correct x-position gpio.GPIO_Pin = GPIO_Pin_3; gpio.GPIO_Speed = GPIO_Speed_100MHz; gpio.GPIO_Mode = GPIO_Mode_AF; gpio.GPIO_OType = GPIO_OType_PP; //gpio.GPIO_PuPd = GPIO_PuPd_UP; gpio.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOB, &gpio); GPIO_PinAFConfig(GPIOB, GPIO_PinSource3, GPIO_AF_TIM2); TIM_TimeBaseStructInit(&tim); tim.TIM_Period = pios_video_type_cfg_act->dc * (pios_video_type_cfg_act->graphics_column_start + x_offset); tim.TIM_Prescaler = 0; tim.TIM_ClockDivision = 0; tim.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(HSYNC_CAPTURE_TIMER, &tim); TIM_SelectOnePulseMode(HSYNC_CAPTURE_TIMER, TIM_OPMode_Single); TIM_SelectSlaveMode(HSYNC_CAPTURE_TIMER, TIM_SlaveMode_Trigger); TIM_SelectInputTrigger(HSYNC_CAPTURE_TIMER, TIM_TS_TI2FP2); TIM_SelectMasterSlaveMode(HSYNC_CAPTURE_TIMER, TIM_MasterSlaveMode_Enable); TIM_SelectOutputTrigger(HSYNC_CAPTURE_TIMER, TIM_TRGOSource_Update); // Pixel timer: Outputs clock for SPI gpio.GPIO_Pin = GPIO_Pin_4; gpio.GPIO_Speed = GPIO_Speed_100MHz; gpio.GPIO_Mode = GPIO_Mode_AF; gpio.GPIO_OType = GPIO_OType_PP; gpio.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOB, &gpio); GPIO_PinAFConfig(GPIOB, GPIO_PinSource4, GPIO_AF_TIM3); // TIM_TimeBaseStructInit(&tim); // tim.TIM_Period = 10; // tim.TIM_Prescaler = 1; // tim.TIM_ClockDivision = 0; // tim.TIM_CounterMode = TIM_CounterMode_Up; // TIM_TimeBaseInit(PIXEL_TIMER, &tim); TIM_OCStructInit( &timoc ); timoc.TIM_OCMode = TIM_OCMode_PWM1; timoc.TIM_OutputState = TIM_OutputState_Enable; timoc.TIM_OutputNState = TIM_OutputNState_Disable; timoc.TIM_Pulse = 1; timoc.TIM_OCPolarity = TIM_OCPolarity_High; timoc.TIM_OCNPolarity = TIM_OCPolarity_High; timoc.TIM_OCIdleState = TIM_OCIdleState_Reset; timoc.TIM_OCNIdleState = TIM_OCNIdleState_Reset; TIM_OC1Init(PIXEL_TIMER, &timoc ); TIM_OC1PreloadConfig(PIXEL_TIMER, TIM_OCPreload_Enable); TIM_SetCompare1(PIXEL_TIMER, pios_video_type_cfg_act->dc); TIM_SetAutoreload(PIXEL_TIMER, pios_video_type_cfg_act->period); TIM_ARRPreloadConfig(PIXEL_TIMER, ENABLE); TIM_CtrlPWMOutputs(PIXEL_TIMER, ENABLE); TIM_SelectInputTrigger(PIXEL_TIMER, TIM_TS_ITR1); // Line counter: Counts number of HSYNCS (from hsync_capture) and triggers output of first visible line TIM_TimeBaseStructInit(&tim); tim.TIM_Period = 0xffff; tim.TIM_Prescaler = 0; tim.TIM_ClockDivision = 0; tim.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(LINE_COUNTER_TIMER, &tim); /* Enable the TIM4 gloabal Interrupt */ nvic.NVIC_IRQChannel = TIM4_IRQn; nvic.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGHEST; nvic.NVIC_IRQChannelSubPriority = 1; nvic.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&nvic); TIM_SelectInputTrigger(LINE_COUNTER_TIMER, TIM_TS_ITR1); TIM_SelectSlaveMode(LINE_COUNTER_TIMER, TIM_SlaveMode_External1); TIM_SelectOnePulseMode(LINE_COUNTER_TIMER, TIM_OPMode_Single); TIM_ITConfig(LINE_COUNTER_TIMER, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_CC4 | TIM_IT_COM | TIM_IT_Trigger | TIM_IT_Break, DISABLE); TIM_Cmd(LINE_COUNTER_TIMER, DISABLE); // init OSD mask SPI SPI_StructInit(&spi); spi.SPI_Mode = SPI_Mode_Slave; spi.SPI_Direction = SPI_Direction_1Line_Tx; spi.SPI_DataSize = SPI_DataSize_8b; spi.SPI_NSS = SPI_NSS_Soft; spi.SPI_FirstBit = SPI_FirstBit_MSB; spi.SPI_CRCPolynomial = 7; spi.SPI_CPOL = SPI_CPOL_Low; spi.SPI_CPHA = SPI_CPHA_2Edge; spi.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2; SPI_Init(OSD_MASK_SPI, &spi); SPI_StructInit(&spi); spi.SPI_Mode = SPI_Mode_Slave; spi.SPI_Direction = SPI_Direction_1Line_Tx; spi.SPI_DataSize = SPI_DataSize_8b; spi.SPI_NSS = SPI_NSS_Soft; spi.SPI_FirstBit = SPI_FirstBit_MSB; spi.SPI_CRCPolynomial = 7; spi.SPI_CPOL = SPI_CPOL_Low; spi.SPI_CPHA = SPI_CPHA_2Edge; spi.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2; SPI_Init(OSD_LEVEL_SPI, &spi); // Configure DMA for SPI - MASK_DMA DMA1_Channel3, LEVEL_DMA DMA1_Channel5 DMA_StructInit(&dma); dma.DMA_Channel = DMA_Channel_3; dma.DMA_PeripheralBaseAddr = (uint32_t)&(SPI1->DR); dma.DMA_DIR = DMA_DIR_MemoryToPeripheral; dma.DMA_BufferSize = BUFFER_WIDTH; dma.DMA_PeripheralInc = DMA_PeripheralInc_Disable; dma.DMA_MemoryInc = DMA_MemoryInc_Enable; dma.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; dma.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; dma.DMA_Mode = DMA_Mode_Normal; dma.DMA_Priority = DMA_Priority_VeryHigh; dma.DMA_FIFOMode = DMA_FIFOMode_Enable; dma.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; dma.DMA_MemoryBurst = DMA_MemoryBurst_INC4; dma.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_Init(OSD_MASK_DMA, &dma); dma.DMA_Channel = DMA_Channel_0; dma.DMA_PeripheralBaseAddr = (uint32_t)&(SPI2->DR); dma.DMA_DIR = DMA_DIR_MemoryToPeripheral; dma.DMA_BufferSize = BUFFER_WIDTH; dma.DMA_PeripheralInc = DMA_PeripheralInc_Disable; dma.DMA_MemoryInc = DMA_MemoryInc_Enable; dma.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; dma.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; dma.DMA_Mode = DMA_Mode_Normal; dma.DMA_Priority = DMA_Priority_VeryHigh; dma.DMA_FIFOMode = DMA_FIFOMode_Enable; dma.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; dma.DMA_MemoryBurst = DMA_MemoryBurst_INC4; dma.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_Init(OSD_LEVEL_DMA, &dma); /* Trigger interrupt when transfer complete */ DMA_ITConfig(OSD_MASK_DMA, DMA_IT_TC, ENABLE); DMA_ITConfig(OSD_LEVEL_DMA, DMA_IT_TC, ENABLE); /* Configure and clear buffers */ draw_buffer_level = buffer0_level; draw_buffer_mask = buffer0_mask; disp_buffer_level = buffer1_level; disp_buffer_mask = buffer1_mask; memset(disp_buffer_mask, 0, BUFFER_HEIGHT * BUFFER_WIDTH); memset(disp_buffer_level, 0, BUFFER_HEIGHT * BUFFER_WIDTH); memset(draw_buffer_mask, 0, BUFFER_HEIGHT * BUFFER_WIDTH); memset(draw_buffer_level, 0, BUFFER_HEIGHT * BUFFER_WIDTH); /* Configure DMA interrupt */ nvic.NVIC_IRQChannel = OSD_MASK_DMA_IRQ; nvic.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGHEST; nvic.NVIC_IRQChannelSubPriority = 0; nvic.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&nvic); nvic.NVIC_IRQChannel = OSD_LEVEL_DMA_IRQ; nvic.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGHEST; nvic.NVIC_IRQChannelSubPriority = 0; nvic.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&nvic); /* Enable SPI interrupts to DMA */ SPI_I2S_DMACmd(OSD_MASK_SPI, SPI_I2S_DMAReq_Tx, ENABLE); SPI_I2S_DMACmd(OSD_LEVEL_SPI, SPI_I2S_DMAReq_Tx, ENABLE); // init and enable interrupts for vsync gpio.GPIO_Pin = GPIO_PinSource1; gpio.GPIO_Speed = GPIO_Speed_100MHz; gpio.GPIO_Mode = GPIO_Mode_IN; gpio.GPIO_OType = GPIO_OType_OD; gpio.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOB, &gpio); SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOB, EXTI_PinSource1); EXTI_InitStructure.EXTI_Line=EXTI_Line1; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); nvic.NVIC_IRQChannel = EXTI1_IRQn; nvic.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGHEST; nvic.NVIC_IRQChannelSubPriority = 0; nvic.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&nvic); // Enable hsync interrupts TIM_ITConfig(LINE_COUNTER_TIMER, TIM_IT_Update, ENABLE); // Enable the capture timer TIM_Cmd(HSYNC_CAPTURE_TIMER, ENABLE); }
/** * @brief Main program * @param None * @retval None */ int main(void) { /* System Clocks Configuration */ RCC_Configuration(); /* GPIO Configuration */ GPIO_Configuration(); /* Timers synchronisation in cascade mode ---------------------------- 1/TIM2 is configured as Master Timer: - PWM Mode is used - The TIM2 Update event is used as Trigger Output 2/TIM3 is slave for TIM2 and Master for TIM4, - PWM Mode is used - The ITR1(TIM2) is used as input trigger - Gated mode is used, so start and stop of slave counter are controlled by the Master trigger output signal(TIM2 update event). - The TIM3 Update event is used as Trigger Output. 3/TIM4 is slave for TIM3, - PWM Mode is used - The ITR2(TIM3) is used as input trigger - Gated mode is used, so start and stop of slave counter are controlled by the Master trigger output signal(TIM3 update event). The TIMxCLK is fixed to 72 MHz, the TIM2 counter clock is 72 MHz. The Master Timer TIM2 is running at TIM2 frequency : TIM2 frequency = (TIM2 counter clock)/ (TIM2 period + 1) = 281.250 KHz and the duty cycle = TIM2_CCR1/(TIM2_ARR + 1) = 25%. The TIM3 is running: - At (TIM2 frequency)/ (TIM3 period + 1) = 70.312 KHz and a duty cycle equal to TIM3_CCR1/(TIM3_ARR + 1) = 25% The TIM4 is running: - At (TIM3 frequency)/ (TIM4 period + 1) = 17.578 KHz and a duty cycle equal to TIM4_CCR1/(TIM4_ARR + 1) = 25% -------------------------------------------------------------------- */ /* Time base configuration */ TIM_TimeBaseStructure.TIM_Period = 255; TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_Period = 3; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_Period = 3; TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); /* Master Configuration in PWM1 Mode */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 64; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(TIM2, &TIM_OCInitStructure); /* Select the Master Slave Mode */ TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable); /* Master Mode selection */ TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update); /* Slaves Configuration: PWM1 Mode */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 1; TIM_OC1Init(TIM3, &TIM_OCInitStructure); TIM_OC1Init(TIM4, &TIM_OCInitStructure); /* Slave Mode selection: TIM3 */ TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Gated); TIM_SelectInputTrigger(TIM3, TIM_TS_ITR1); /* Select the Master Slave Mode */ TIM_SelectMasterSlaveMode(TIM3, TIM_MasterSlaveMode_Enable); /* Master Mode selection: TIM3 */ TIM_SelectOutputTrigger(TIM3, TIM_TRGOSource_Update); /* Slave Mode selection: TIM4 */ TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_Gated); TIM_SelectInputTrigger(TIM4, TIM_TS_ITR2); /* TIM enable counter */ TIM_Cmd(TIM3, ENABLE); TIM_Cmd(TIM2, ENABLE); TIM_Cmd(TIM4, ENABLE); while (1) { } }
/** * @brief Main program * @param None * @retval None */ int main(void) { /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup files (startup_stm32f40_41xxx.s/startup_stm32f427_437xx.s/startup_stm32f429_439xx.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f4xx.c file */ /* TIM Configuration */ TIM_Config(); /* Timers synchronisation in cascade mode with an external trigger ----- 1/TIM1 is configured as Master Timer: - Toggle Mode is used - The TIM1 Enable event is used as Trigger Output 2/TIM1 is configured as Slave Timer for an external Trigger connected to TIM1 TI2 pin (TIM1 CH2 configured as input pin): - The TIM1 TI2FP2 is used as Trigger Input - Rising edge is used to start and stop the TIM1: Gated Mode. 3/TIM3 is slave for TIM1 and Master for TIM4, - Toggle Mode is used - The ITR1(TIM1) is used as input trigger - Gated mode is used, so start and stop of slave counter are controlled by the Master trigger output signal(TIM1 enable event). - The TIM3 enable event is used as Trigger Output. 4/TIM4 is slave for TIM3, - Toggle Mode is used - The ITR2(TIM3) is used as input trigger - Gated mode is used, so start and stop of slave counter are controlled by the Master trigger output signal(TIM3 enable event). TIM1 input clock (TIM1CLK) is set to 2 * APB2 clock (PCLK2), since APB2 prescaler is different from 1. TIM1CLK = 2 * PCLK2 PCLK2 = HCLK / 2 => TIM1CLK = 2 * (HCLK / 2) = HCLK = SystemCoreClock TIM3/TIM4 input clock (TIM3CLK/TIM4CLK) is set to 2 * APB1 clock (PCLK1), since APB1 prescaler is different from 1. TIM3CLK/TIM4CLK = 2 * PCLK1 PCLK1 = HCLK / 4 => TIM3CLK/TIM4CLK = HCLK / 2 = SystemCoreClock /2 The TIM1CLK is fixed to 168 MHZ, the Prescaler is equal to 5 so the TIMx clock counter is equal to 28 MHz. The TIM3CLK and TIM4CLK are fixed to 84 MHZ, the Prescaler is equal to 5 so the TIMx clock counter is equal to 14 MHz. The Three Timers are running at: TIMx frequency = TIMx clock counter/ 2*(TIMx_Period + 1) = 189.1 KHz. The starts and stops of the TIM1 counters are controlled by the external trigger. The TIM3 starts and stops are controlled by the TIM1, and the TIM4 starts and stops are controlled by the TIM3. Note: SystemCoreClock variable holds HCLK frequency and is defined in system_stm32f4xx.c file. Each time the core clock (HCLK) changes, user had to call SystemCoreClockUpdate() function to update SystemCoreClock variable value. Otherwise, any configuration based on this variable will be incorrect. -------------------------------------------------------------------- */ /* Time base configuration for TIM1, TIM3 & TIM4 */ TIM_TimeBaseStructure.TIM_Period = 73; TIM_TimeBaseStructure.TIM_Prescaler = 5; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_Period = 36; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_Period = 36; TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); /* Master Configuration in Toggle Mode */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 64; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(TIM1, &TIM_OCInitStructure); /* TIM1 Input Capture Configuration */ TIM_ICInitStructure.TIM_Channel = TIM_Channel_2; TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; TIM_ICInitStructure.TIM_ICFilter = 0; TIM_ICInit(TIM1, &TIM_ICInitStructure); /* TIM1 Input trigger configuration: External Trigger connected to TI2 */ TIM_SelectInputTrigger(TIM1, TIM_TS_TI2FP2); TIM_SelectSlaveMode(TIM1, TIM_SlaveMode_Gated); /* Select the Master Slave Mode */ TIM_SelectMasterSlaveMode(TIM1, TIM_MasterSlaveMode_Enable); /* Master Mode selection: TIM1 */ TIM_SelectOutputTrigger(TIM1, TIM_TRGOSource_Enable); /* Slaves Configuration: Toggle Mode */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 10; TIM_OC1Init(TIM3, &TIM_OCInitStructure); TIM_OC1Init(TIM4, &TIM_OCInitStructure); /* Slave Mode selection: TIM3 */ TIM_SelectInputTrigger(TIM3, TIM_TS_ITR0); TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Gated); /* Select the Master Slave Mode */ TIM_SelectMasterSlaveMode(TIM3, TIM_MasterSlaveMode_Enable); /* Master Mode selection: TIM3 */ TIM_SelectOutputTrigger(TIM3, TIM_TRGOSource_Enable); /* Slave Mode selection: TIM4 */ TIM_SelectInputTrigger(TIM4, TIM_TS_ITR2); TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_Gated); /* TIM1 Main Output Enable */ TIM_CtrlPWMOutputs(TIM1, ENABLE); /* TIM enable counter */ TIM_Cmd(TIM1, ENABLE); TIM_Cmd(TIM3, ENABLE); TIM_Cmd(TIM4, ENABLE); while (1) { } }
/** * @brief Main program * @param None * @retval None */ int main(void) { /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup files (startup_stm32f40_41xxx.s/startup_stm32f427_437xx.s/startup_stm32f429_439xx.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f4xx.c file */ /* TIM1 Configuration */ TIM_Config(); /* --------------------------------------------------------------------------- TIM1 and Timers(TIM3 and TIM4) synchronisation in parallel mode. 1/TIM1 is configured as Master Timer: - PWM Mode is used - The TIM1 Update event is used as Trigger Output 2/TIM3 and TIM4 are slaves for TIM1, - PWM Mode is used - The ITR0(TIM1) is used as input trigger for both slaves - Gated mode is used, so starts and stops of slaves counters are controlled by the Master trigger output signal(update event). In this example TIM1 input clock (TIM1CLK) is set to 2 * APB2 clock (PCLK2), since APB2 prescaler is different from 1. TIM1CLK = 2 * PCLK2 PCLK2 = HCLK / 2 => TIM1CLK = HCLK = SystemCoreClock The TIM1 counter clock is equal to SystemCoreClock = 168 Mhz. The Master Timer TIM1 is running at: TIM1 frequency = TIM1 counter clock / (TIM1_Period + 1) = 656 KHz TIM1_Period = (TIM1 counter clock / TIM1 frequency) - 1 = 255 and the duty cycle is equal to: TIM1_CCR1/(TIM1_ARR + 1) = 50% The TIM3 is running at: (TIM1 frequency)/ ((TIM3 period +1)* (Repetition_Counter+1)) = 43.730 KHz and a duty cycle equal to TIM3_CCR1/(TIM3_ARR + 1) = 33.3% The TIM4 is running at: (TIM1 frequency)/ ((TIM4 period +1)* (Repetition_Counter+1)) = 65.600 KHz and a duty cycle equal to TIM4_CCR1/(TIM4_ARR + 1) = 50% Note: SystemCoreClock variable holds HCLK frequency and is defined in system_stm32f4xx.c file. Each time the core clock (HCLK) changes, user had to call SystemCoreClockUpdate() function to update SystemCoreClock variable value. Otherwise, any configuration based on this variable will be incorrect. --------------------------------------------------------------------------- */ /* TIM3 Peripheral Configuration ----------------------------------------*/ /* TIM3 Slave Configuration: PWM1 Mode */ TIM_TimeBaseStructure.TIM_Period = 2; TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 1; TIM_OC1Init(TIM3, &TIM_OCInitStructure); /* Slave Mode selection: TIM3 */ TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Gated); TIM_SelectInputTrigger(TIM3, TIM_TS_ITR0); /* TIM4 Peripheral Configuration ----------------------------------------*/ /* TIM4 Slave Configuration: PWM1 Mode */ TIM_TimeBaseStructure.TIM_Period = 1; TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 1; TIM_OC1Init(TIM4, &TIM_OCInitStructure); /* Slave Mode selection: TIM4 */ TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_Gated); TIM_SelectInputTrigger(TIM4, TIM_TS_ITR0); /* TIM1 Peripheral Configuration ----------------------------------------*/ /* Time Base configuration */ TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_Period = 255; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_RepetitionCounter = 4; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); /* Channel 1 Configuration in PWM mode */ 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 = 127; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low; TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset; TIM_OC1Init(TIM1, &TIM_OCInitStructure); /* Automatic Output enable, Break, dead time and lock configuration*/ TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable; TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable; TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1; TIM_BDTRInitStructure.TIM_DeadTime = 5; TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable; TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High; TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Disable; TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure); /* Master Mode selection */ TIM_SelectOutputTrigger(TIM1, TIM_TRGOSource_Update); /* Select the Master Slave Mode */ TIM_SelectMasterSlaveMode(TIM1, TIM_MasterSlaveMode_Enable); /* TIM1 counter enable */ TIM_Cmd(TIM1, ENABLE); /* TIM enable counter */ TIM_Cmd(TIM3, ENABLE); TIM_Cmd(TIM4, ENABLE); /* Main Output Enable */ TIM_CtrlPWMOutputs(TIM1, ENABLE); while (1) {} }
void TIMER_Configuration(void) { 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; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_8; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); /* SVGA 800x600 @ 56 Hz Vertical refresh 35.15625 kHz Pixel freq. 36.0 MHz 1 system tick @ 72Mhz = 0,0138 us */ /* Horizontal timing ----------------- Timer 1 period = 35156 Hz Timer 1 channel 1 generates a pulse for HSYNC each 28.4 us. 28.4 us = Visible area + Front porch + Sync pulse + Back porch. HSYNC is 2 us long, so the math to do is: 2us / 0,0138us = 144 system ticks. Timer 1 channel 2 generates a pulse equal to HSYNC + back porch. This interrupt will fire the DMA request to draw on the screen if vflag == 1. Since firing the DMA takes more or less 800ns, we'll add some extra time. The math for HSYNC + back porch is: (2us + 3,55us - dma) / 0,0138us = +-350 system ticks Horizontal timing info ---------------------- Dots us -------------------------------------------- Visible area 800 22.222222222222 Front porch 24 0.66666666666667 Sync pulse 72 2 Back porch 128 3.5555555555556 Whole line 1024 28.444444444444 */ 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); /* Vertical timing --------------- Polarity of vertical sync pulse is positive. Lines ------------------------------ Visible area 600 Front porch 1 Sync pulse 2 Back porch 22 Whole frame 625 */ /* VSYNC (TIM2_CH2) and VSYNC_BACKPORCH (TIM2_CH3) */ /* Channel 2 and 3 Configuration in PWM mode */ 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); }
/** * @brief Calibration of External crystal oscillator auto(through Timer * * @param None * @retval : None */ void AutoClockCalibration(void) { RCC_ClocksTypeDef ClockValue; uint16_t TimerPrescalerValue=0x0003; uint16_t CountWait; uint16_t DeviationInteger; uint32_t CalibrationTimer; float f32_Deviation; TIM_ICInitTypeDef TIM_ICInitStructure; TIM_DeInit(TIM2); BKP_TamperPinCmd(DISABLE); BKP_RTCOutputConfig(BKP_RTCOutputSource_CalibClock); /* TIM2 configuration: PWM Input mode ------------------------ The external signal is connected to TIM2 CH2 pin (PA.01), The Rising edge is used as active edge, The TIM2 CCR2 is used to compute the frequency value The TIM2 CCR1 is used to compute the duty cycle value ------------------------------------------------------------ */ TIM_PrescalerConfig(TIM2,TimerPrescalerValue,TIM_PSCReloadMode_Immediate); TIM_ICInitStructure.TIM_Channel = TIM_Channel_2; TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; TIM_ICInitStructure.TIM_ICFilter = 0x00; TIM_PWMIConfig(TIM2, &TIM_ICInitStructure); TIM_ICInit(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); /* Enable the Master/Slave Mode */ TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable); /* TIM enable Counter */ TIM_Cmd(TIM2, ENABLE); LCD_Clear(Blue2); LCD_DisplayString(Line4,Column1,"Please Wait....."); /* Wait for 2 seconds */ CalibrationTimer = RTC_GetCounter(); while((RTC_GetCounter() - CalibrationTimer) < 2) { } RCC_GetClocksFreq(&ClockValue); TimerFrequency=(ClockValue.PCLK1_Frequency * 2)/(TimerPrescalerValue+1); /* Enable the CC2 Interrupt Request */ TIM_ITConfig(TIM2, TIM_IT_CC2, ENABLE); /* Wait for 2 seconds */ CalibrationTimer = RTC_GetCounter(); while((RTC_GetCounter() - CalibrationTimer) < 2) { } if(!(TIM_GetFlagStatus(TIM2, TIM_FLAG_CC1))) /* There is no signal at the timer TIM2 peripheral input */ { LCD_Clear(Blue2); LCD_DisplayString(Line3,Column0,"Please connect wire"); LCD_DisplayString(Line4,Column0,"link between PC13"); LCD_DisplayString(Line5,Column0,"and PA1"); LCD_DisplayString(Line7,Column0,"No calibration done"); } else { /* Calulate Deviation in ppm using the formula : Deviation in ppm = (Deviation from 511.968/511.968)*1 million*/ if(f32_Frequency > 511.968) { f32_Deviation=((f32_Frequency-511.968)/511.968)*1000000; } else { f32_Deviation=((511.968-f32_Frequency)/511.968)*1000000; } DeviationInteger = (uint16_t)f32_Deviation; if(f32_Deviation >= (DeviationInteger + 0.5)) { DeviationInteger = ((uint16_t)f32_Deviation)+1; } CountWait=0; /* Frequency deviation in ppm should be les than equal to 121 ppm*/ if(DeviationInteger <= 121) { while(CountWait<128) { if(CalibrationPpm[CountWait] == DeviationInteger) break; CountWait++; } BKP_SetRTCCalibrationValue(CountWait); LCD_Clear(Blue2); LCD_DisplayString(Line4,Column1,"Calibration Value"); LCD_DisplayChar(Line5,Column10,(CountWait%10)+0x30); CountWait=CountWait/10; LCD_DisplayChar(Line5,Column9,(CountWait%10)+0x30); CountWait=CountWait/10; if(CountWait>0) { LCD_DisplayChar(Line5,Column8,(CountWait%10)+0x30); } } else /* Frequency deviation in ppm is more than 121 ppm, hence calibration can not be done */ { LCD_Clear(Blue2); LCD_DisplayString(Line3,Column1,"Out Of Calibration"); LCD_DisplayString(Line4,Column4,"Range"); } } BKP_RTCOutputConfig(BKP_RTCOutputSource_None); TIM_ITConfig(TIM2, TIM_IT_CC2, DISABLE); TIM_Cmd(TIM2, DISABLE); TIM_DeInit(TIM2); CalibrationTimer=RTC_GetCounter(); /* Wait for 2 seconds */ while((RTC_GetCounter() - CalibrationTimer) < 5) { } MenuInit(); }
/** * @brief Main program * @param None * @retval None */ int main(void) { /*!< 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 */ /* System Clocks Configuration */ RCC_Configuration(); /* GPIO Configuration */ GPIO_Configuration(); /* TIM1 and Timers(TIM3 and TIM4) synchronisation in parallel mode ----------- 1/TIM1 is configured as Master Timer: - PWM Mode is used - The TIM1 Update event is used as Trigger Output 2/TIM3 and TIM4 are slaves for TIM1, - PWM Mode is used - The ITR0(TIM1) is used as input trigger for both slaves - Gated mode is used, so starts and stops of slaves counters are controlled by the Master trigger output signal(update event). o For Low-density, Medium-density, High-density and Connectivity line devices: The TIMxCLK is fixed to 72 MHz, Prescaler = 0 so the TIM1 counter clock is 72 MHz. The Master Timer TIM1 is running at: TIM1 frequency = TIM1 counter clock / (TIM1_Period + 1) = 281.250 KHz and the duty cycle is equal to: TIM1_CCR1/(TIM1_ARR + 1) = 50% The TIM3 is running at: (TIM1 frequency)/ ((TIM3 period +1)* (Repetion_Counter+1)) = 18.750 KHz and a duty cycle equal to TIM3_CCR1/(TIM3_ARR + 1) = 33.3% The TIM4 is running at: (TIM1 frequency)/ ((TIM4 period +1)* (Repetion_Counter+1)) = 28.125 KHz and a duty cycle equal to TIM4_CCR1/(TIM4_ARR + 1) = 50% o For Low-Density Value line and Medium-Density Value line devices: The TIMxCLK is fixed to 24 MHz, Prescaler = 0 so the TIM1 counter clock is 24 MHz. TIM1 frequency = 93.75 KHz TIM3 frequency = 6.25 KHz TIM4 frequency = 9.375 KHz --------------------------------------------------------------------------- */ /* TIM3 Peripheral Configuration ----------------------------------------*/ /* TIM3 Slave Configuration: PWM1 Mode */ TIM_TimeBaseStructure.TIM_Period = 2; TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 1; TIM_OC1Init(TIM3, &TIM_OCInitStructure); /* Slave Mode selection: TIM3 */ TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Gated); TIM_SelectInputTrigger(TIM3, TIM_TS_ITR0); /* TIM4 Peripheral Configuration ----------------------------------------*/ /* TIM4 Slave Configuration: PWM1 Mode */ TIM_TimeBaseStructure.TIM_Period = 1; TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 1; TIM_OC1Init(TIM4, &TIM_OCInitStructure); /* Slave Mode selection: TIM4 */ TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_Gated); TIM_SelectInputTrigger(TIM4, TIM_TS_ITR0); /* TIM1 Peripheral Configuration ----------------------------------------*/ /* Time Base configuration */ TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_Period = 255; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_RepetitionCounter = 4; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); /* Channel 1 Configuration in PWM mode */ 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 = 127; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low; TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset; TIM_OC1Init(TIM1, &TIM_OCInitStructure); /* Automatic Output enable, Break, dead time and lock configuration*/ TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable; TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable; TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1; TIM_BDTRInitStructure.TIM_DeadTime = 5; TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable; TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High; TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Disable; TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure); /* Master Mode selection */ TIM_SelectOutputTrigger(TIM1, TIM_TRGOSource_Update); /* Select the Master Slave Mode */ TIM_SelectMasterSlaveMode(TIM1, TIM_MasterSlaveMode_Enable); /* TIM1 counter enable */ TIM_Cmd(TIM1, ENABLE); /* TIM enable counter */ TIM_Cmd(TIM3, ENABLE); TIM_Cmd(TIM4, ENABLE); /* Main Output Enable */ TIM_CtrlPWMOutputs(TIM1, ENABLE); while (1) {} }