JH7UBCブログ

アマチュア無線 電子工作 家庭菜園など趣味のブログです

PIC12F1840 ロータリーエンコーダ テスト

2019-06-22 20:45:41 | PIC12F1822/40

 しばらくぶりに、PICの記事を書きます。

 先日製作した3.5MHz/7MHz用SDRフロントエンド+パソコンを受信機とし、簡単な7MHz CW送信機と組み合わせて交信してみたいと考えました。

 そこで、3チャンネルクロックジェネレータSi5351AをVFOとして使い、BS170 E級のファイナルとして、2~3Wの送信機を作ってみようと思います。

 Si5351Aのコントロールは、PIC12F1840を使うことにします。

 今日は、第一段階として、PIC12F1840でロータリーエンコーダを使うテストをしました。

 回路図です。ロータリーエンコーダの回転方向を判定して、シリアル通信でパソコンに結果を送り、TeraTermの「RIGHT」「LEFT」と表示します。シリアルUSB変換は、FT234モジュールを使用します。

 OPTION_REGのnWPUEN=0として、ウィークプルアップを有効にします。

 更にWPUA=0b00110000として、RA4とRA5をウィークプルアップします。これにより、プルアップ抵抗を省略しています。

 ロータリーエンコーダは、回転させると接点A,Bの状態(+か0)が変化し、RA4とRA5の状態が変化します。このピンの状態が変化したときに割り込みがかかるようにして(IOC割り込み)、回転方向を判定します。

 IOCIE=1として、ピン状態変化割り込みを有効にします。

 更に、IOCAP=0b00110000として、RA4とRA5のピン状態の立ち上がり検出を有効にし、IOCAN=0b00110000として、ピン状態の立下り検出も有効にします。

 回転方向に判定方法については、JH7UBCホームページのここを見てください。

 ブレッドボードです。

 プログラムです。

/*
 * File:   main.c
 * Author: JH7UBC Keiji Hata
 * PIC12F1840 Rotary Encoder test
 * Created on 2019/06/22
 */
#include <stdio.h>
#include <stdlib.h>
#include <xc.h>
 
// CONFIG1
#pragma config FOSC     = INTOSC
#pragma config WDTE     = OFF
#pragma config PWRTE    = ON
#pragma config MCLRE    = OFF
#pragma config CP       = OFF
#pragma config CPD      = OFF
#pragma config BOREN    = ON
#pragma config CLKOUTEN = OFF
#pragma config IESO     = OFF
#pragma config FCMEN    = OFF
 
// CONFIG2
#pragma config WRT    = OFF
#pragma config PLLEN  = ON
#pragma config STVREN = ON
#pragma config BORV   = HI
#pragma config LVP    = OFF
#define _XTAL_FREQ 32000000
 
/* ロータリーエンコーダ関係定義*/
#define ECA RA5 //エンコーダA
#define ECB RA4 //エンコーダB
volatile unsigned char curDat;
volatile unsigned char befDat;
volatile signed char count= 0;
 
void serial_init(unsigned long BR){
    TXSTA = 0x24;   //SYNC=0 TXEN = 1 BRGH = 1
    BRG16 = 1;      //BRG 16bit mode
    RCSTA = 0x90;   //非同期、継続受信可
    unsigned int X= _XTAL_FREQ/BR/4 - 1;
    SPBRGH = X / 256;
    SPBRGL = X % 256;
}
 
void putch(unsigned char byte){
    while(!TXIF);
    TXREG = byte;
}
 
void __interrupt() isr(){
    IOCIF = 0;   //割り込みフラッグクリア
    IOCAF = 0;
    __delay_ms(2);
    curDat = ECA + (ECB<<1);
    if (befDat != curDat){
        unsigned char d = ((befDat<<1)^curDat) & 3; //回転方向判定
        if(d < 2){
            count++;
        }else{
            count--;
        }
        befDat = curDat;
    }
    if(count >= 4){
        printf("RIGHT\r\n");
        count = 0;
    }else if(count <= -4){
        printf("LEFT\r\n");
        count = 0;
    }
}
 
void main() {
    OSCCON = 0b01110000 ;     // 内部クロック8MHz
    ANSELA = 0b00000000 ;     // アナログは使用しない
    TRISA  = 0b00110010 ;     // RA1,RA4,RA5は入力、他は出力
    PORTA  = 0b00000000 ;     // 出力ピンの初期化
    OPTION_REGbits.nWPUEN = 0;//ウィークプルアップ許可
    WPUA = 0b00110000;        //RA4,RA5をウィークプルアップ
   
    /* 割り込み関係設定 */
    IOCIE = 1;                //状態変化割り込み許可
    IOCAP = 0b00110000;       //RA4,RA5立ち上がりエッジ検出
    IOCAN = 0b00110000;       //RA4,RA5立ち下りエッジ検出
    PEIE = 1;                 //周辺割り込み許可
    GIE = 1;                  //全割り込み許可
   
    /* シリアル通信設定 */
    serial_init(9600);
   
    while(1){
    }
}
 
 TeraTernの画面です。時計方向に回転させると「RIGHT」、反時計回りに回転させると「LEFT」と表示されます。
 
 コンパイラは、xc8 Ver2.05を使っています。
 コンパイルエラーが出るときは、Project PropartiesでXC8 Global OptionのC standerdをC99からC90に変更してください。
 


最新の画像もっと見る

コメントを投稿