Speaker, Watchdog timer, Sleep 실습 (not updated)

Download Report

Transcript Speaker, Watchdog timer, Sleep 실습 (not updated)

마이크로프로세서응용설계 - 7
Speaker
Watchdog timer
Sleep
시스템및센서네트워크연구실
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
VSS
#3
시스템및센서네트워크연구실
+5
V
LEDA
LEDK
RS
R/W
E
PC0
PC1
PC2
DB4
DB5
DB6
DB7
PC4
PC5
PC6
PC7
4
시스템및센서네트워크연구실
5
LCD 함수
// LCD 초기화 함수
#include <delay.h>
void LCD_init(void)
#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
{
DDRC = 0xFF;
// 포트 C 출력 설정
PORTC &= 0xFB;
//E = 0;
// 충분한 지연시간을 통한 안정화 과정
delay_ms(15);
Command(0x20);
void LCD_init(void);
void LCD_String(char flash str[]);
void Busy(void);
void Command(unsigned char);
void Data(unsigned char);
// D5=1
delay_ms(5);
Command(0x20);
// D5=1
delay_us(100);
Command(0x20);
// D5=1
// 초기화 과정
Command(0x28);
// function set
Command(0x06);
// entry mode set
Command(0x01);
// all clear
Command(0x0c);
// 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
Speaker – 음악 멜로디 연주
 음악의 기본 구성
 음의 높이(음계, 음정, tone), 음의 길이(박자, beat), 음의 강약, 음의 색깔
 음의 높이는 주파수로, 음의 길이는 신호 발생시간으로 조절 가능
 음의 강약은 신호 파형의 진폭에 의해, 음의 색깔은 신호 파형에 고조파 성분의
포함 정도나 진폭의 변화에 의해 결정됨
 uC에는 음의 높이와 길이는 쉽게 조절이 가능하나, 음의 강약과 색깔은 D/A 컨버
터나 Op Amp 등과 같은 복잡한 회로가 필요
 음악 멜로디 연주의 원리
 주파수는 타이머의 분주 기능을 이용하여 조절
 연주시간은 시간지연 루틴을 사용하여 조절
 스피커를 구동하는 파형은 듀티비를 50%에 가깝게 하는 것이 좋음
• 타이머 CTC모드의 토글 동작 이용
시스템및센서네트워크연구실
8
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)
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
• CTC mode일 때
00 : OCn 차단
01 : 비교 매치에서 OCnA(B,C) toggle 신호
10 : 비교 매치에서 OCnA(B,C) 클리어
11 : 비교 매치에서 OCnA(B,C) 셋
 TCCR1B (Timer/Counter1 Control Register B)
 bit 4, 3 – WGM13, WGM12(Waveform Generation Mode)
0100 : CTC – TOP : OCR1A
 bit 2:0 – CS02:00 (Clock Selection)
010 : 8분주
시스템및센서네트워크연구실
9
음계 및 쉼표의 발생
 음계 발생의 원리




음계는 0 – 9 옥타브로 구성
각 옥타브에는 C, C#, D, D#, E, F, F#, G, G#, A, A#, B 등 12개의 음이 존재
이웃하는 두 음계 사이에는 1:212, 즉 1:1.05946의 비율로 주파수가 증가됨
타이머1을 이용한 출력 주파수 계산
• CTC mode 4 사용 : OCR1A를 Top
• 프리스케일러 – 8분주
• fOC1A = 16*106 / (2 * 8 * (1+OCR1A)) = 106 / (1+OCR1A)
• COM1A toggle mode 사용
OCRn
TCNTn
0x00
OCn
 음계별 표준주파수와 타이머1에 의한 출력 주파수 (표)
시스템및센서네트워크연구실
10
시스템및센서네트워크연구실
11
 음표 및 쉼표 발생의 원리
 음표나 쉼표는 각 음계의 연주시간 또는 휴지시간을 나타냄
 음표나 쉼표는 상대적인 시간값을 가짐
 각 음표의 실제 연주시간은 음표의 종류뿐 아니라 음악의 연주 속도를 표시하는
