Periode PWM ditentukan oleh tingkat luapan timer Anda. Ada banyak pengaturan pada bagian Mode Operasi untuk dipikirkan. Jika semua yang ingin Anda lakukan adalah menghasilkan gelombang persegi periode konstan, dengan siklus tugas variabel, saya pikir Anda akan ingin menggunakan mode CTC (Clear Timer on Compare Match). Ide dasarnya adalah untuk menetapkan OCR0A ke jumlah kutu waktu sampai Anda ingin pin untuk beralih berikutnya, dan gunakan interupsi Bandingkan Pertandingan untuk mengubah nilai itu untuk waktu berikutnya. Jadi dalam avr-gcc akan terlihat seperti:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdint.h>
// global variables defining number of ticks on and off
uint8_t on_time_ticks, off_time_ticks, csxx_bits=0;
void setup_timer(double p_ms, double duty){
TCCR0A = _BV(COM0A0) // toggle OC0A on Compare Match
TCCR0B = _BV(WGM02); // set CTC mode WGM0[2,1,0] = 0b100
// ... do some stuff based on your CPU frequency
// to define the csxx_bits of TCCR0B when the timer is running
// and consequently, to set on_time_ticks and off_time_ticks
OCR0A = on_time_ticks;
TCCR0B |= your_settings_here;
}
void start_timer(){
//start the timer running at the desired rate
TCCR0B |= csxx_bits;
}
int main(int argc, char **argv){
double period_ms, duty_cycle;
setup_timer(period_ms, duty cycle);
start_timer();
for(;;){
//spin or sleep or whatever
}
}
ISR(TIM0_COMPA_vect){
if(OCR0A == on_time_ticks){
OCR0A = off_time_ticks;
}
else{
OCR0A = on_time_ticks;
}
}
Peringatan, ini kode yang belum diuji tetapi saya pikir idenya benar. Tidak berarti apakah ini satu - satunya cara untuk melakukannya juga.
Ada satu hal yang harus Anda ketahui tentang ATTiny13. RC Oscillator internal hanya dijamin akurat hingga 10% dari lantai pabrik. Ada proses kalibrasi pengguna yang dapat Anda lalui (dijelaskan oleh atmel appnote ) yang akan membawa Anda ke akurasi 2% untuk ATTiny13. Jika Anda ingin melakukan yang lebih baik dari itu, Anda mungkin perlu menggunakan chip yang mengakomodasi kristal eksternal ...