Arm 在输出比较的低状态下创建脉冲,默认情况下必须为高+;计时器在需要时未启用

Arm 在输出比较的低状态下创建脉冲,默认情况下必须为高+;计时器在需要时未启用,arm,embedded,stm32,dma,stm32f4,Arm,Embedded,Stm32,Dma,Stm32f4,这个问题起源于。我决定创建一个新的,因为这是一个非常特别的东西,我在任何地方都找不到 在STM32F415中,我希望定时器的输出比较在默认情况下为高,在我告诉他的时钟周期数中为低。我的目标是使用另一个计时器禁用一个计时器。在620页中,有一个使用一个计时器启用另一个计时器的示例 在我的例子中,我希望TIM3控制TIM2,TIM4控制TIM5。TIM2和TIM5正在触发对DMA的DAC请求,它们工作正常 这就是我初始化TIM3的方式(该函数在无限循环之前在main中调用): 然后,在相应的DMA

这个问题起源于。我决定创建一个新的,因为这是一个非常特别的东西,我在任何地方都找不到

在STM32F415中,我希望定时器的输出比较在默认情况下为高,在我告诉他的时钟周期数中为低。我的目标是使用另一个计时器禁用一个计时器。在620页中,有一个使用一个计时器启用另一个计时器的示例

在我的例子中,我希望TIM3控制TIM2,TIM4控制TIM5。TIM2和TIM5正在触发对DMA的DAC请求,它们工作正常

这就是我初始化TIM3的方式(该函数在无限循环之前在main中调用):

然后,在相应的DMA IRQ处理程序中:

void DMA1_Stream6_IRQHandler(void)           /* DAC2 */
{

if (DMA_GetITStatus(DMA1_Stream6,DMA_IT_HTIF6) == SET)
{
    DMA_ClearITPendingBit(DMA1_Stream6,DMA_IT_HTIF6);

    TIM3->CNT  = 0x0;     // Reset timer
    TIM3->CR1 |= 0x1;     // Enable timer
}
/* Some code for the Transfer Complete case */
}
在程序的另一点中,我根据我希望禁用从属计时器(TIM2或TIM5)的周期数更改CCR

我的主要问题是它根本不工作,在调试时,我发现TIM3和TIM4 enable指令似乎没有任何作用:enable位(TIMx CR1寄存器中的CEN)保持为“0”,而不是更改为“1”。TIM2和TIM5初始化基本相同,没有输出比较,并且与相应定时器TRGO的选通输入配置相比较,并且可以无问题地启用和禁用它们

我还没有发现任何条件或限制,我应该如何启用一个计时器,可能会影响我的程序,所以我有点迷失了这一点


任何帮助都将不胜感激,谢谢

设置
OPM
位时,
CEN
位会在计数器完成后立即重置为0,因此可能所有操作都正常,但您无法看到它,因为它发生得太快了。如果要使用调试器检查计时器,请在APB冻结寄存器中设置一些位,
DBGMCU->APB1_FZ
。或者把一切都慢下来,我使用预分频器,在没有PLL的情况下运行内部HSI时钟的核心

然而,我只能同意这里的大多数观点,即使用SPL或HAL作为计时器只是浪费了(程序员和控制器的)各种资源。使用寄存器可以生成更短、更简单的代码,而且还具有很强的可移植性。我已经在STM32L1上测试过了,但我很确定它也能在F415上使用

#define PRESCALER   0xFFFFU
#define TDELAY      8U