템포(tempo)에 의하여 결정됨
 음표 및 쉼표의 종류와 상대 길이 (표)
 프로그램에서는 템포를 1(가장 빠름)에서 7(가장 느림)까지 정의하고, 가장 짧은
연주 시간 단위인 32분 음표를 21ms의 기본 시간으로 정의
• 실제 음표의 연주시간 : 기본 시간 * 상대 길이 * 템포값
시스템및센서네트워크연구실
12
시스템및센서네트워크연구실
13
실습1
 악보
-
OC1A(PB5)
시스템및센서네트워크연구실
+
+5V
14
// 학교종이땡땡땡 연주
// note
#define VLOA
9008 // octave 2
#define VLOAX 8580
#define VLOB
8098
#define LOC
#define LOCX
#define LOD
#define LODX
#define LOE
#define LOF
#define LOFX
#define LOG
#define LOGX
#define LOA
#define LOAX
#define LOB
7644
7214
6810
6427
6066
5726
5404
5101
4815
4544
4289
4049
#define MIC
#define MICX
#define MID
#define MIDX
#define MIE
#define MIF
#define MIFX
#define MIG
#define MIGX
#define MIA
#define MIAX
#define MIB
3821
3607
3404
3213
3033
2862
2702
2550
2407
2272
2144
2024
// 도 octave 3
// 레
// 미
// 파
// 솔
// 라
// 시
// 도 octave 4 (기본 음계)
// 레
// 미
// 파
// 솔
// 라
// 시
시스템및센서네트워크연구실
#define HIC
#define HICX
#define HID
#define HIDX
#define HIE
#define HIF
#define HIFX
#define HIG
#define HIGX
#define HIA
#define HIAX
#define HIB
1910
3607
3404
3213
3033
2862
2702
2550
2407
2272
2144
2024
// 도 octave 5
// 레
// 미
// 파
// 솔
// 라
// 시
// note length
#define NOTE32 1*3
#define NOTE16 2*3
#define NOTE16D 3*3
#define NOTE8 4*3
#define NOTE8D 6*3
#define NOTE4 8*3
#define NOTE4D 12*3
#define NOTE2 16*3
#define NOTE2D 24*3
#define NOTE1 32*3
// rest length
#define REST32 1*3
#define REST16 2*3
#define REST16D 3*3
#define REST8 4*3
#define REST8D 6*3
#define REST4 8*3
#define REST4D 12*3
#define REST2 16*3
#define REST2D 24*3
#define REST1 32*3
15
void play_note(unsigned int sound, unsigned int note);
void play_rest(unsigned int rest);
play_note(MIG, NOTE4);
play_note(MIG, NOTE4);
play_note(MIE, NOTE4);
play_note(MIE, NOTE4);
play_note(MID, NOTE2D);
play_rest(REST4);
void main(void)
{
DDRB = 0b00100000;
play_note(MIG, NOTE4);
play_note(MIG, NOTE4);
play_note(MIA, NOTE4);
// OC1A(PD5)에 스피커 연결
unsigned int tempo=0;
// PB5(OC1A) 출력 설정
play_note(MIA, NOTE4);
TCCR1A = 0b01000000; // COM1A1,A0(7,6)-01, mode 4 - CTC모드 / OCR1A (WGM11,10 - 00)
TCCR1B = 0b00001010; // mode 4(WGM13,12 - 01), 프리스케일 = 8
while(1){
tempo = 4;
play_note(MIG, NOTE4);
play_note(MIG, NOTE4);
play_note(MIE, NOTE4);
play_rest(REST4);
// while(1) : 무한 루프
play_note(MIG, NOTE4);
play_note(MIG, NOTE4);
play_note(MIA, NOTE4);
play_note(MIA, NOTE4);
play_note(MIG, NOTE4);
play_note(MIG, NOTE4);
play_note(MIE, NOTE4);
play_rest(REST4);
play_note(MIG, NOTE4);
play_note(MIE, NOTE4);
play_note(MID, NOTE4);
play_note(MIE, NOTE4);
play_note(MIC, NOTE2D);
play_rest(REST4);
delay_ms(1000);
}
}
시스템및센서네트워크연구실
16
void play_note(unsigned int sound, unsigned int note)
{
OCR1A = sound;
TCNT1 = 0x0000;
TCCR1A = 0b01000000;
TCCR1B = 0b00001010;
// COM1A1,A0(7,6)-01, mode 4 - CTC모드 / OCR1A (WGM11,10 - 00)
// mode 4(WGM13,12 - 01), 프리스케일 = 8
delay_ms(note * tempo * 7);
TCCR1B = 0b00001000;
// speaker off
}
void play_rest(unsigned int rest)
{
delay_ms(rest * tempo * 7);
}
시스템및센서네트워크연구실
17
Speaker – 전자 음향 발생
 전화벨 음향
