You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无PWM模块单片机单计数器+中断生成指定占空比输出方案问询

Alright, let's break down these two counter-based PWM problems step by step—no fancy PWM modules required here!

1. 如何仅使用一个计数器生成20%占空比的输出?

First off, let's recall what a 20% duty cycle means: the output is HIGH for 20% of the total period, and LOW for the remaining 80%. Here's how to pull this off with a single counter:

Core Idea

We'll use a counter in auto-reload mode (it resets to 0 once it hits a pre-defined "reload" value). By setting a comparison threshold, we can set/clear the output pin when the counter crosses that threshold—no interrupts needed if your counter supports hardware compare match.

Step-by-Step Implementation

  • Pick a counter period: Let's use easy math for 20%—set the counter's auto-reload register to 9 (most counters count from 0 to the reload value, making the total period reload_value + 1 = 10 timer ticks).
  • Set the comparison value: For 20% duty cycle, the HIGH time should be 2 ticks. So set the counter's compare register to 1 (counts 0 and 1 as HIGH, that's exactly 2 ticks).
  • Configure output behavior: Set up the counter to drive the output pin HIGH when the counter starts at 0, and LOW when the counter matches the compare value.

Example Pseudocode (for a typical 8-bit MCU)

// Configure counter in auto-reload mode
TIMER->CR1 |= TIMER_CR1_ARPE; // Enable auto-reload preload
TIMER->ARR = 9; // Total period: 10 timer ticks
TIMER->CCR1 = 1; // Compare threshold for 20% HIGH time

// Configure output compare to stay HIGH until match, then LOW
TIMER->CCMR1 |= TIMER_CCMR1_OC1M_2 | TIMER_CCMR1_OC1M_0; // PWM mode 1
TIMER->CCER |= TIMER_CCER_CC1E; // Enable output on channel 1
TIMER->CR1 |= TIMER_CR1_CEN; // Start the counter

This setup makes the output pin stay HIGH from counter value 0 to 1, then LOW from 2 to 9—perfect 20% duty cycle.


2. 若单片机无PWM模块,如何通过一个计数器及中断(非轮询方式),在引脚1生成20%占空比输出、引脚2生成80%占空比输出?

Since we don't have hardware PWM, we'll use counter interrupts to manually toggle the pins. The key insight here: 80% duty cycle is just the inverse of 20%, so we can sync both pins to the same counter's events.

Core Idea

We'll use two interrupt events from the same counter:

  1. A compare match interrupt when the counter hits the 20% threshold (to switch pin1 LOW and pin2 HIGH)
  2. An overflow interrupt when the counter resets (to switch pin1 HIGH and pin2 LOW)

Step-by-Step Implementation

  • Configure the counter: Same as before—auto-reload mode, reload value 9 (10-tick total period).
  • Set comparison value: 1 for the 20% threshold.
  • Enable interrupts: Turn on the compare match interrupt (for the 1 value) and the counter overflow interrupt.
  • Write interrupt service routines (ISRs): Handle pin state changes in each ISR, and don't forget to clear interrupt flags!

Example Pseudocode

// Initialize GPIO pins as outputs
GPIO->DDR |= (1 << PIN1) | (1 << PIN2);
GPIO->ODR |= (1 << PIN1); // Start pin1 HIGH, pin2 LOW

// Configure counter
TIMER->ARR = 9;
TIMER->CCR1 = 1;
TIMER->DIER |= TIMER_DIER_CC1IE | TIMER_DIER_UIE; // Enable compare and overflow interrupts
TIMER->CR1 |= TIMER_CR1_CEN;

// Enable global interrupts (depends on your MCU)
__enable_irq();

// Compare match ISR (triggers when counter hits 1)
void TIMER_CC1_IRQHandler(void) {
  TIMER->SR &= ~TIMER_SR_CC1IF; // Clear interrupt flag
  GPIO->ODR &= ~(1 << PIN1); // Set pin1 LOW
  GPIO->ODR |= (1 << PIN2);  // Set pin2 HIGH
}

// Overflow ISR (triggers when counter resets to 0)
void TIMER_IRQHandler(void) {
  TIMER->SR &= ~TIMER_SR_UIF; // Clear interrupt flag
  GPIO->ODR |= (1 << PIN1);  // Set pin1 HIGH
  GPIO->ODR &= ~(1 << PIN2); // Set pin2 LOW
}

This way, pin1 stays HIGH for 2 ticks (20%) and LOW for 8, while pin2 is the exact opposite—HIGH for 8 ticks (80%) and LOW for 2. All handled via interrupts, so your MCU can run other code without polling pins nonstop.


内容的提问来源于stack exchange,提问作者W.Wafi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 09:12:26