void gatedtimer(void) {
    RCC->APB1ENR |= RCC_APB1ENR_TIM2EN | RCC_APB1ENR_TIM3EN;
    RCC->APB1RSTR = RCC_APB1RSTR_TIM2RST | RCC_APB1RSTR_TIM3RST;
    RCC->APB1RSTR = 0;

    TIM2->PSC = PRESCALER;  // a BIG prescaler to slow things down to observable speed
    TIM2->EGR = TIM_EGR_UG; // force prescaler update
    TIM3->PSC = PRESCALER;  // same prescaler to all timers
    TIM3->EGR = TIM_EGR_UG; // force prescaler update
    // of course you should omit the above in production code

    TIM2->SMCR = (0b010U << TIM_SMCR_TS_Pos)    // Trigger selection ITR2 = TIM3
               | (0b101U << TIM_SMCR_SMS_Pos);  // Gated Mode
    TIM2->CR1 = TIM_CR1_CEN; // start the slave

    TIM3->CR2   = (0b100U << TIM_CR2_MMS_Pos); // "100: Compare - OC1REF signal is used as trigger output (TRGO)"
    TIM3->CCMR1 = (0b110U << TIM_CCMR1_OC1M_Pos); // "110: PWM mode 1 - In upcounting, channel 1 is active as long as TIMx_CNT < TIMx_CCR1 else inactive."
    TIM3->CCR1 = TDELAY;    // "some delay" is required for the timer hw to start a pulse

    while(TIM2->CNT < 20U)
        printf("TIM2->CNT=%lu TIM3->CNT=%lu\n", TIM2->CNT, TIM3->CNT); // slave runs normally

    TIM3->ARR = TDELAY + 30; // set delay length
    TIM3->CR1 = TIM_CR1_CEN | TIM_CR1_OPM; // start the master in one pulse mode

    while(TIM3->CR1 & TIM_CR1_CEN) // CEN bit will be reset
        printf("TIM2->CNT=%lu TIM3->CNT=%lu\n", TIM2->CNT, TIM3->CNT); // slave stops when master CNT reaches TDELAY
    while(TIM2->CNT < 40)
        printf("TIM2->CNT=%lu TIM3->CNT=%lu\n", TIM2->CNT, TIM3->CNT); // slave resumes counting
}
#定义预分频器0xFFFFU
#定义TDELAY 8U
无效网关计时器(无效){
RCC->APB1ENR |=RCC_APB1ENR|n | RCC_APB1ENR|n;
RCC->APB1RSTR=RCC_APB1RSTR_TIM2RST | RCC_APB1RSTR_TIM3RST;
RCC->APB1RSTR=0;
TIM2->PSC=预分频器;//一个大的预分频器,可以将事情降低到可观察的速度
TIM2->EGR=TIM\U EGR\U UG;//强制预分频器更新
TIM3->PSC=预分频器;//所有定时器使用相同的预分频器
TIM3->EGR=TIM\U EGR\U UG;//强制预分频器更新
//当然,您应该在生产代码中省略上述内容
TIM2->SMCR=(0b010U CR2=(0b100U CCMR1=(0b110U CCR1=t延迟;/“一些延迟”是计时器hw启动脉冲所必需的
而(TIM2->CNT<20U)
printf(“TIM2->CNT=%lu TIM3->CNT=%lu\n”,TIM2->CNT,TIM3->CNT);//从机正常运行
TIM3->ARR=TDELAY+30;//设置延迟长度
TIM3->CR1=TIM_CR1_CEN | TIM_CR1_OPM;//以单脉冲模式启动主机
而(TIM3->CR1&TIM\U CR1\U CEN)//CEN位将被重置
printf(“TIM2->CNT=%lu TIM3->CNT=%lu\n”,TIM2->CNT,TIM3->CNT);//当主CNT到达TDELAY时,从机停止
而(TIM2->CNT<40)
printf(“TIM2->CNT=%lu TIM3->CNT=%lu\n”,TIM2->CNT,TIM3->CNT);//从机继续计数
}

当设置
OPM
位时,计数器一结束,
CEN
位就被重置为0,因此可能所有工作都正常,但您看不到它,因为它发生得太快。如果您想用deb检查计时器,请在APB冻结寄存器中设置一些位,
DBGMCU->APB1_FZ
或者把一切都慢下来,我使用了预分频器,在没有PLL的情况下运行内部HSI时钟的核心

然而,我只能同意这里的大多数观点,即使用SPL或HAL作为计时器只是浪费(程序员和控制器的)各种资源.使用寄存器会产生更短、更简单的代码,而且它的可移植性也很好。我实际上已经在STM32L1上测试过这一点,但我很确定它在F415上也会起作用

#define PRESCALER   0xFFFFU
#define TDELAY      8U

void gatedtimer(void) {
    RCC->APB1ENR |= RCC_APB1ENR_TIM2EN | RCC_APB1ENR_TIM3EN;
    RCC->APB1RSTR = RCC_APB1RSTR_TIM2RST | RCC_APB1RSTR_TIM3RST;
    RCC->APB1RSTR = 0;

    TIM2->PSC = PRESCALER;  // a BIG prescaler to slow things down to observable speed
    TIM2->EGR = TIM_EGR_UG; // force prescaler update
    TIM3->PSC = PRESCALER;  // same prescaler to all timers
    TIM3->EGR = TIM_EGR_UG; // force prescaler update
    // of course you should omit the above in production code

    TIM2->SMCR = (0b010U << TIM_SMCR_TS_Pos)    // Trigger selection ITR2 = TIM3
               | (0b101U << TIM_SMCR_SMS_Pos);  // Gated Mode
    TIM2->CR1 = TIM_CR1_CEN; // start the slave

    TIM3->CR2   = (0b100U << TIM_CR2_MMS_Pos); // "100: Compare - OC1REF signal is used as trigger output (TRGO)"
    TIM3->CCMR1 = (0b110U << TIM_CCMR1_OC1M_Pos); // "110: PWM mode 1 - In upcounting, channel 1 is active as long as TIMx_CNT < TIMx_CCR1 else inactive."
    TIM3->CCR1 = TDELAY;    // "some delay" is required for the timer hw to start a pulse

    while(TIM2->CNT < 20U)
        printf("TIM2->CNT=%lu TIM3->CNT=%lu\n", TIM2->CNT, TIM3->CNT); // slave runs normally

    TIM3->ARR = TDELAY + 30; // set delay length
    TIM3->CR1 = TIM_CR1_CEN | TIM_CR1_OPM; // start the master in one pulse mode

    while(TIM3->CR1 & TIM_CR1_CEN) // CEN bit will be reset
        printf("TIM2->CNT=%lu TIM3->CNT=%lu\n", TIM2->CNT, TIM3->CNT); // slave stops when master CNT reaches TDELAY
    while(TIM2->CNT < 40)
        printf("TIM2->CNT=%lu TIM3->CNT=%lu\n", TIM2->CNT, TIM3->CNT); // slave resumes counting
}
#定义预分频器0xFFFFU
#定义TDELAY 8U
无效网关计时器(无效){
RCC->APB1ENR |=RCC_APB1ENR|n | RCC_APB1ENR|n;
RCC->APB1RSTR=RCC_APB1RSTR_TIM2RST | RCC_APB1RSTR_TIM3RST;
RCC->APB1RSTR=0;
TIM2->PSC=预分频器;//一个大的预分频器,可以将事情降低到可观察的速度
TIM2->EGR=TIM\U EGR\U UG;//强制预分频器更新
TIM3->PSC=预分频器;//所有定时器使用相同的预分频器
TIM3->EGR=TIM\U EGR\U UG;//强制预分频器更新
//当然,您应该在生产代码中省略上述内容
TIM2->SMCR=(0b010U CR2=(0b100U CCMR1=(0b110U CCR1=t延迟;/“一些延迟”是计时器hw启动脉冲所必需的
而(TIM2->CNT<20U)
printf(“TIM2->CNT=%lu TIM3->CNT=%lu\n”,TIM2->CNT,TIM3->CNT);//从机正常运行
TIM3->ARR=TDELAY+30;//设置延迟长度
TIM3->CR1=TIM_CR1_CEN | TIM_CR1_OPM;//以单脉冲模式启动主机
而(TIM3->CR1&TIM\U CR1\U CEN)//CEN位将被重置
printf(“TIM2->CNT=%lu TIM3->CNT=%lu\n”,TIM2->CNT,TIM3->CNT);//当主CNT到达TDELAY时,从机停止
而(TIM2->CNT<40)
printf(“TIM2->CNT=%lu TIM3->CNT=%lu\n”,TIM2->CNT,TIM3->CNT);//从机继续计数
}

太长了,读不下去了,太长了,读不下去了。