0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ATtiny3224: PWM 出力 (ソフトウェア版)

Posted at

PIN_PA5 に 170Hz の PWM出力をします。

プログラム

pwm04/pwm04.ino
// ----------------------------------------------------------------
/*
	pwm04.ino
				Sep/21/2025
*/
// ----------------------------------------------------------------
#define	PROGRAM	"pwm04.ino"
#define	VERSION	"2025-09-21 PM 13:33"

// 20MHz, target 300Hz software PWM for PA5 (works with TinyCore 0.3.0)

#define LED_PIN PIN_PA5

// 170Hz の周期(マイクロ秒)
const uint32_t TARGET_HZ = 170;
const uint32_t PERIOD_US = 1000000UL / TARGET_HZ;
	// = 3333 us (実測周波数 = 1000000/3333 ≈ 300.03 Hz)

// ----------------------------------------------------------------
void setup() {
	Serial1.begin(19200);
	delay(200);
	Serial1.println("*** setup start ***");
	delay(1000);
	Serial1.println("*** ATtiny3224 ***");
	Serial1.println(PROGRAM);
        delay(1000);
        Serial1.println(VERSION);
        delay(1000);

  Serial1.print("CPU Clock = "); Serial1.println(F_CPU);
  Serial1.print("Using software PWM at approx "); Serial1.print(1000000.0f / (float)PERIOD_US, 3);
  Serial1.println(" Hz");
  pinMode(LED_PIN, OUTPUT);
}

// ----------------------------------------------------------------
// duty: 0..255
void pwmRunFor(uint8_t duty8, uint32_t duration_ms) {
  uint32_t cycles = (duration_ms * 1000UL) / PERIOD_US;
  uint32_t high_us = (uint32_t)((uint64_t)(PERIOD_US) * (uint32_t)duty8 / 255ULL);

  // 特殊値の最適化
  if (duty8 == 0) {
    digitalWrite(LED_PIN, LOW);
    delay(duration_ms);
    return;
  }
  if (duty8 == 255) {
    digitalWrite(LED_PIN, HIGH);
    delay(duration_ms);
    return;
  }

  for (uint32_t i = 0; i < cycles; ++i) {
    if (high_us > 0) {
      digitalWrite(LED_PIN, HIGH);
      if (high_us > 1) delayMicroseconds(high_us);
      else __asm__ __volatile__ ("nop");
    }
    uint32_t low_us = PERIOD_US - high_us;
    if (low_us > 0) {
      digitalWrite(LED_PIN, LOW);
      if (low_us > 4) delayMicroseconds(low_us); // delayMicroseconds は 1us 単位
      else for (volatile uint8_t k=0;k< (uint8_t)low_us; ++k) __asm__ __volatile__ ("nop");
    }
  }
}

// ----------------------------------------------------------------
void loop() {
  // テスト:0->64->128->192->255->0 の各デューティを1秒ずつ表示
  uint8_t dutySteps[] = {0, 32, 64, 128, 0};
  for (int i=0;i < sizeof(dutySteps)/sizeof(dutySteps[0]); ++i) {
    uint8_t d = dutySteps[i];
    Serial1.print("Setting duty (0..255) = "); Serial1.println(d);
    pwmRunFor(d, 1000);
		// 1000ms = 1秒
    delay(1000);
		// 少し余裕
  }
}

// ----------------------------------------------------------------

シリアルの出力

*** setup start ***
*** ATtiny3224 ***
pwm04.ino
2025-09-21 PM 13:33
CPU Clock = 20000000
Using software PWM at approx 170.010 Hz
Setting duty (0..255) = 0
Setting duty (0..255) = 32
Setting duty (0..255) = 64
Setting duty (0..255) = 128
Setting duty (0..255) = 0
Setting duty (0..255) = 0
Setting duty (0..255) = 32
Setting duty (0..255) = 64
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?