Nikonのデジカメ用リモコンML-L3の互換機をPIC12F1822で作ります。
ML-L3に解析データは先人の知恵を参考にさせて頂いてます。
PIC12F1822は今回初めて使う石ですが、JalV2でサポートされているので安心。
完成品 |
完成品 |
コードの説明
delay
m秒単位の_usec_delay(2_000)だと時間が安定してなくて、delayライブラリのdelay_1ms(2)を使いました。
定数判定の最適化
JalV2は定数の分岐は最適化されてコンパイル時にコード生成するのでクロック指定の部分でも
case target_clock of
32_000_000: block pragma
pragma target PLLEN P4
OSCCON_SPLLEN = 1
OSCCON_IRCF = 0b1110 -- 32MHz = 8Mhz * 4
OSCCON_SCS = 0
end block
16_000_000: OSCCON_IRCF = 0b1111 -- 16MHz
8_000_000: OSCCON_IRCF = 0b1110 -- 8MHz
4_000_000: OSCCON_IRCF = 0b1101 -- 4MHz
2_000_000: OSCCON_IRCF = 0b1100 -- 2MHz
1_000_000: OSCCON_IRCF = 0b1011 -- 1MHz
500_000: OSCCON_IRCF = 0b1010 -- 500kHz HF
250_000: OSCCON_IRCF = 0b1001 -- 250kHz HF
125_000: OSCCON_IRCF = 0b1000 -- 125kHz HF
otherwise OSCCON_IRCF = 0b1101 -- 4MHz
end case
実際には
; 56 16_000_000: OSCCON_IRCF = 0b1111 -- 16MHz movlw 135 andwf v_osccon,w iorlw 120 movwf v_osccon
の部分だけコードになってます。
c言語だとプリプロセッサ命令(#IF)使う部分をJalV2は普通に記述できるんです。
凄いですね。
部品
PIC12F1822 80円/1個
2N7002k 200円/40個
赤外線LED 100円/10個
CR2032 100円/2個
CR2032電池ホルダー 35円/1個
Frisk基板 100円/2枚
Frisk空き箱
抵抗20Ω 100円/100本
SMD部品を先にはんだ付け
コード
-- ------------------------------------------------------
-- Title: Nikon ML-L3 IR Wireless Remote Control of the Microchip pic12f1822
--
-- Author: Masahiko KANETAKA, Copyright (c) 2013, all rights reserved.
-- http://kane4d.blogspot.jp/
-- kane4d at gmail.com
--
-- Adapted-by:
--
-- Compiler: 2.4p
--
-- Description:
-- Nikon ML-L3 IR Wireless Remote Control for Microchip PIC12f1822.
--
-- Sources:
--
-- Notes:
-- - File creation date/time: 13 Apr 2013 14:11:50.
--
-- ------------------------------------------------------
--
include 12f1822 -- target PICmicro
-- Vdd 1--+---+--8 Vss
-- CCP1/RA5 2--| |--7 RA0/ICSPDAT
-- CLKo/RA4 3--| |--6 RA1/ICSPCLK
-- MCLR/RA3 4--+---+--5 RA2/CCP1
--
-- #1 Vdd
-- #3 CLOCK Out
-- #5 PWM LED Drive
-- #8 Vss
-- include 16f1823
-- Vdd 1--+---+--14 Vss
-- RA5 2--| |--13 RA0/ICSPDAT
-- RA4 3--| |--12 RA1/ICSPCLK
-- MCLR/RA3 4--| |--11 RA2
-- RC5 5--| |--10 RC0
-- RC4 6--| |--9 RC1
-- RC3 7--+---+--8 RC2
-- This program assumes that a 4 MHz Internal OSC
pragma target clock 16_000_000 -- oscillator frequency
pragma target PLLEN P1
pragma target OSC INTOSC_NOCLKOUT -- INTOSC
OSCCON_SPLLEN = 0
OSCCON_SCS = 0b10
case target_clock of
32_000_000: block
pragma target PLLEN P4
OSCCON_SPLLEN = 1
OSCCON_IRCF = 0b1110 -- 32MHz = 8Mhz * 4
OSCCON_SCS = 0
end block
16_000_000: OSCCON_IRCF = 0b1111 -- 16MHz
8_000_000: OSCCON_IRCF = 0b1110 -- 8MHz
4_000_000: OSCCON_IRCF = 0b1101 -- 4MHz
2_000_000: OSCCON_IRCF = 0b1100 -- 2MHz
1_000_000: OSCCON_IRCF = 0b1011 -- 1MHz
500_000: OSCCON_IRCF = 0b1010 -- 500kHz HF
250_000: OSCCON_IRCF = 0b1001 -- 250kHz HF
125_000: OSCCON_IRCF = 0b1000 -- 125kHz HF
otherwise OSCCON_IRCF = 0b1101 -- 4MHz
end case
-- configuration memory settings (fuses)
pragma target WDT disabled -- no watchdog
pragma target DEBUG disabled -- no debugging
pragma target LVP disabled -- no Low Voltage Programming
pragma target MCLR internal -- reset internally
pragma target CLKOUTEN disabled --enabled
include pwm_hardware
include delay
enable_digital_io() -- make all pins digital I/O
--
alias clkout_test_pin is pin_CLKOUT --RA4
pin_CLKOUT_direction = output
if (true) then
pin_CCP1_RA2_direction = output
APFCON_CCP1SEL = 0 --RA2
else
pin_CCP1_RA5_direction = output
APFCON_CCP1SEL = 1 --RA5
end if
-- pwm_max_resolution(1)
pwm_set_frequency(38_400) -- 38.4KHz
pwm1_set_dutycycle_percent(0)
-- http://www002.upp.so-net.ne.jp/hard-and-soft/IR_Remocon/IR_Remocon.html
-- http://www.sbprojects.com/projects/nikon/index.php
-- high low high low high low high
-- +--------+ +-------+ +-------+ +-------+
-- | | 28000us | | 1580us | | 3580us | | 63000us
----+ 2000us +---------+ 400us +--------+ 400us +--------+ 400us +---------+
_usec_delay(2_000)
pwm1_set_dutycycle_percent(50)
for 2 loop
--forever loop
pwm1_on()
--_usec_delay(2_000)
delay_1ms(2)
pwm1_off()
--_usec_delay(28_000)
delay_1ms(28)
pwm1_on()
--_usec_delay(400)
delay_10us(40)
pwm1_off()
--_usec_delay(1_580)
delay_10us(158)
pwm1_on()
--_usec_delay(400)
delay_10us(40)
pwm1_off()
--_usec_delay(3_580)
delay_1ms(3)
delay_10us(58)
pwm1_on()
--_usec_delay(400)
delay_10us(40)
pwm1_off()
--_usec_delay(63_000)
delay_1ms(63)
end loop
pwm1_off()
asm sleep
--
JalV2のソースとHEX
OSC16MHzはPWM38.4Hzを発生できるクロックなら変更可能だと思う。
2013/5/5 OSC1MHzに変更 1MHzだとdelay関数が正しく働かないので、実測値でパラメータを設定しました。