STM32F4一个主定时器触发两个从属时间
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STM32F4一个主定时器触发两个从属时间相关的知识,希望对你有一定的参考价值。
我对STM32F446RE的定时器同步感到有些困惑。
我想使用1个定时器作为主设备,使用两个定时器作为从设备。主定时器(即TIM2)具有5秒的周期并同时启动另外两个定时器。
从属计时器具有自己的周期(第一个从站的周期为4秒,第二个从站的周期为最长3秒)。第二从定时器(即TIM1)将产生单脉冲输出。两个奴隶都应跑1次并停下来。如果主计时器发送触发器,它们只应再次激活。我想使用1. slave来调整第二个从器件的周期,调用一个中断处理程序,我写入寄存器ARR和PSC以及CCR1(一个脉冲)。
我试图用HAL做到这一点,但它变得越来越混乱。有没有人有一个很好的想法如何编写这个(小代码片段将是非常好的)写寄存器而不是HAL?
我还在第6章看了STM的计时器烹饪书,但还没有让它工作。 https://www.st.com/content/ccc/resource/technical/document/application_note/group0/91/01/84/3f/7c/67/41/3f/DM00236305/files/DM00236305.pdf/jcr:content/translations/en.DM00236305.pdf
非常感谢您的任何反馈!
亲切的问候,托比
第一部分完成了。
TIM2的配置: - 配置为主设备,周期为10秒。 - 使用TIM_TRGO_UPDATE作为从定时器的输出触发器。
我首先使用STM32CubeMX创建了计时器,然后检查了被调用的HAL函数。
static void Timer2_Init(){
/* activate clock for TIM2 peripheral */
__HAL_RCC_TIM2_CLK_ENABLE();
/* Prescaler */
TIM2->PSC = 44999; // bus is running with 90MHz
/* set counter mode */
TIM2->CR1 &= ~(TIM_CR1_DIR | TIM_CR1_CMS);
TIM2->CR1 |= TIM_COUNTERMODE_UP;
/* Auto-Reload Register */
TIM2->ARR = 20000;
/* Set Clock Division */
TIM2->CR1 &= ~ TIM_CR1_CKD;
TIM2->CR1 |= TIM_CLOCKDIVISION_DIV1;
/* set Auto-Reload-Preload */
//TIM2->CR1 |= (0 << 7);
/* Update Event - if this timer is configured as Master with output TRGO_UPDATE
* the slave timer TIM 1 will get a trigger and run one time
*
* This bit can be set by software, it is automatically cleared by hardware.
* 0: No action
* 1: Reinitialize the counter and generates an update of the registers. Note that the prescaler
* counter is cleared too (anyway the prescaler ratio is not affected). For more see manual. */
//TIM2->EGR = TIM_EGR_UG;
/* Set Clock Source */
TIM2->SMCR &= ~(TIM_SMCR_SMS | TIM_SMCR_TS | TIM_SMCR_ETF | TIM_SMCR_ETPS | TIM_SMCR_ECE | TIM_SMCR_ETP);
/* Master Configuration */
TIM2->CR2 &= ~TIM_CR2_MMS;
TIM2->CR2 |= TIM_TRGO_UPDATE;
TIM2->SMCR &= ~TIM_SMCR_MSM;
TIM2->SMCR |= TIM_SMCR_MSM;
TIM2->CR1 = TIM_CR1_CEN;
}
接下来TIM1的初始化: - 配置为主。 - 将ARR设置为5秒。 - 将CCR1设置为1秒的脉冲长度。
我再次使用STM32CubeMX创建代码,然后检查所有HAL函数的内容。
static void Timer1_Init(){
/* activate clock for TIM1 peripheral */
__HAL_RCC_TIM1_CLK_ENABLE();
/* Edited Registers of HAL_TIM_Base_Init(&htim1) */
/* Prescaler */
TIM1->PSC = 17999; // bus is running with 180MHz
/* set counter mode */
TIM1->CR1 &= ~(TIM_CR1_DIR | TIM_CR1_CMS);
TIM1->CR1 |= TIM_COUNTERMODE_UP;
/* Auto-Reload-Register */
TIM1->ARR = 49999;
TIM1->CR1 &= ~ TIM_CR1_CKD;
TIM1->CR1 |= TIM_CLOCKDIVISION_DIV1;
/* repetition counter if pulse should be displayed more than 1 time */
TIM1->RCR = 0;
/* Auto-Reload Preload Enable */
//TIM1->CR1 |=TIM_CR1_ARPE;
/* update event */
TIM1->EGR = TIM_EGR_UG;
/* Edited registers of HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) */
TIM1->SMCR &= ~(TIM_SMCR_SMS | TIM_SMCR_TS | TIM_SMCR_ETF | TIM_SMCR_ETPS | TIM_SMCR_ECE | TIM_SMCR_ETP);
/* One Pulse Mode: Edited registers of HAL_TIM_OnePulse_Init(&htim1, TIM_OPMODE_SINGLE) */
//TIM1->CR1 &= ~TIM_CR1_OPM;
TIM1->CR1 |= TIM_CR1_OPM;
/* Slave Mode configuration: edited registers of HAL_TIM_SlaveConfigSynchro(&htim1, &sSlaveConfig) */
TIM1->SMCR &= ~TIM_SMCR_TS;
TIM1->SMCR |= TIM_TS_ITR1;
TIM1->SMCR &= ~TIM_SMCR_SMS;
TIM1->SMCR |= (TIM_SMCR_SMS_2 | TIM_SMCR_SMS_1); // = TIM_SLAVEMODE_TRIGGER -
// TIM1->DIER &= ~TIM_DIER_TIE;
// TIM1->DIER &= ~TIM_DIER_TDE;
/* HAL_TIM_PWM_ConfigChannel: HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) */
/* Disable the Channel 1: Reset the CC1E Bit */
// TIM1->CCER &= ~TIM_CCER_CC1E;
/* Reset the Output Compare Mode Bits */
TIM1->CCMR1 &= ~TIM_CCMR1_OC1M;
TIM1->CCMR1 &= ~TIM_CCMR1_CC1S;
/* Select the Output Compare (OC) Mode 1 */
TIM1->CCMR1 |= (TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1); // = TIM_OCMODE_PWM1
/* Reset and set the Output N Polarity level to LOW */
TIM1->CCER &= ~TIM_CCER_CC1P;
TIM1->CCER |= TIM_CCER_CC1P; // = TIM_OCPOLARITY_LOW
/* Reset the Output N State */
// TIM1->CCER &= ~TIM_CCER_CC1NP;
//TIM1->CCER |= 0x00000000U;
/* Reset the Output N State */
// TIM1->CCER &= ~TIM_CCER_CC1NE;
/* IS_TIM_BREAK_INSTANCE */
/* Reset the Output Compare and Output Compare N IDLE State */
// TIM1->CR2 &= ~TIM_CR2_OIS1;
// TIM1->CR2 &= ~TIM_CR2_OIS1N;
/* Set the Output Idle state */
//TIM1->CR2 |= 0x00000000U;
/* Set the Capture Compare Register: Pulse */
TIM1->CCR1 = 40000;
/* Set the Preload enable bit for channel 1 */
TIM1->CCMR1 |= TIM_CCMR1_OC1PE;
/* Configure the Output Fast mode */
// TIM1->CCMR1 &= ~TIM_CCMR1_OC1FE;
//TIM1->CCMR1 |= 0x00000000U;
/* Edited registers by HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1) */
/* Enable the Capture compare channel */
TIM1->CCER |= (1 << 0); // = TIM_CCER_CC1E
/* Enable the main output */
TIM1->BDTR |= TIM_BDTR_MOE;
/* Initialize the GPIO Pin for output: HAL_TIM_MspPostInit(&htim1) */
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_8;
GPIO_InitStruct.Pin = GPIO_PIN_8;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF1_TIM1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* Enable Counter: will be automatically enabled with trigger event */
//TIM1->CR1 = TIM_CR1_CEN;
}
下一步是配置第二个从定时器(TIM3),它将编辑TIM1的寄存器。
static void Timer3_Init(){
/* activate clock for TIM1 peripheral */
__HAL_RCC_TIM3_CLK_ENABLE();
/* Edited Registers of HAL_TIM_Base_Init(&htim1) */
/* Prescaler */
TIM3->PSC = 50000; //44999;
/* set counter mode */
TIM3->CR1 &= ~(TIM_CR1_DIR | TIM_CR1_CMS);
TIM3->CR1 |= TIM_COUNTERMODE_UP;
/* Auto-Reload-Register */
TIM3->ARR = 11000;
TIM3->CR1 &= ~ TIM_CR1_CKD;
TIM3->CR1 |= TIM_CLOCKDIVISION_DIV1;
/* update event */
TIM3->EGR = TIM_EGR_UG;
/* Edited registers of HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) */
TIM3->SMCR &= ~(TIM_SMCR_SMS | TIM_SMCR_TS | TIM_SMCR_ETF | TIM_SMCR_ETPS | TIM_SMCR_ECE | TIM_SMCR_ETP);
/* One Pulse Mode: Edited registers of HAL_TIM_OnePulse_Init(&htim1, TIM_OPMODE_SINGLE) */
//TIM1->CR1 &= ~TIM_CR1_OPM;
TIM3->CR1 |= TIM_CR1_OPM;
/* Slave Mode configuration: edited registers of HAL_TIM_SlaveConfigSynchro(&htim1, &sSlaveConfig) */
TIM3->SMCR &= ~TIM_SMCR_TS;
TIM3->SMCR |= TIM_TS_ITR1;
TIM3->SMCR &= ~TIM_SMCR_SMS;
TIM3->SMCR |= (TIM_SMCR_SMS_2 | TIM_SMCR_SMS_1); // = TIM_SLAVEMODE_TRIGGER
/* HAL_TIM_PWM_ConfigChannel: HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) */
/* Disable the Channel 1: Reset the CC1E Bit */
/* Reset the Output Compare Mode Bits */
TIM3->CCMR1 &= ~TIM_CCMR1_OC1M;
TIM3->CCMR1 &= ~TIM_CCMR1_CC1S;
/* Select the Output Compare (OC) Mode 1 */
TIM3->CCMR1 |= (TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1); // = TIM_OCMODE_PWM1
/* Reset and set the Output N Polarity level to HIGH */
TIM3->CCER &= ~TIM_CCER_CC1P; // = TIM_OCPOLARITY_HIGH
/* Set the Capture Compare Register: Pulse */
TIM3->CCR1 = 0;
/* Set the Preload enable bit for channel 1 */
//TIM3->CCMR1 |= TIM_CCMR1_OC1PE;
HAL_NVIC_SetPriority(TIM3_IRQn, 0, 1);
HAL_NVIC_EnableIRQ(TIM3_IRQn);
TIM3->DIER = TIM_DIER_CC1IE; //DMA Interrupt Enable Register (DIER): Interrupt "Capture/Compare 1 interrupt enable"
/* warning: setting this bit will cause the timer running continuously, but timer should only start with trigger,
* so don't set the CEN bit - let the trigger do the job automatically */
//TIM3->CR1 = TIM_CR1_CEN;
}
最后是TIM3的IRQ处理程序:
void TIM3_IRQHandler(void)
{
if (((TIM3->SR & TIM_FLAG_CC1) == TIM_FLAG_CC1) != RESET)
{
if (((TIM3->DIER &以上是关于STM32F4一个主定时器触发两个从属时间的主要内容,如果未能解决你的问题,请参考以下文章