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