PWM 실습 2

Download Report

Transcript PWM 실습 2

마이크로프로세서응용설계 - 6
PWM 2 – T1, T3
시스템및센서네트워크연구실
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
ATmega128 타이머/카운터의 특징
 ATmega128 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
시스템및센서네트워크연구실
8
 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
시스템및센서네트워크연구실
9
Timer/counter1 & 3 관련 IO 레지스터
 TCNT1 & 3 (Timer/Counter1 & 3 Register)
 OCR1A, 1B, 1C & 3A, 3B, 3C (Output Compare Register 1A, 1B, 1C, & 3A, 3B, 3C)
 TIMSK (Timer/Counter Interrupt Mask Register) / ETIMSK (Extended TIMSK)
 TIFR (T/C Interrupt Flag Register) / ETIFR (Extended TIFR)
시스템및센서네트워크연구실
10
 TCCR1A (Timer/Counter1 Control Register A)
 bit 1, 0 – WGM11, WGM10(Waveform Generation Mode)
 bit (7,6), (5,4), (3,2) – COMnA(B,C)1, COMnA(B,C)0
• Fast PWM mode일 때
00 : OCn 차단
01 : -
10 : 비교 매치에서 OCnA(B,C) 클리어, TOP -> BOTTOM일 때 셋
11 : 비교 매치에서 OCnA(B,C) 셋, TOP -> BOTTOM일 때 클리어
• Phase correct PWM mode일 때
00 : OCn 차단
01 : -
10 : 업 카운터 중 비교 매치에서 OCnA(B,C) 클리어, 다운 카운터 중 비교 매체에서
OCnA(B,C) 셋
11 : 업 카운터 중 비교 매치에서 OCnA(B,C) 셋, 다운 카운터 중 비교 매체에서
OCnA(B,C) 클리어
시스템및센서네트워크연구실
11
 TCCR1B (Timer/Counter1 Control Register B)
 bit 4, 3 – WGM13, WGM12(Waveform Generation Mode)
0000 : normal (n3, n2, n1, n0 순)
0100 : CTC – TOP : OCR1A
0011 : PC PWM, 10bit TOP
0111 : Fast PWM, 10bit TOP
 bit 2:0 – CS02:00 (Clock Selection)
