ポイント
ポイント制御は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の修正

/