PWMの設定
TCCR1A = _BV(COM1A1)|_BV(WGM11); //Compare match A enable,Fast PWM (ICR1 as TOP)
TCCR1B = _BV(WGM13)|_BV(WGM12)|_BV(CS10); //Fast PWM (ICR1 as TOP),Clock Source enable
前書いたコードと同じだけど、再掲。
//#define F_CPU 1000000UL #include <avr/io.h> //#include <util/delay.h> #include <stdio.h> void rs_putc (char c) { loop_until_bit_is_set(UCSR0A, UDRE0); UDR0 = c; } void rs_puts (char *st) { while (*st) { rs_putc (*st); if (*(st++) == '\n') rs_putc('\r'); } } int main(void) { UCSR0B = _BV(TXEN0)|_BV(RXEN0); /* TX/RX interrupt enable */ UCSR0C = 0b00000110;//8bit UBRR0H = 0x00; UBRR0L = 0x19; TCCR1A = 0b10000010; //10:コンペアマッチAでLOW,10:高速PWM動作 TCCR1B = 0b00011001; //11:高速PWM動作, 001:分周なし ICR1 = 64999; //0から数える. 全体時間 65ms //0.000001 * 65000 : 65ms OCR1A = 0; //0から数える. High時間 32.5ms //0.000001 * 32500 : 32.5ms //OCR1AはPD5ピン DDRB |= (1 << PORTB1); while(1){ int i; unsigned int val; char buf[7]; unsigned int iter = 15; unsigned long j; for(i=0;i<iter;i++){ j = 0; while(j<100000){ val = (64999/iter)*i; OCR1A = val; j++; }; //sprintf(buf,"%u\n",val); //rs_puts(buf); } for(i=iter;i>0;i--){ j = 0; while(j<100000){ val = (64999/iter)*i; OCR1A = val; j++; }; //sprintf(buf,"%u\n",val); //rs_puts(buf); } //char msg[] = "Hello\n"; //rs_puts(msg); //_delay_ms(2000); } }
_delay_ms()を使ってもう少し上手く実装してみた。
#include <avr/io.h> #include <util/delay.h> #include <stdlib.h> #define FOSC 16000000UL #define BAUD 9600 #define MYUBRR ((FOSC/(16UL*BAUD))-1) void USART_init(unsigned int ubrr){ UBRR0H = (ubrr>>8); UBRR0L = ubrr; UCSR0B = _BV(RXEN0)|_BV(TXEN0); //RX-TX enable UCSR0C = (3<<UCSZ00);//define data frame: CSZ = CharacterSiZe } void USART_Transmit(unsigned char data){ loop_until_bit_is_set(UCSR0A,UDRE0); UDR0 = data; } char USART_recv(void) { while(!(UCSR0A & (1<<RXC0))); return UDR0; } void putString(char msg[]) { int i; for(i=0;msg[i];i++){ USART_Transmit(msg[i]); } } void PB1_PWM_init(){ DDRB |= _BV(PORTB1);//For PWM output TCCR1A = _BV(COM1A1)|_BV(WGM11); //Compare match A enable,Fast PWM (ICR1 as TOP) TCCR1B = _BV(WGM13)|_BV(WGM12)|_BV(CS10); //Fast PWM (ICR1 as TOP),Clock Source enable ICR1 = 65000; } void PB1_dim(){ int i; char buf[20]; for(i=0;i<10;i++){ unsigned long j; for(j=0;j<1000000;j++){ //nop; } OCR1A = 6500 * i; //_delay_ms(200); } } void PWM_test(){ ICR1 = 65000; int i; for(i=0;i<10;i++){ OCR1A = 6500*i; _delay_ms(200); } for(i=10;i>0;i--){ OCR1A = 6500*i; _delay_ms(200); } } int main(void){ DDRB |= _BV(PORTB5);//For monitor LED13 USART_init(MYUBRR); char data; putString("Hello\n"); putString("Hello\n"); PB1_PWM_init(); OCR1A = 65000; while(1){ //data = USART_recv(); //USART_Transmit(data); //PB1_dim(); PWM_test(); } return 0; }