Last active
July 8, 2025 06:46
-
-
Save akira345/244e0005b12bad0b8fcba5b9afec6905 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define F_CPU 8000000UL // 内蔵クロック8MHz | |
#include <avr/io.h> | |
#include <util/delay.h> | |
// 設定 | |
#define FREQ_HZ 60 // 周波数60Hz | |
#define CYCLE_US (1000000UL / ((FREQ_HZ -10) * 2)) // 周期のマイクロ秒。10Hz高く出るので引く | |
#define HALF_PERIOD_US (CYCLE_US / 2) // 半周期のマイクロ秒 | |
#define DEADTIME_US 20 // デッドタイム20us | |
#define MAX_ON_TIME_US (HALF_PERIOD_US - DEADTIME_US) // 最大ON時間(半周期からデッドタイムを引いた値) | |
#define START_DUTY_RATIO 0.1 // スタート時のデューティ比(10%) | |
#define DUTY_STEP (MAX_ON_TIME_US / 50) // デューティ比のステップ(最大ON時間の1/50) | |
// 出力ピン(PB0: Q1 P-ch、PB1: Q2 N-ch、PB2: Q3 P-ch、PB3: Q4 N-ch) | |
#define Q1_PCH_PIN PB0 | |
#define Q2_NCH_PIN PB1 | |
#define Q3_PCH_PIN PB2 | |
#define Q4_NCH_PIN PB3 | |
/* | |
ATTinyのPB0 → Q1(左上P-ch)のゲート(1kΩ抵抗を介して)10Kプルアップ | |
ATTinyのPB1 → Q2(左下N-ch)のゲート(1kΩ抵抗を介して)10Kプルダウン | |
ATTinyのPB2 → Q3(右上P-ch)のゲート(1kΩ抵抗を介して)10Kプルアップ | |
ATTinyのPB3 → Q4(右下N-ch)のゲート(1kΩ抵抗を介して)10Kプルダウン | |
Pchのゲートは10Kでプルアップ。Nchのゲートは10Kでプルダウン。 | |
MOSのゲート抵抗は1kΩを介して接続。すべてトランジスタによるレベルシフトを行う。 | |
*/ | |
// 可変usディレイ関数 | |
void variable_delay_us(uint16_t us) { | |
while (us--) { | |
_delay_us(1); | |
} | |
} | |
int main(void) { | |
// 出力設定 | |
DDRB |= (1 << Q1_PCH_PIN) | (1 << Q2_NCH_PIN) | (1 << Q3_PCH_PIN) | (1 << Q4_NCH_PIN); | |
// 初期化 | |
uint16_t on_time_us = MAX_ON_TIME_US * START_DUTY_RATIO; | |
// 全ゲートOFF(全MOSFET OFF) | |
PORTB = (0 << Q1_PCH_PIN) | (1 << Q2_NCH_PIN) | (0 << Q3_PCH_PIN) | (1 << Q4_NCH_PIN); // pChMOS=0(OFF), nChMOS=1(OFF) | |
while (1) { | |
// --- 左回転: Q1(P-ch,PB0)・Q4(N-ch,PB3) ON(対角のみON) --- | |
PORTB = (1 << Q1_PCH_PIN) | (1 << Q2_NCH_PIN) | (0 << Q3_PCH_PIN) | (0 << Q4_NCH_PIN); // Q1=1(ON), Q2=1(OFF), Q3=0(OFF), Q4=0(ON) | |
variable_delay_us(on_time_us); | |
// 全OFF(デッドタイム) | |
PORTB = (0 << Q1_PCH_PIN) | (1 << Q2_NCH_PIN) | (0 << Q3_PCH_PIN) | (1 << Q4_NCH_PIN); // 全OFF | |
variable_delay_us(DEADTIME_US); | |
// --- 右回転: Q3(P-ch,PB2)・Q2(N-ch,PB1) ON(対角のみON) --- | |
PORTB = (0 << Q1_PCH_PIN) | (0 << Q2_NCH_PIN) | (1 << Q3_PCH_PIN) | (1 << Q4_NCH_PIN); // Q1=0(OFF), Q2=0(ON), Q3=1(ON), Q4=1(OFF) | |
variable_delay_us(on_time_us); | |
// 全OFF(デッドタイム) | |
PORTB = (0 << Q1_PCH_PIN) | (1 << Q2_NCH_PIN) | (0 << Q3_PCH_PIN) | (1 << Q4_NCH_PIN); // 全OFF | |
variable_delay_us(DEADTIME_US); | |
// --- ソフトスタート --- | |
if (on_time_us < MAX_ON_TIME_US) { | |
on_time_us += DUTY_STEP; | |
if (on_time_us > MAX_ON_TIME_US) { | |
on_time_us = MAX_ON_TIME_US; | |
} | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* ATtiny85 SPWM インバーター (IR2302 x2 フルブリッジ構成) | |
* | |
* ピンアサイン: | |
* PB0 (pin 5) - PB0 PWM出力 (左レグ - IR2302#1のIN) | |
* PB1 (pin 6) - PB1 PWM出力 (右レグ - IR2302#2のIN) | |
* PB2 (pin 7) - PB2 : シャットダウン制御 (両IR2302のSD端子) | |
* PB3 (pin 2) - 未使用 | |
* PB4 (pin 3) - 未使用 | |
* PB5 (pin 1) - RESET | |
* VCC (pin 8) - 電源 +5V | |
* GND (pin 4) - 電源 GND | |
* | |
* フルブリッジ動作: | |
* - 正の半波: 左レグ上側PWM制御、右レグ下側常時ON | |
* - 負の半波: 右レグ上側PWM制御、左レグ下側常時ON | |
* - IR2302動作: IN=HIGH→上側MOSFET導通、IN=LOW→下側MOSFET導通 | |
* - PWM周波数: 約31kHz, 正弦波周波数: 約60Hz | |
*/ | |
#define F_CPU 8000000UL | |
#include <avr/io.h> | |
#include <avr/interrupt.h> | |
#include <avr/pgmspace.h> | |
#include <util/delay.h> | |
#define SD_PIN PB2 | |
volatile uint8_t num = 0; | |
#define STEPS 160 | |
const uint8_t sine_table[STEPS] PROGMEM = { | |
128, 133, 138, 143, 148, 153, 158, 162, | |
167, 172, 177, 181, 186, 190, 194, 199, | |
203, 207, 210, 214, 218, 221, 225, 228, | |
231, 234, 236, 239, 241, 243, 245, 247, | |
249, 250, 251, 253, 253, 254, 255, 255, | |
255, 255, 255, 254, 253, 253, 251, 250, | |
249, 247, 245, 243, 241, 239, 236, 234, | |
231, 228, 225, 221, 218, 214, 210, 207, | |
203, 199, 194, 190, 186, 181, 177, 172, | |
167, 162, 158, 153, 148, 143, 138, 133, | |
128, 123, 118, 113, 108, 103, 98, 94, | |
89, 84, 79, 75, 70, 66, 62, 57, | |
53, 49, 46, 42, 38, 35, 31, 28, | |
25, 22, 20, 17, 15, 13, 11, 9, | |
7, 6, 5, 3, 3, 2, 1, 1, | |
1, 1, 1, 2, 3, 3, 5, 6, | |
7, 9, 11, 13, 15, 17, 20, 22, | |
25, 28, 31, 35, 38, 42, 46, 49, | |
53, 57, 62, 66, 70, 75, 79, 84, | |
89, 94, 98, 103, 108, 113, 118, 123, | |
}; | |
int main(void) { | |
cli(); // 割り込み禁止 | |
_delay_ms(10); // 電源安定化待ち | |
// PWM設定(Timer0) | |
// PWM周波数約31.25kHz | |
// OCR0A(PB0)とOCR0B(PB1)を使用して、左レグと右レグのPWM出力を制御 | |
// 8ビット高速PWM動作(WGM01, WGM00ビットを設定) | |
TCCR0A = (1 << COM0A1) | (1 << COM0B1) | (1 << WGM01) | (1 << WGM00); // Fast PWM, 非反転出力 | |
TCCR0B = (1 << CS00); // 分周なし → 約31.25kHz | |
// PB0とPB1のPWM出力を初期化 | |
OCR0A = 0; | |
OCR0B = 0; | |
// Timer1設定(CTCモード、分周8) | |
// 正弦波生成のための設定 | |
TCCR1 = (1 << CTC1) | (1 << CS12); // 分周8 | |
// 60Hz正弦波のために調整 | |
// 60Hzの周期16.67ms。これを160ステップで分割すると、1ステップあたり約104us。 | |
// 8MHzクロックの場合8MHz / 8 = 1MHz → 1us/ステップ | |
OCR1A = 104; // 約104us → 60Hz正弦波 | |
OCR1C = 104; // 同じ値 | |
TIMSK |= (1 << OCIE1A); // OCR1Aマッチ割り込み有効 | |
// 出力ピン設定 | |
DDRB |= (1 << PB0) | (1 << PB1) | (1 << SD_PIN); | |
PORTB |= (1 << SD_PIN); // IOR2302シャットダウン解除 | |
_delay_ms(10); // IR2302起動後の安定化待ち | |
sei(); // 割り込み許可 | |
while (1) { | |
// メインループ不要(全て割り込み駆動) | |
} | |
} | |
// Timer1のOCR1Aマッチ割り込みハンドラ | |
// 正弦波のサンプル値を読み出し、PWM出力を更新 | |
// ここでは、sine_tableから値を読み出し、OCR0AとOCR0Bに設定します。 | |
// numは現在のサンプルインデックスで、STEPSは正弦波テーブルのサイズです。 | |
ISR(TIMER1_COMPA_vect) { | |
uint8_t value = pgm_read_byte(&sine_table[num]); | |
OCR0A = value; // 左レグのPWM値 | |
OCR0B = pgm_read_byte(&sine_table[(num + STEPS/2) % STEPS]); // 反対側のレグのPWM値 | |
num++; | |
if(num >= STEPS) num = 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import math | |
# パラメータ | |
STEPS = 160 | |
AMPLITUDE = 127 # 0〜255の中心を128とする | |
OFFSET = 128 | |
# テーブル生成 | |
table = [] | |
for i in range(STEPS): | |
angle = 2 * math.pi * i / STEPS | |
value = int(round(OFFSET + AMPLITUDE * math.sin(angle))) | |
table.append(value) | |
# Cコード形式で出力 | |
print('#include <avr/pgmspace.h>') | |
print(f'const uint8_t sine_table[{STEPS}] PROGMEM = {{') | |
for i in range(0, STEPS, 8): | |
line = ", ".join(f"{v:3}" for v in table[i:i+8]) | |
print(" " + line + ",") | |
print("};") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ATTiny85ビルド方法 | |
## -Wall : 詳細な警告を全て表示するようにする | |
## -Os : バイナリサイズが小さくなるよう最適化をする | |
## -mmcu=<Name> : プログラムを動かすマイコンを指定 | |
# ビルド | |
avr-gcc -Os -Wall -mmcu=attiny85 AVR-Inverter.c -o test.elf | |
# elfからhexファイル作成 | |
avr-objcopy -I elf32-avr -O ihex test.elf test.hex | |
# メモリ使用量を調べる | |
avr-size -C --mcu=attiny85 test.elf |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
ATTiny85ヒューズビット設定