320Hz
(25ms)
480Hz
(25ms)
320Hz
(25ms)
320Hz
(25ms)
480Hz
(25ms)
1초 계속
1초 정지
480Hz
(25ms)
1초 계속
 119 구급차 소리
480Hz
(500ms)
360Hz
(500ms)
480Hz
(500ms)
360Hz
(500ms)
무한정 반복
시스템및센서네트워크연구실
18
실습 2
// 전화벨 음향
TCCR1B = 0b00001000;
delay_ms(1000);
}
void main(void)
{
unsigned int i=0;
DDRB = 0b00100000;
// CS – 000, speaker off
}
// PB5(OC1A) 출력 설정
TCCR1A = 0b01000000; // COM1A1,A0(7,6)-01, mode 4 - CTC모드 / OCR1A (WGM11,10 - 00)
TCCR1B = 0b00001010; // mode 4(WGM13,12 - 01), 프리스케일 = 8
delay_ms(50);
while(1){
// while(1) : 무한 루프
for(i=0; i<=20; i++) {
TCCR1B = 0b00001010; // CS – 8분주, speaker on
OCR1A = 3124;
delay_ms(25);
// 1M / (1+3124) = 320
OCR1A = 2082;
delay_ms(25);
// 1M / (1+2082) = 480
}
시스템및센서네트워크연구실
19
실습 3
// 119 구급차 음향
TCCR1B = 0b00001000;
delay_ms(1000);
void main(void)
{
unsigned int i=0;
DDRB = 0b00100000;
// CS – 000, speaker off
}
}
// PB5(OC1A) 출력 설정
TCCR1A = 0b01000000; // COM1A1,A0(7,6)-01, mode 4 - CTC모드 / OCR1A (WGM11,10 - 00)
TCCR1B = 0b00001010; // mode 4(WGM13,12 - 01), 프리스케일 = 8
delay_ms(50);
while(1){
// while(1) : 무한 루프
for(i=0; i<5; i++) {
TCCR1B = 0b00001010; // CS – 8, speaker on
OCR1A = 2082;
delay_ms(500);
// 1M / (1+2082) = 480
OCR1A = 2777;
delay_ms(500);
// 1M / (1+2777) = 360
}
시스템및센서네트워크연구실
20
Reset
 리셋
 리셋이 걸리는 동안 모든 I/O 레지스터는 초기 값으로 설정
 프로그램은 처음부터 새로 실행됨
 ATmeg1a6의 리셋 소스
 Power-on reset
• 전원전압 Vcc가 power-on reset의 임계전압 Vpot보다 낮을 때 발생
 External reset
• /RESET 핀에 1.5us 이상의 low 신호가 입력되면 발생
 Watchdog reset
• 워치독 타이머가 타임아웃이 될 때 발생
 Brown-out reset
• Brown-out 검출기가 enable되어 있고 brown-out 임계전압 Vbot보다 낮을 때 발
생
시스템및센서네트워크연구실
21
Watchdog timer
 워치독 타이머의 특징
 기능
• 시스템이 프로그램의 착오로 무한 루프에 들어가거나 또는 기계 고장으로 휴
지 상태로 되는 것을 방지하기 위해 프로그램에 의해 설정된 타이머로서 주
어진 일정 시간이 경과하면 워치독 리셋이 발생
• 워치독 타이머를 동작시키면, 프로그래머가 주기적으로 워치독 타이머의 값
을 0으로 리셋시켜야 함. 그렇지 않을 경우, uC가 이상 동작한다고 판단하고,
워치독 타이머가 직접 uC를 H/W 리셋시켜 버림
 동작
• 별도의 1MHz 내장 발진기로부터 클럭을 공급받아 동작
• 워치독 타이머 프리스케일러에 의하여 워치독 타이머 리셋의 주기가 설정
• 워치독 타이머 리셋은 WDR 명령에 의해 이루어짐
• 워치독 타이머 리셋없이 리셋 주기가 끝나면 uC는 H/W 리셋됨
시스템및센서네트워크연구실
22
Watchdog timer 관련 IO 레지스터
 WDTCR(watchdog timer control register)
 bit 4 - WDCE : watchdog change enable
• WDE 비트를 제어하기 전에 셋시켜야 함
• 한번 셋되면, 하드웨어적으로 4클럭 사이클 후에 자동 클리어됨
 bit 3 – WDE : watchdog enable
• 셋 되면 워치독 타이머의 기능이 인에이블됨
 bit 2:0 – WDP: watchdog prescaler
• 워치독 타이머의 프리스케일
동작 결정
시스템및센서네트워크연구실
23
실습 4
 워치독 타이머 리셋 명령 실행
 워치독 리셋 주기를 약 0.95초로 설정하고,
 타이머/카운터1의 오버플로우 주기를 64분주로 하여 0.26초마다 인터럽트를 발
생시키도록 함
 타이머/카운터1의 오버플로우 인터럽트가 발생될 때마다 워치독 타이머를 리셋
(어셈블러 wdr 명령)하여 LED 순차 점멸이 정상적으로 동작하도록 프로그램 작
성
 워치독 타이머의 리셋 발생 조건
1. 타이머 오버플로우가 발생되지 않고, 1초가 지나가면, 자동으로 리셋됨
2. 리셋 명령을 사용하는 경우 리셋됨 (리셋 버튼)
 레지스터
• WDTCR = 0b00011000
WDTCE(4) = 1, WDE(3) = 1
• WDTCR = 0b00001110
WDE(3) = 1, WDP(2:0) =110 (1024 : 1.0us)
 리셋 명령
• #asm (“wdr”)
시스템및센서네트워크연구실
-> 어셈블리 명령어를 C에서 사용할 수 있게 함
24
// 타이머/카운터 오버플로 1 서비스 루틴
#include <mega128.h>
#include <delay.h>
// (1/16us) * 64 * 65536 = 0.26s
interrupt [TIM1_OVF] void timer_int1(void)
char led = 0xFE;
void main(void)
{
DDRC = 0xFF;
PORTC = led;
{
// LED 순차 점멸
led <<= 1;
// 포트 C 출력으로 설정
// 포트 C에 초기값 출력
// 타이머/카운터1 오버플로 인터럽트 초기화
TIMSK = 0x04;
// TOIE1(2) = '1'
TCCR1A = 0x00;
// WGM10(1,0):00, normal mode
TCCR1B = 0x03;
// WGM32(4,3):00, CS(2-0):011 (64분주)
TCNT1 = 0x0000;
// 타이머/카운터1 레지스터 초기값
led |= 0x01;
if(led == 0xFF) led = 0xFE;
PORTC = led;
#asm ("wdr")
// 워치-독 타이머 리셋
}
// #asm (“wdr”)을 제거하고 나서 동작 확인 !
// 워치독 타이머 초기화
WDTCR = 0b00011000;
WDTCR = 0b00001110;
// WDTCE(4) =1, WDE(3) = 1
// WDE(3) = 1, WDP = 110 (1024 : 1.0s)
SREG = 0x80;
// 전역 인터럽트 인에이블 비트 I 셋.
while(1);
// 무한 루프
// 제거하면, 워치독 타이머를 리셋시키지 못하므로,
// 1초가 지난 후에 uC가 H/W 리셋되어 버림
}
시스템및센서네트워크연구실
25
Sleep
 Sleep mode
 AVR 내에서 사용하지 않는 주변장치를 차단하여 전원을 절약하는 기능
 다양한 Sleep mode를 지원하여 사용자가 필요한 모듈만 선택하게 해 줌
 Sleep mode에 있는 동안 enable된 인터럽트가 발생하면 sleep mode로부터 해제됨
 주요 모드
 Idle mode
• MCU의 동작은 정지
• SPI, TWI, USART, 아날로그 비교기, 타이머/카운터, 워치독, ADC, 인터럽트
는 동작
 Power-down mode
• 외부 발진기 정지
• 외부 인터럽트, TWI, 워치독은 동작
• 외부 리셋, 워치독 리셋, 외부 인터럽트 등에 의해서만 해제 가능
시스템및센서네트워크연구실
26
Sleep mode 관련 IO 레지스터
 MCUCR
 bit 5 : SE (sleep mode enable)
• 1일 때 sleep mode enable
• 슬립 모드에 들어갈 시점에 #asm (“SLEEP”) 명령 사용
 bit 4, 3, 2: SM2, 1, 0 (sleep model select)
• 000 – idle mode
• 010 – power-down mode
시스템및센서네트워크연구실
27
실습 5
// LED를 한번 왕복 쉬프트시킨 후 sleep 모드로 들어감
// SW1을 누르면 sleep 모드에서 해제된 후, 다시 한번 왕복 쉬프트시킴
char led = 0xFE;
void main(void)
{
DDRC = 0xFF;
// DDRC : 포트 방향 설정 레지스터
MCUCR = 0b00100000;
DDRD = 0b00000000; // PD0, PD1 입력 설정 (SW1, SW2)
EIMSK = 0b00000011; // 외부 인터럽트0, 1 인에이블
EICRA = 0b00001010; // 외부 인터럽트0, 1 하강 에지
SREG = 0b10000000; // 전역 인터럽트 인에이블 비트 셋
PORTC = led;
while(led != 0b11111110) {
delay_ms(500);
led >>= 1;
led |= 0b10000000;
PORTC = led;
}
}
}
// 외부 인터럽트0 서비스 루틴
interrupt [EXT_INT0] void external_int0(void)
{
}
while(1){
// while(1) : 무한 루프
while(led != 0b01111111) {
delay_ms(500);
led <<= 1;
led |= 0b00000001;
PORTC = led;
}
#asm ("SLEEP")
시스템및센서네트워크연구실
28
실습 6
// SW를 누르고 있을 때 알람 발생 및 LCD에 ‘경고’ 출력하고 깜빡거림
// Sleep mode 적용
// 외부 인터럽트0 서비스 루틴
interrupt [EXT_INT0] void external_int0(void)
{
TCCR1B = 0b00001010; // CS – 010
OCR1A = 2082;
void warn_display(void);
void safe_display(void);
// 1M / (1+2082) = 480
warn_display();
delay_ms(500);
void main(void)
{
DDRB = 0b00100000;
// PB5(OC1A) 출력 설정
TCCR1A = 0b01000000; // COM1A1,A0(7,6)-01, mode 4 - CTC모드
// OCR1A (WGM11,10 - 00)
TCCR1B = 0b00001010; // mode 4(WGM13,12 - 01), 프리스케일 = 8
OCR1A = 2777;
// 1M / (1+2777) = 360
Command(CLEAR);
delay_ms(500);
}
DDRD = 0b00000000;
// PD0, PD1 입력 설정 (SW1, SW2)
EIMSK = 0b00000011; // 외부 인터럽트0, 1 인에이블
EICRA = 0b00000000;
// 외부 인터럽트0, 1 레벨 트리거
MCUCR = 0b00100000;
SREG = 0b10000000;
// 전역 인터럽트 인에이블 비트 셋
void warn_display(void)
{
Command(HOME);
LCD_String(“Warning!”);
}
LCD_init();
void safe_display(void)
{
Command(HOME);
LCD_String(“Safe”);
}
while(1) {
// while(1) : 무한 루프
TCCR1B = 0b00010000; // speaker off
safe_display();
#asm (“SLEEP”);
}
}
시스템및센서네트워크연구실
29