• 적외선 통신은 뭐?
적외선 통신을 이용해 PIC와 PIC로 통신을 시도합니다. 적외선과는 사람의 눈에는 안 보이는 빛입니다. 필요한 것은「적외선 LED」와「적외선 수신 모듈」입니다.
• 적외선 수신 모듈의 사양
적외선 수신 모듈에는「캐리어 주파수 」라고 하는 것이 있습니다.「40 kHz」라고「38 kHz」가 되고 있을 것입니다. 테스트로 사용하는 모듈은「38 kHz」의 것이므로「38 kHz」로 테스트해 갈 것입니다.「캐리어 주파수는 무엇이나 자지 않는? 」이라고 생각합니다만 그 주파수에 맞춘 주파수로 적외선 LED를 점멸시키지 않으면 수신 모듈이 일하지 않는다고 하는 것과 같습니다. 결국은 송신측은 38 kHz의 주파수로 적외선 LED를 점멸(방형파)시킬 필요가 있는 것입니다. 다음에 적외선 수신 모듈에는「출력 펄스폭 」이라고 하는 것이 기재되어 있습니다. 또 다시「「출력 펄스폭은 무엇이나 ? 」라고 생각합니다만 적외선 수신 모듈이 출력하는「HI or LOW 시간」같습니다. 결국은 적외선 수신 모듈이「Hi」라고 판단했을 경우는「Hi를 출력 펄스폭분 출력」해「Lo」라고 판단했을 경우는「Low를 출력 펄스폭분 출력 한다」라고 하는 것입니다. 이번 테스트에 사용하는 모듈의 출력 펄스폭은「600μs」이므로「600μs」을 바탕으로 테스트를 진행시켜 나갑니다.
• 제어는 어떻게 하는 거야?
사양의 항목으로 설명한 것처럼 수신 모듈은 600μs일에서 Hi나 Low를 출력합니다. 적외선 LED는 38 kHz로 점멸시킨다고 썼습니다만 이것으로는 주기가 매치하지 않습니다. 그 수수께끼는「수신 모듈로부터 Hi를 출력하고 싶은 경우는 600μs간 38 kHz의 주파수로 적외선 LED를 점멸 시킨다」라고 하는 것입니다. 필연적으로 Low를 출력시키고 싶은 경우는 600μs의 사이 적외선 LED를 소등하고 있으면 좋습니다. 주파수가 38 kHz이므로 주기가 26μs와 요구할 수가 있습니다. 따라서 23회 점멸을 반복하면≒600μs라는 것이 됩니다.
위의 그림을 보면 알겠지만 적외선 LED로부터 Hi를 출력하면 수신 모듈은 Low를 출력합니다. 반대로 적외선 LED로부터 Low를 출력하면 수신 모듈은 Hi를 출력합니다. 이 부분을 확실히 파악하고 있지 않으면 마이크로컴퓨터의 프로그램을 작성할 단계에서 미스를 해 버립니다.
• 송수신용의 데이터 구성을 생각한다
적외선 통신과 제어의 방법을 알 수 있으면 다음은 데이터를 어떻게 보내는가 하는 것을 생각할 뿐 우선은 어디까지 제어를 할까라고 하는 것에 걸려옵니다. 복잡한 제어를 세세하게 지시하는 컨트롤러를 만드는 경우는 비트수를 늘리지 않으면 대응할 수 없습니다. 그러나 이번 컨트롤러는 마이크로컴퓨터의 내장 오실레이터를 사용하기 때문에 너무 긴 비트라면 데이터가 잘 전해지지 않을 가능성이 있습니다. 거기서 이번은 이것만은 있으면 어떻게든 될까라고 생각하는「4비트」로 데이터를 구성하고 싶습니다.
4비트 데이터라고 생각했을 경우 위 그림과 같은 데이터가 됩니다. 수신측은 시작 비트「1」을 감시해 「1」이 입력된 후에 차례차례 600μs일에 데이터를 줍도록(듯이) 합니다. 이 경우 「1」을 감시합니다만 수신 모듈은 반전하므로 사실은「0」의 감시군요. 틀림없게 데이터 비트를 2비트로 해 전체를 8비트 통신으로 하는 방법도 있습니다만 비트를 짧게 하면 모든 리모컨의 영향을 받기 쉬워져 버립니다. 실제 10비트에서도 텔레비전의 일부의 버튼으로 반응하거나 합니다. 데이터를 만드는 방법을 틀려 있을까?
• 송신용의 회로
송신 회로로서는 적외선 LED에 100 mA를 주는 것이 메인이 됩니다. 물론 100 mA를 계속 걸치는 것은 좋지 않고 점멸 주기에서만 적외선 LED를 점등시킵니다.
회로도는 위 그림과 같이 해 보았습니다. 이 회로에서는 100 mA 흐르지 않습니다만 이번은 통신 거리에 사로잡히지 않기 때문에 적당하게 빛나는 범위에서 회로를 짜 보았습니다. 간단하게 말하면 소지의 부품으로 회로를 구성했다고 말하는 일이군요. 송신 스위치를 누르면 차례로 데이터를 앞당겨 송신하는 프로그램으로 할 예정입니다.
대단한 회로가 아니네요. 회로도에는 쓰지 않았습니다만 스위치의 입력은 pull-up 할 필요가 있군요.
• 수신용의 회로
수신측의 회로도도 매우 간단합니다.
적외선 모듈은 전원과 OUT 단자의 3개로 구성되어 있습니다. 솔직하게 전원을 이어 OUT를 PIC의 포토에 입력하는 것만으로 테스트 하는 분에게는 괜찮습니다. 수신 데이터 확인용으로 LED를 두 개 붙였습니다. 본래는 4번 연속 시험하는 것이 제일 좋겠지요.
• 송신측 프로그램(CCS-C)
송신측 프로그램으로 주의해야 할 일은 특히 없다. 억지로 말한다면 적외선 LED의 점멸 시간 이것을 틀리면 영원히 수신은 하지 않기 때문에 주의가 필요합니다. 타이머를 사용하는 방법도 있을지도 모릅니다만 동작을 파악하기 쉽게 움직임을 간파할 수 있도록(듯이) 프로그램 해 보았습니다. 적외선 LED를 점멸시키는 서브루틴과 600μs간 소등하고 있는 서브루틴을 만들어 그것을 필요한 개수 호출하고 있을 뿐입니다. 혹시 어셈블러에서 쓰는 편이 빨랐을지도?
회로도가 PIC12F675이였는데 프로그램이 PIC18F2320인 것은 신경 쓰지 마시길. 설정 바꿀 뿐이니까 알지요? 프로그램의 내용은 스위치가 3개 있고 누르면 스위치마다의 데이터를 송신하고 있을 뿐입니다.
수신측의 프로그램은 어떻게 할까 헤매었습니다. 넷에서 검색한 결과 이 방식이 베타인가라고 생각 프로그램 해 보았습니다.
우선은 시작 비트를 감시해, 스타와 비트를 검출하면 600μs일에 포토 상태를 확인. 순서다 쑥스러워해 데이터의 부분을 변수에 대입한다고 하는 방식입니다. 이번은 3개의 패턴 밖에 사용해 좋았기 때문에 변수는 2개 밖에 준비해 있지 않습니다.
동작으로서는 출력에 LED3개와 모터가 한 개 있는 회로로, 「1」이 송신되어 오면 LED가 순서에 점등합니다. 「2」이 보내져 왔을 경우는 LED를 점멸시키면서 모터를 움직입니다. 「3」의 경우는 모터만 움직입니다. 모터는 진동 모터이므로 움직이거나 멈추거나 하고 있습니다.
이 프로그램으로 실제로 잘 움직일까 불안했습니다만 잡기 엎지름도 없게 움직이고 있습니다. 다른 리모컨으로 부터 신호를 수신해 움직여 버립니다만 비트수가 적기 때문에 어쩔 수 없을 것입니다. 비트수를 늘릴까 데이터 방식을 생각해 회피하는 일도 간단하겠지요.
■PWM주파수
PWM 주기보다 PWM 주파수를 요구할 수 있습니다.
PWM 주파수=1/PWM 주기
PWM 주기가 1. 25 ms 때의 PWM 주파수를 요구해 봅시다.
PWM 주파수=1/PWM 주기=1/1. 25 ms=800 Hz=0. 8 kHz
대답은 0. 8 kHz입니다.
■ PIC12F683의 하드웨어 PWM를 사용합시다.
PIC12F683에는 PWM 제어 전용의 하드웨어가 내장되고 있습니다. 즉시 사용해 봅시다.
레지스터명 |
비트수 |
설명 |
세트할 수 있는 값 |
DC1레지스터 |
10 |
Duty Cycle1 레지스터 |
0~1023 |
PR2레지스터 |
8 |
Timer2용 레지스터 |
0~255 |
프리스케일러 |
- |
배율기 |
1、4、16 |
。PIC12F683에는 하드웨어 PWM가 1 채널 내장되고 있습니다. 통상은 GP2가 출력 포토입니다. Timer2를 사용해 PWM 주기와 듀티를 설정합니다. Timer2의 PR2 레지스터와 DC1 레지스터, 프리스케일러가 설정의"요소"입니다.
■PWM주기설정
Timer2의 PR2 레지스터와 프리스케일러에 값을 세트 하는 것으로, PWM 주기를 설정할 수 있습니다.
PR2 레지스터(8 bit)에 세트 할 수 있는 값: 0~255 프리스케일러에 세트 할 수 있는 값: 1, 4, 16
DC모터를 구동한다면, PWM 주기 1 ms=PWM 주파수 1 KHz 이상의 설정으로 하고 싶은 곳입니다.
PWM 주기는 다음의 식에 의해 요구합니다.
PWM 주기=(PR2 레지스터+1)*4*(1/클럭 주파수)*프리스케일러치
· PIC12F683의 내장 CPU 클락=8 MHz, PR2=255, 프리스케일러=4때, PWM 주기와 주파수를 요구합시다.
PWM 주기=(255+1)*4*(1/8 MHz)*4=0. 512 ms
PWM 주파수=1/0. 512 ms=1. 95 kHz
대답은 PWM 주기 0. 512 ms, PWM 주파수 1. 95 kHz입니다.
PR2의 값과 프리스케일러의 값의 편성으로 PWM 주파수는 자유롭게 설정할 수 있습니다만, 제약이 있습니다. 제약에 대해서는 후술 합니다.
■듀티의 설정
PWM 주파수를 설정 후, 듀티(ON가 되어 있는 시간)를 DC1 레지스터로 설정합니다. 듀티는 10비트=0~1023의 1024 단계에서 설정할 수 있습니다. 듀티를 설정한 DC1 레지스터의 내용은, CCPR1H 레지스터에 카피되어 듀티가 초기화됩니다.
듀티 설정용 DC1 레지스터로 설정할 수 있는 값: 0~1023 DC1 레지스터에 세트 한 값에 의해 듀티는 다음의 식에서 계산할 수 있습니다.
듀티=DC1*(1/클럭 주파수)*프리스케일러치
· PIC12F683의 내장 CPU 클락=8 MHz, PR2=255, 프리스케일러=4에 세트 된 Timer2가 있습니다. DC1 레지스터=512에 세트 했을 경우의 듀티를 요구합시다.
듀티=512*(1/8 MHz)*4=0. 256 ms
대답은 0. 256 ms입니다.
■듀티비의 계산
PWM 주기와 듀티보다 듀티비를 요구할 수 있습니다.
PWM 주기=(PR2 레지스터+1)*4*(1/클럭 주파수)*프리스케일러치····(a)
PWM 듀티=DC1*(1/클럭 주파수)*프리스케일러치···(b)
이 두 개의 식으로부터, PWM 듀티비=(b)/(a)=PWM 듀티/PWM 주기=DC1/((PR2 레지스터+1)*4)
그리고 요구할 수 있습니다.
P·IC12F683의 내장 CPU 클락=8 MHz, PR2=255, 프리스케일러=4에 세트 된 Timer2가 있습니다. . 듀티=DC1 레지스터=512에 세트 했을 경우의 듀티비(%)를 요구합시다.
듀티비=듀티/PWM 주기=DC1/((PR2 레지스터+1)*4)*100
=512/((255+1)*4)*100=50%
대답은50%입니다.
■PWM제약
매우 편리한 PIC12F683의 PWM 기능입니다만, 제약이 있습니다.
DC1 ((PR2 레지스터+1)*4)*100되었을 경우는 듀티비=100%가 되어, PWM는 항상on"가 됩니다.
■PWM의 값의 선택 방법
PR2=127의 경우, DC1 레지스터에 세트 할 수 있는 유효한 값(듀티비100% 이내)은 0~512입니다. 설정 범위=PWM 분해가능이 좁아집니다. 그 때문에(위해), 모터를 구동하는 경우는 PR2=255에 세트 했을 때에, PWM 분해가능이 최대가 되는 값을 선택합니다.
PWM 주기와 프리스케일러치로 부터 다음의 식에서 PR2의 최대 세트치를 요구할 수 있습니다.
PR2=PWM 주기/(4*(1/8 MHz)*프리스케일러치) -1
설정 가능한 듀티 DC1의 최대치는 다음의 식에서 요구할 수 있습니다.
DC1=(PR2+1)*4
PR2=25DC1=(PR2+1)*4
PIC12F683를 내장 8 MHz 클럭으로 구동하는 경우의 PWM로 설정 가능한 값을 정리했으므로, 참고로 해 주세요.
PR2=255로 설정할 수 있기 위해서 사용하기 쉬운 PWM 주파수···0. 512 KHz, 1. 95 kHz, 7. 81 kHz
PWM주파수(kHz) |
0.488 |
0.651 |
1.0 |
1.95 |
3.91 |
7.81 |
10 |
38 |
50 |
100 |
PWM주기(ms) |
2.05 |
1.54 |
1.0 |
0.512 |
0.256 |
0.128 |
0.1 |
0.026 |
0.02 |
0.01 |
프리스케일치(1/4/16) |
16 |
16 |
16 |
4 |
4 |
1 |
1 |
1 |
1 |
1 |
PR2치(0~255) |
255 |
191 |
124 |
255 |
127 |
255 |
199 |
51 |
39 |
19 |
PR2(듀티)유효최대치 |
1023 |
768 |
625 |
1023 |
512 |
1023 |
800 |
208 |
160 |
90 |
설정가부 |
◎ |
○ |
○ |
◎ |
○ |
◎ |
◎ |
○ |
△ |
△ |
◎・・・PWM분해능최대、○・・・PWM분해능중、△・・・PWM분해능저
■CCS-C에 의한 설정
CCS-C에서는 PIC의 하드웨어 PWM를 간단하게 사용하기 위한 편입 함수가 준비되어 있습니다. 3개의 함수를 세트로 사용합니다.
PWM 모드 사용 선언···setup_ccp1(CCP_PWM);
PWM 주기의 설정···setup_timer2_(프리스케일러의 값, PR2의 값, 1); T2_DIV_BY_1 : 프리스케일러 설정1/1 T2_DIV_BY_4 : 〃1/4 T2_DIV_BY_16 : 〃1/16 (3개째의"1"은 포스트스켈러(출력측의 배율기)의 배율입니다. 통상은 1으로 사용합니다. )
PWM 듀티 세트···set_pwm1_duty(듀티);
· PIC12F683를 내장 CPU 클락=8 MHz로 구동하고 있습니다. 하드웨어 PWM의 PWM 주파수가 1. 95 kHz가 되도록(듯이) CCS-C로 기술합시다. 또, 듀티비50%에 세트 해 봅시다.
setup_ccp1(CCP_PWM); setup_timer2_(T2_DIV_4, 255,1);
set_pwm1_duty(512);
이와 같이 기술하는 것으로 PWM는 동작합니다.
■ 모터의 PWM 제어
DC모터를 PWM 제어하는 방법을 생각합니다.
회전시키는 모터는 10000 회전/분 (RPM: Rotate Per Minute)로 하면, 1초간의 회전수는,10000/60=167회전/초 1회전에 필요한 시간은, 1/167=6 ms=167 Hz입니다.
따라서, 6 ms=167 Hz이하의 주기에 전압을 더한다=ON로 하면, 연속 회전이 됩니다. 실제로 모형용 DC모터를 구동하려면 PWM 주파수가 1 kHz 이상이면, 부드러운 회전을 얻을 수 있습니다.
#include <12F683.h>
#device ADC=8
#fuses INTRC_IO,NOWDT,NOCPD,NOPROTECT,PUT,NOMCLR,BROWNOUT
#use delay (clock=8000000)
#use fast_io(A)
///// 메인/////
void main()
{
//클럭설정
setup_oscillator(OSC_8MHZ);
//아날로그입력설정
//0・・디지털。1・・아날로그
setup_adc_ports(0b00000000);
//각핀의 입력, 출력의 설정
//0・・출력으로 1・・입력으로
set_TRIS_A(0b00000000);
output_A(0b00000000);
//메인루프
while (true){
output_HIGH(PIN_A0);
Delay_ms(1000);
output_LOW(PIN_A0);
Delay_ms(1000);
}
}
'펌웨어디자인(Firmware Design)' 카테고리의 다른 글
마이컴으로 제작하는 타이머 (0) | 2009.09.20 |
---|---|
PIC마이컴 (0) | 2009.09.18 |
AVR로터리엔코더볼륨 (0) | 2008.12.09 |
초음파거리측정 (0) | 2008.11.11 |
AVR 마이크로컨트롤러설계도구 (0) | 2008.11.11 |