000 : 타이머 차단
001 : 1분주
010 : 8분주
011 : 64분주
100 : 256분주
101 : 1024분주
110 : 카운터, 하강 에지에서 동작
111 : 카운터 동작, 상승 에지에서 동작
시스템및센서네트워크연구실
12
시스템및센서네트워크연구실
13
Fast PWM mode
시스템및센서네트워크연구실
14
Phase correct PWM
시스템및센서네트워크연구실
15
실습 1
// 타이머/카운터1을 이용한 fast PWM, 10bit TOP 시험
// OC1A(PB5)핀에 duty ratio 25, 50, 75, 100%로 LED on하는 프로그램
int pwm = 0;
void main(void)
{
DDRB = 0b00100000;
// PB5(OC1A) 출력 설정
TCCR1A = 0b10000011;
// mode 7 : 0111 1,0(WGM11,WGM10)-11, 7,6(COM1A1,COM1A0)-10
TCCR1B = 0b00001010;
// 4,3(WGM13,WGM12)-01, 2-0(CS)-010
TCNT1 = 0x0000;
// 타이머1 초기화
OCR1A = 0x0000;
while(1) {
OCR1A = pwm;
pwm += 0x0100;
if(pwm > 0x03FF) pwm = 0;
// 0%:0x0000, 25%:0x00FF, 50%:0x01FF, 75%:0x02FF, 100%:0x03FF (10bit TOP)
delay_ms(500);
}
}
시스템및센서네트워크연구실
16
실습 2
// 타이머/카운터1을 이용한 phase correct PWM, 10bit TOP실험
// OC1B(PB6)핀에 duty ratio 25, 50, 75, 100%로 LED on하는 프로그램
int pwm = 0;
void main(void)
{
DDRB = 0b01000000;
// PB6(OC1B) 출력 설정
TCCR1A = 0b00100011;
// mode 3 : 0011 1,0(WGM11,WGM10)-11, 5,4(COM1B1,COM1B0)-10
TCCR1B = 0b00000010;
// 4,3(WGM13,WGM12)-00, 2-0(CS)-010
TCNT1 = 0x0000;
// 타이머1 초기화
OCR1B = 0x0000;
while(1) {
OCR1A = pwm;
pwm += 0x0100;
if(pwm > 0x03FF) pwm = 0;
// 0%:0x0000, 25%:0x00FF, 50%:0x01FF, 75%:0x02FF, 100%:0x03FF (10bit TOP)
delay_ms(500);
}
}
시스템및센서네트워크연구실
17
실습 3
// 타이머/카운터1을 이용한 fast PWM, ICRn TOP 실험
// 64분주, ICR1=0x09C3로 하여, 주기를 10msec로 조정
int pwm = 0;
void main(void)
{
DDRB = 0b00100000;
TCCR1A = 0b10000010;
TCCR1B = 0b00011011;
ICR1H = 0x09;
ICR1L = 0xC3;
TCNT1 = 0x0000;
// PB5(OC1A) 출력 설정
// mode 14(ICRn top fast PWM) : 1110, 1,0(WGM11,10)-10, 7,6(COM1A1,COM1A0)-10
// 4,3(WGM13,12)-11, 2-0(CS)-011 (64분주)
// ICR1 = 2499 (0x09C3) -> 주기 : 10msec
// 타이머1 초기화
OCR1A = 0x0000;
while(1) {
OCR1A = pwm;
pwm += 0x0010;
if(pwm > 2499) pwm = 0;
delay_ms(50);
}
}
시스템및센서네트워크연구실
18
실습 4
// 타이머/카운터1을 이용한 fast PWM, ICRn TOP 실험
// 64분주, ICR1=0x09C3로 하여, 주기를 10msec로 조정
// 스위치1을 누르면 LED1, 스위치2를 누르면 LED2 점차적으로 밝아짐
int pwm1a = 0, pwm1b=0;
void main(void)
{
DDRB = 0b01100000;
TCCR1A = 0b10100010;
TCCR1B = 0b00011011;
ICR1H = 0x09;
ICR1L = 0xC3;
// PB5(OC1A), PB6(OC1B) 출력 설정
// mode 14(ICRn top fast PWM) : 1110, 1,0(WGM11,10)-10
// 7,6(COM1A1,COM1A0)-10 ,5,4(COM1B1,COM1B0)-10
// 4,3(WGM13,12)-11, 2-0(CS)-011 (64분주)
// ICR1 = 2499 (0x09C3) -> 주기 : 10msec
// 외부 인터럽트0 서비스 루틴
interrupt [EXT_INT0] void external_int0(void)
{
OCR1A = pwm1a;
pwm1a += 0x0050;
if(pwm1a > 0x09C3) pwm1a = 0;
DDRD = 0b00000000;
// PD0, PD1 입력 설정 (SW1, SW2)
}
EIMSK = 0b00000011; // 외부 인터럽트0, 1 인에이블
EICRA = 0b00001010;
// 외부 인터럽트0, 1 하강 에지
// 외부 인터럽트1 서비스 루틴
interrupt [EXT_INT1] void external_int1(void)
SREG = 0b10000000;
{
OCR1B = pwm1b;
while(1);
pwm1b += 0x0050;
}
if(pwm1b > 0x09C3) pwm1b = 0;
}
시스템및센서네트워크연구실
19
실습 5
// 타이머/카운터1를 이용한 fast PWM , ICRn TOP 실험
// 타이머/카운터3를 이용하여 0.2초마다 OC1A(PB5)에 접속된 LED가 밝아졌다 어두워졌다를 반복하는 프로그램
// 0.2s 계산 : 1/16us * 256분주 * 12500 = 200ms
void duty_display(void);
interrupt [TIM3_OVF] void timer_int3(void)
int pwm = 0,dir=0;
{
void main(void)
TCNT3H = 0xCF;
{
TCNT3L = 0x2C;
ETIMSK = 0b00000100; // TOIE3 = 1;
TCCR3A = 0b00000000; // 일반모드 (WGM11, WGM10)
if(dir == 0) {
TCCR3B = 0b00000100; // 일반모드 (WGM13, WGM12), 프리스케일 = 256
pwm += 0x0050;
TCNT3H = 0xCF;
if(pwm > 0x09C3) {
TCNT3L = 0x2C;
//53036;
pwm = 0x09C3; // 증가
dir = 1;
DDRB = 0b01100000;
// PB5(OC1A), PB6(OC1B) 출력 설정
}
TCCR1A = 0b10100010;
// mode 14(ICRn top fast PWM) : 1110,
}
// 1,0(WGM11,10)-10, 7,6(COM1A1,COM1A0)-10
else {
TCCR1B = 0b00011011;
// 4,3(WGM13,12)-11, 2-0(CS)-011 (64분주)
pwm -= 0x0050;
ICR1H = 0x09;
// ICR1 = 2499 (0x09C3) -> 주기 : 10msec
if(pwm < 0x0000) {
ICR1L = 0xC3;
pwm = 0x0000; // 감소
OCR1A = pwm;
dir = 0;
}
SREG = 0b10000000;
}
LCD_init();
OCR1A = pwm;
duty_display();
duty_display();
while(1);
}
} 시스템및센서네트워크연구실
20
void duty_display(void)
{
float duty_ratio=0;
int temp0=0, temp1=0;
duty_ratio = (float)pwm *100 / 0x09C3;
Command(HOME);
LCD_String(“duty : “)
temp1 = (int)duty_ratio / 10;
temp0 = (int)duty_ratio % 10;
Data(0x30 + temp1);
Data(0x30 + temp0);
}
시스템및센서네트워크연구실
21
실습 6
// 타이머/카운터1를 이용한 fast PWM , ICRn TOP 실험
// 타이머/카운터3를 이용하여 0.2초마다 OC1A(PB5)에 접속된 LED가 밝아졌다 어두워졌다를 반복하는 프로그램
// 0.2s 계산 : 1/16us * 256분주 * 12500 = 200ms
// SW1을 누르면 LED가 밟아졌다 어두워졌다 반복, SW2를 누르면 LED off
void duty_display(void);
int pwm = 0,dir=0;
void main(void)
{
DDRD = 0b00000000; // PD0, PD1 입력 설정 (SW1, SW2)
EIMSK = 0b00000011; // 외부 인터럽트0, 1 인에이블
EICRA = 0b00001010; // 외부 인터럽트0, 1 하강 에지
SREG = 0b10000000;
LCD_init();
duty_display();
while(1);
}
시스템및센서네트워크연구실
22
// 외부 인터럽트0 서비스 루틴
interrupt [EXT_INT0] void external_int0(void)
interrupt [TIM3_OVF] void timer_int3(void)
{
{
TCNT3H = 0xCF;
ETIMSK = 0b00000100; // TOIE3 = 1;
TCCR3A = 0b00000000; // 일반모드 (WGM11, WGM10)
TCCR3B = 0b00000100; // 일반모드 (WGM13, WGM12), 프리스케일 = 256
TCNT3H = 0xCF;
TCNT3L = 0x2C;
//53036;
DDRB = 0b01100000;
TCCR1A = 0b10100010;
TCCR1B = 0b00011011;
ICR1H = 0x09;
ICR1L = 0xC3;
OCR1A = pwm;
TCNT3L = 0x2C;
if(dir == 0) {
pwm += 0x0050;
if(pwm > 0x09C3) {
pwm = 0x09C3; // 증가
dir = 1;
}
}
else {
pwm -= 0x0050;
if(pwm < 0x0000) {
pwm = 0x0000; // 감소
dir = 0;
}
}
OCR1A = pwm;
duty_display();
// PB5(OC1A), PB6(OC1B) 출력 설정
// mode 14(ICRn top fast PWM) : 1110,
// 1,0(WGM11,10)-10, 7,6(COM1A1,COM1A0)-10
// 4,3(WGM13,12)-11, 2-0(CS)-011 (64분주)
// ICR1 = 2499 (0x09C3) -> 주기 : 10msec
}
// 외부 인터럽트1 서비스 루틴
interrupt [EXT_INT1] void external_int1(void)
{
TCCR3A = 0x00;
TCCR3B = 0x00;
TCCR1A = 0x00;
TCCR1B = 0x00;
}
시스템및센서네트워크연구실
//53036;
}
23