ポイント

ポイント制御はPIC16F1827を使用します。

ハードの部分はこちらです。

MCC Melody でコードを作ります。

 

 

 

プロジェクトが開いたらMCCボタンを押し、MCC Melody を選択します。

Finishを押すとMCC設定画面になります。

ConfigurationBits設定

Config1のOscillatorSelectionをINTOSC

Config2 Low-Voltage Programming Enabel を High-Voltage(Disable)

ClockControl設定

ClockControlで最高速32MHzに設定するには少し手間が必要で、まずは

systemClockSlect:INTOSC

InternalOscillatorFrequencySelect:8MHz_HF

にします。

そのあと、

systemClockSlect:FOSC

SoftwarePLL Enable:ON

OSCCONが0xf0になるようにします。

ConfigurationBitsのConfig2ーPLL Enableを4×PLL Enableにして、SoftwarePLL EnableをOFFでも同じです。この時はOSCCON:0x70になります。

また、 __delay_ms(500);などのディレイマクロを使用するには、ExternalClock(Hz)の値を

32000000に書き換えます。こうするとcloch.h内の

#define _XTAL_FREQ 32000000

に書き換わりこのマクロのディレイ時間が合います。

InterruptManager設定

EXT_INTのEnableをチェック

INT EdgeDetectをFalling_edge

PORTB:0をクリックするとRB0がINT入力端子になりPinsを選択するとWeakPullupもチェックが入っています。

Genarateボタンを押すとコードが作成されます。

ファイルの追加
point.c
//
//2023 0805
//point.c
#include "mcc_generated_files/system/system.h"

#define ExtInt	RB0
#define ExtData	RB1

#define P_0		TRISA1
#define P_1		TRISA0
#define P_2		TRISB5
#define P_3		TRISB4
#define P_4		TRISB3
#define P_5		TRISB2
#define P_6		TRISA2
#define P_7		TRISA3
#define P_COM	TRISA4


#define ON_TIME 12
#define OFF_TIME 12
#define POINT_ADR 0x60
#define POINT_ADR_SEND 0x70

int IntCount;
unsigned char bit_p;
unsigned char receive_data;
unsigned char data_p;
unsigned char RxData[128];
unsigned char send_data;
unsigned char busy;
unsigned char point_req;
unsigned char p_counter;
unsigned char seq_num = 0;
unsigned char EnableBit[] = {1, 2, 4, 8, 16, 32, 64, 128};

unsigned char data_bit;

unsigned char dir; //切り替え方向
unsigned char p_num; //point番号

void point_chg(unsigned char, unsigned char);

void point_main() {

    //---LED SIGN---
    TRISA7 = 0;
    RA7 = seq_num & 1;

    if (!p_counter) //P_counter=0
        switch (seq_num) {
            case 0:
                if (point_req) {
                    busy = point_req;

                    //point切り替え方向
                    if (busy & 0x40)
                        dir = 1;
                    else
                        dir = 0;

                    //point ON
                    p_num = busy & 0x7; //point番号セット
                    point_chg(p_num, dir);

                    p_counter = ON_TIME; //ON時間

                    seq_num++;
                }

                break;
            case 1:
                //point off
                TRISA = 0xff; //FET OFF
                TRISB |= 0b11111100;
                //P_COM = 1; //COM
                p_counter = OFF_TIME; //OFF時間
                seq_num++;
                break;
            case 2:
                //2回目 ON
                point_chg(p_num, dir);
                p_counter = ON_TIME;
                seq_num++;
                break;
            case 3:
                //point OFF
                TRISA = 0xff; //FET OFF
                TRISB |= 0b11111100;
                //P_COM = 1; //COM
                p_counter = OFF_TIME;
                seq_num++;
                break;
            case 4:
                //busy 解除
                //リクエストCLRまで待機
                if (point_req == 0) {
                    busy = 0;
                    seq_num = 0; //処理終了
                }
                
                break;
                
        }

}

void point_int() {

    IntCount++;

    if (ExtInt == 0) {
        //--- IntCount 0 ---
        IntCount = 0;
        if (p_counter)
            p_counter--;

    }

    //受信
    TRISB1 = 1; //PortInput

    data_p = (IntCount - 1) >> 3;
    bit_p = EnableBit[(IntCount - 1) & 0b111];


    if (data_bit)//inp_bit
        receive_data |= bit_p;
    else
        receive_data &= ~bit_p;

    if (bit_p == 0x80) {
        RxData[data_p] = receive_data; //DataSet

        if (data_p == POINT_ADR) {//現位置確認
            point_req = RxData[POINT_ADR]; //DataSet
            //point_req =0x80;
        }
    }


    data_p = IntCount >> 3;

    if (data_p == POINT_ADR_SEND) {//0x70 POINT_ADR
        //送信
        TRISB1 = 0; //PortOutput
        bit_p = EnableBit[IntCount & 0b111];

        //send_data = point_req;
        send_data = busy;

        if (send_data & bit_p)
            ExtData = 1;
        else
            ExtData = 0;

    }


}

void point_chg(unsigned char p, unsigned char d) {
    //方向設定
    if (d) {
        //切り替え
        PORTA = 0b11101111;
        PORTB |= 0b11111100;
    } else {
        //戻し
        PORTA = 0b00010000;
        PORTB &= 0b00000011;
    }
    TRISA = 0xff;
    TRISB |= 0b11111100;

    //選択されたポイントのみ出力ポートに設定(FET ON)
    switch (p) {
        case 0:
            P_0 = 0;
            break;
        case 1:
            P_1 = 0;
            break;
        case 2:
            P_2 = 0;
            break;
        case 3:
            P_3 = 0;
            break;
        case 4:
            P_4 = 0;
            break;
        case 5:
            P_5 = 0;
            break;
        case 6:
            P_6 = 0;
            break;
        case 7:
            P_7 = 0;
            break;
    }

    P_COM = 0; //COM側
}

point.h
//
//2023 0805
//point.h
//
void point_main(void);
void point_int(void);

extern unsigned char data_bit;




system.hの修正

pins.cの修正

interrupt.cの修正

main.cの修正