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