PWM 실습 1 (not updated)
Download
Report
Transcript PWM 실습 1 (not updated)
마이크로프로세서응용설계 – 5
PWM 1 – T0, T2
시스템및센서네트워크연구실
1
ATmega128
시스템및센서네트워크연구실
2
LED sink / switch pullup 회로
470
5V
PC0
+5V
PC1
…..
10K
PC7
PD2
104 (0.1uF)
시스템및센서네트워크연구실
3
LCD 회로
#1
+5V
VDD
#2
LCD 밝기 조절
V0
RS
R/W
E
PC0
PC1
PC2
DB4
DB5
DB6
DB7
PC4
PC5
PC6
PC7
VSS
#3
시스템및센서네트워크연구실
+5V
LEDA
LEDK
4
시스템및센서네트워크연구실
5
LCD 함수
#include <delay.h>
#define LINE2
#define HOME
#define RSHIFT
#define LSHIFT
#define DISPON
#define DISPOFF
0xC0
0x02
0x1C
0x18
0x0c
0x08
// 2nd Line Move
// Cursor Home
// Display Right Shift
// Display Left Shift
// Display On
// Display Off
// LCD 초기화 함수
void LCD_init(void)
{
DDRC = 0xFF;
PORTC &= 0xFB;
// 포트 C 출력 설정
//E = 0;
// 충분한 지연시간을 통한 안정화 과정
delay_ms(15);
Command(0x20);
// D5=1
delay_ms(5);
Command(0x20);
// D5=1
delay_us(100);
Command(0x20);
// D5=1
void LCD_init(void);
void LCD_String(char flash str[]);
void Busy(void);
void Command(unsigned char);
void Data(unsigned char);
// 초기화 과정
Command(0x28);
Command(0x06);
Command(0x01);
Command(0x0c);
// function set
// entry mode set
// all clear
// display on
}
시스템및센서네트워크연구실
6
//데이터 쓰기 함수
void Data(unsigned char byte)
{
Busy();
// 인스트럭션 쓰기 함수
void Command(unsigned char byte)
{
Busy();
// 인스트럭션 상위 바이트
PORTC = (byte & 0xF0);
PORTC &= 0xFE;
PORTC &= 0xFD;
delay_us(1);
PORTC |= 0x04;
delay_us(1);
PORTC &= 0xFB;
// 인스트럭션 하위 바이트
PORTC = ((byte<<4) & 0xF0);
PORTC &= 0xFE;
PORTC &= 0xFD;
delay_us(1);
PORTC |= 0x04;
delay_us(1);
PORTC &= 0xFB;
// 데이터 상위 바이트
PORTC = (byte & 0xF0);
PORTC |= 0x01;
PORTC &= 0xFD;
delay_us(1);
PORTC |= 0x04;
delay_us(1);
PORTC &= 0xFB;
// 데이터
// RS = 0;
// RW = 0;
// E = 1;
// E = 0;
// 데이터 하위 바이트
PORTC = ((byte<<4) & 0xF0);
PORTC |= 0x01;
PORTC &= 0xFD;
delay_us(1);
PORTC |= 0x04;
delay_us(1);
PORTC &= 0xFB;
// 데이터
// RS = 0;
// RW = 0;
// E = 1;
// E = 0;
// 데이터
//RS = 1;
//RW = 0;
//E = 1;
//E = 0;
// 데이터
//RS = 1;
//RW = 0;
//E = 1;
//E = 0;
}
}
// 문자열 출력 함수
void LCD_String(char flash str[])
{
char flash *pStr=0;
// Busy Flag Check -> 일반적인 BF를 체크하는 것이 아니라
// 일정한 시간 지연을 이용한다.
void Busy(void)
{
delay_ms(2);
}
pStr = str;
while(*pStr) Data(*pStr++);
}
시스템및센서네트워크연구실
7
PWM (pulse-width modulation)
PWM
모터의 속도를 제어하려고 할 때, 모터에 가해지는 전압 V를 일정 주기마
다 W의 폭으로 on/off 제어를 하는 방식
출력을 내 보내는 시간의 폭 W을 조절
• W를 넓게 하면 출력되는 값이 많아지므로 평균전압이 높아짐
• W를 좁게 하면 출력되는 값이 적어지므로 평균전압이 낮아짐
duty cycle : 초당 반복되는 주기 (Hz)
duty ratio : 주기에 high value를 유지한 비율 (%)
시스템및센서네트워크연구실
8
PWM의 활용
DC 모터 제어
LED 밝기 제어
사운드 출력
적외선 통신 (리모콘)
시스템및센서네트워크연구실
9
ATmega128 타이머/카운터의 특징
ATmega16 timer/counter의 특징
2개의 8비트 타이머/카운터 0과 2
2개의 16비트 타이머/카운터 1과 3
타이머/카운터는 다음과 같은 기능이 가능
• 타이머
• 카운터
• PWM
Timer/counter0 및 Timer/counter2의 특징
8비트 타이머/카운터
10비트 프리스케일러
4개 동작 모드
카운터 입력을 위한 외부 전용 카운터 핀 (T2핀 – timer2용)
Output compare 인터럽트시 출력을 위한 외부 전용 출력 핀
(OC0(PB6)핀 – timer0용, OC2(PB7)핀 – timer2용)
2개의 인터럽트 : timer overflow, compare match
시스템및센서네트워크연구실
10
Timer/counter1 및 Timer/counter3의 특징
16비트 타이머/카운터
10비트 프리스케일러
16개 동작 모드
1개의 외부 전용 카운터 핀 (T1, T3 핀)
3개의 독립된 output compare 기능 (OC1A/OC1B/OC1C,
OC3A/OC3B/OC3C 핀)
1개의 input capture 기능 (ICP1, ICP3 핀)
5개의 인터럽트 : overflow, compare match A, compare match B,
compare match C, input capture
시스템및센서네트워크연구실
11
Timer/counter0 & 2 관련 IO 레지스터
TCNT0 & 2 (Timer/Counter0 & 2 Register)
OCR0 & 2 (Output Compare Register 0 & 2)
TIMSK (Timer/Counter Interrupt Mask Register)
bit 7 – OCIE2 : timer/counter2 Output Compare Interrupt Enable
bit 6 – TOIE2 : Timer/counter2 Overflow Interrupt Enable
bit 1 – OCIE0 : timer/counter0 Output Compare Interrupt Enable
bit 0 – TOIE0 : Timer/counter0 Overflow Interrupt Enable
TIFR (Timer/Counter Interrupt Flag Register)
시스템및센서네트워크연구실
12
TCCR0 (Timer/Counter0 Control Register)
bit 6, 3 – WGM00, WGM01(Waveform Generation Mode)
00 : normal
10 : phase correct PWM
01 : CTC
11 : fast PWM
bit 2:0 – CS02:00 (Clock Selection)
• 클럭 선택 설정
000 : 타이머/카운터 동작 중지
001 : 1분주 (프리스케일러 사용 안함)
010 : 8분주
011 : 32분주
100 : 64분주
101 : 128분주
110 : 256분주
111 : 1024분주
시스템및센서네트워크연구실
13
TCCR2 (Timer/Counter2 Control Register)
bit 6, 3 – WGM21, WGM20 (Waveform Generation Mode)
00 : normal
10 : phase correct (PC) PWM
01 : CTC
11 : fast PWM
bit 2:0 – CS22:20 (Clock Selection)
• 클럭 선택 설정
000 : 타이머/카운터 동작 중지
001 : 1분주 (프리스케일러 사용 안함)
010 : 8분주
011 : 64분주
100 : 256분주
101 : 1024분주
110 : 카운터로 동작 (falling edge)
111 : 카운터로 동작 (rising edge)
시스템및센서네트워크연구실
14
bit 5, 4 – COMn1, COMn0 (Compare Match Output Mode)
• 각 동작 모드에 따라, 타이머/카운터0의 출력 단자 OC0 / OC2 핀의
동작을 제어
• Fast PWM mode일 때
00 : OCn 차단
01 : 10 : 비교 매치에서 OCn 클리어, TOP -> BOTTOM일 때 셋
11 : 비교 매치에서 OCn 셋, TOP -> BOTTOM일 때 클리어
• Phase correct PWM mode일 때
00 : OCn 차단
01 : 10 : 업 카운터 중 비교 매치에서 OCn 클리어, 다운 카운터 중 비교 매체에서 OCn 셋
11 : 업 카운터 중 비교 매치에서 OCn 셋, 다운 카운터 중 비교 매체에서 OCn 클리어
시스템및센서네트워크연구실
15
Fast PWM mode
Fast PWM (pulse width modulation) mode
TCNTn는 BOTTOM에서 TOP까지 반복
비반전 비교 출력 모드(COMn1:n0 - 10)
• TCNTn가 OCRn와 일치하면(비교 매치), OCn 핀에 0 출력(클리어)
• TCNTn가 TOP -> BOTTOM일 때, OCn 핀에 1 출력(셋)
반전 비교 출력 모드(COMn1:n0 - 11)
• TCNTn가 OCRn와 일치하면(비교 매치), OCn 핀에 1 출력(셋)
• TCNTn가 TOP -> BOTTOM일 때, OCn 핀에 0 출력(클리어)
출력 파형 주파수 : foc = fclk / (N*256) - N:분주비
해당 포트 출력 설정
인터럽트
• 타이머/카운트n 오버플로우 (TCNTn이 TOP -> BOTTOM일 때)
• 출력 비교 인터럽트 (TCNTn와 OCRn 값이 일치할 때)
시스템및센서네트워크연구실
16
시스템및센서네트워크연구실
17
Phase correct PWM
PC(Phase Correct) PWM mode
TCNTn 값은 BOTTOM에서 TOP까지 증가하였다가 다시 BOTTOM으로
감소하는 동작 반복
비반전 출력 모드 (COMn1:n0 - 10)
• 업 카운트 중에 TCNTn와 OCR0가 일치하면, OCn핀에 0 출력(클리어)
• 다운 카운트 중에 일치하면, OCn핀에 1 출력(셋)
반전 출력 모드(COMn1:n0 – 11)
• 업 카운트 중에 TCNTn와 OCRn가 일치하면, OCn핀에 1 출력(클리어)
• 다운 카운트 중에 일치하면, OCn핀에 0 출력(셋)
출력 파형 주파수 : foc = fclk / (N*510)
해당 포트 출력 설정
인터럽트
• 타이머/카운트n 오버플로우 (TCNTn이 TOP -> BOTTOM일 때)
• 출력 비교 인터럽트 (TCNTn와 OCRn 값이 일치할 때)
시스템및센서네트워크연구실
18
시스템및센서네트워크연구실
19
실습 1
// 타이머/카운터0을 이용한 fast PWM 실험
// PB4핀에 LED 연결
// OC0(PB4)핀에 duty ratio 25, 50, 75, 100%로 LED on하는 프로그램
void main(void)
{
DDRB = 0xFF;
// PB4 출력 설정
TCCR0 = 0b01101010; // fast PWM mode : 3,6(WGM01,00) - 11, 5,4(COM ) - 10, 2-0(CS) - 010
OCR0 = 0xFF;
// 25%:0x3F, 50%:0x7F, 75%:0xBF, 100%:0xFF로 차례대로 변경해 볼 것
while(1);
}
시스템및센서네트워크연구실
20
실습 1-1
// 타이머/카운터0을 이용한 fast PWM 실험
// PB4핀에 LED 연결
// OC0(PB4)핀에 duty ratio 25, 50, 75, 100%로 LED on하는 프로그램
void main(void)
{
DDRB = 0xFF;
// PB4 출력 설정
TCCR0 = 0b01101010; // fast PWM mode : 3,6(WGM01,00) - 11, 5,4(COM ) - 10, 2-0(CS) - 010
OCR0 = 0x00;
// 25%:0x3F, 50%:0x7F, 75%:0xBF, 100%:0xFF로 차례대로 변경해 볼 것
while(1) {
OCR0 += 0x3F;
if(OCR0 > 0xFF)
OCR0 = 0x00;
delay_ms(500);
}
}
시스템및센서네트워크연구실
21
실습 2
// 타이머/카운터2를 이용한 phase correct PWM 실험
// PB7핀에 LED 연결
// OC2(PB7)핀에 duty ratio 25, 50, 75, 100%로 LED on하는 프로그램
void main(void)
{
DDRB = 0xFF;
// PB7 출력 설정
TCCR2 = 0b01100010; // phase correct PWM mode : 3,6(WGM01,00) - 01, 5,4(COM ) - 10, 2-0(CS) - 010
OCR2 = 0xFF;
// 25%:0x3F, 50%:0x7F, 75%:0xBF, 100%:0xFF로 차례대로 변경해 볼 것
while(1);
}
시스템및센서네트워크연구실
22
interrupt [EXT_INT0] void external_int0(void)
실습 3
{
pwm += 0x10;
if(pwm > 0xFF) pwm = 0xFF;
// 타이머/카운터0을 이용한 fast PWM 실험
// OC0(PB4)핀에 접속된 LED가 밝아졌다(SW1 누를 때)
// 어두워졌다(SW2 누를 때)를 반복하는 프로그램
void duty_display(void);
int pwm = 0;
// 증가
OCR0 = pwm;
duty_display();
}
interrupt [EXT_INT1] void external_int1(void)
{
void main(void)
{
DDRD = 0b00000000; // PD0, PD1 입력 설정 (SW1, SW2)
pwm -= 0x10;
if(pwm < 0x00) pwm = 0x00;
OCR0 = pwm;
EIMSK = 0b00000011; // 외부 인터럽트0, 1 인에이블
EICRA = 0b00001010; // 외부 인터럽트0, 1 하강 에지
DDRB = 0xFF;
// PB4 출력 설정
TCCR0 = 0b01101010; // fast PWM mode : 3,6(WGM01,00) - 11,
// 5,4(COM) - 10, 2-0(CS) - 010
OCR0 = pwm;
SREG = 0b10000000; // 전역 인터럽트 인에이블 비트 셋
LCD_init();
duty_display();
while(1);
}
시스템및센서네트워크연구실
// 감소
duty_display();
}
void duty_display(void)
{
float duty_ratio;
int temp0, temp1;
duty_ratio = (float)pwm *100 / 0xFF
Command(HOME);
LCD_String(“duty : “)
temp1 = (int)duty_ratio / 10;
temp0 = (int)duty_ratio % 10;
Data(0x30 + temp1);
Data(0x30 + temp0);
}
23
실습 4
interrupt [TIM0_OVF] void timer_int0(void)
{
cnt++;
// 타이머/카운터2를 이용한 fast PWM 실험
// 타이머/카운터0를 이용하여 0.2초마다 OC2(PB2)에 접속된 LED가
// 밝아졌다 어두워졌다를 반복하는 프로그램
if(cnt == 12) { // 16.384ms x 12 = 196.6ms
if(dir == 0) {
pwm += 0x10;
if(pwm > 0xFF) {
pwm = 0xFF; // 증가
dir = 1;
}
}
else {
pwm -= 0x10;
if(pwm < 0x00) {
pwm = 0x00; // 감소
dir = 0;
}
}
OCR2 = pwm;
duty_display();
cnt = 0;
void duty_display(void);
int pwm = 0, cnt=0, dir=0;
void main(void)
{
TIMSK = 0b00000001; // TOIE0 = 1;
TCCR0 = 0b00000111; // 일반모드, 프리스케일 = CK/1024
TCNT0 = 0b00000000; // 타이머/카운터0 레지스터 초기값
DDRB = 0xFF;
// PB7 출력 설정
TCCR2 = 0b01101010; // fast PWM mode : 3,6(WGM01,00) - 11,
// 5,4(COM) - 10, 2-0(CS) - 010
OCR2 = pwm;
SREG = 0b10000000;
LCD_init();
duty_display();
}
}
while(1);
}
시스템및센서네트워크연구실
24