質問
atmega8のLED、ポートBのピンにPWMを使用しようとしています。タイマーの設定は迷惑です。これが私のコードです、そして私はいくつかのフィードバックが好きです。
私はPWMの使用方法を把握しようとしています。私はコンセプトを知っています、そしてOCR1aは私がパルスを望んでいる全体のカウンタータイムの割合であるはずです。
#define F_CPU 1000000 // 1 MHz
#include <avr/io.h>
#include <avr/delay.h>
#include <avr/interrupt.h>
int main(void){
TCCR1A |= (1 << CS10) | (1 << CS12) | (1 << CS11);
OCR1A = 0x0000;
TCCR1A |= ( 0 << WGM11 ) | ( 1 << WGM10 ) | (WGM12 << 1) | (WGM13 << 0);
TCCR1A |= ( 1 << COM1A0 ) | ( 0 << COM1A1 );
TIMSK |= (1 << TOIE1); // Enable timer interrupt
DDRB = 0xFF;
sei(); // Enable global interrupts
PORTB = 0b00000000;
while(1)
{
OCR1A = 0x00FF; //I'm trying to get the timer to alternate being on for 100% of the time,
_delay_ms(200);
OCR1A = 0x0066; // Then 50%
_delay_ms(200);
OCR1A = 0x0000; // Then 0%
_delay_ms(200);
}
}
ISR (TIMER1_COMA_vect) // timer0 overflow interrupt
{
PORTB =~ PORTB;
}
. 解決 2
これら2行のOCR1Aを初期化する必要があります。
TCCR1A = (1 << WGM10) | (1 << COM1A1);
TCCR1B = (1 << CS10) | (1 << WGM12);
.
を使用してから:
OCR1A = in
.
と範囲が0~255であることを知っています。あなたの割合を数え、そこにそれを持っています!
#define F_CPU 1000000 // 1 MHz
#include <avr/io.h>
#include <avr/delay.h>
#include <avr/interrupt.h>
int main(void){
TCCR1A = (1 << WGM10) | (1 << COM1A1);
TCCR1B = (1 << CS10) | (1 << WGM12);
DDRB = 0xFF;
sei(); // Enable global interrupts
PORTB = 0b00000000;
while(1)
{
OCR1A = 255;
_delay_ms(200);
OCR1A = 125;
_delay_ms(200);
OCR1A = 0;
_delay_ms(200);
}
}
. 他のヒント
いいえ、これはではなくあなたがPWMをする方法です。たとえば、たとえば42%のPWMレートを設定しますか。また、コードサイズは大きく、それははるかに効率的な方法で行うことができます。また、8ビットの操作を行うために16ビットタイマーを無駄にします。 2倍8ビットタイマ(タイマ/カウンタ0と2)、16ビットタイマ、Timer/Counter 1
。
未使用のPortpinsを出力に設定するのは悪い考えです。何でも接続されていないすべてのポートピンは入力として残されるべきです。
Atmega8にはPWMジェネレータが内蔵されており、タイマー1と2にはソフトウェアを介してシミュレーションする必要はありません。ポートを手動で設定する必要はありません(対応するPortPinを出力に設定するだけです)
割り込みが必要ありません。
.
#define fillrate OCR2A
//...
// main()
PORTB=0x00;
DDRB=0x08; //We use PORTB.3 as output, for OC2A, see the atmega8 reference manual
// Mode: Phase correct PWM top=0xFF
// OC2A output: Non-Inverted PWM
TCCR2A=0x81;
// Set the speed here, it will depend on your clock rate.
TCCR2B=0x02;
// for example, this will alternate between 75% and 42% PWM
while(1)
{
fillrate = 191; // ca. 75% PWM
delay_ms(2000);
fillrate = 107; // ca. 42% PWM
delay_ms(2000);
}
同じタイマーを使用して、OCR2Aの代わりにOCR2Bを設定して、別のPWMを使用して別のLEDを使用できます。 PWMの出力としてOCR2Bを有効にするようにTCCR2Aを設定することを忘れないでください。この例の場合はOCR2Aのみが許可されています。