/*
// STEPPING MOTOR TEST
// Ver No. 0.2       2023/08/25
// PIC18F25K42 
// XC8 Cコンパイラー用
 *
 *MOtor :17HS3401S
 *Driver : STSPIN220
 * 
 *
 * 
 *  

*/
// PIC18F27K42 Configuration Bit Settings

// 'C' source line config statements

// CONFIG1L
#pragma config FEXTOSC = OFF    // External Oscillator Selection (Oscillator not enabled)
#pragma config RSTOSC = HFINTOSC_64MHZ// Reset Oscillator Selection (HFINTOSC with HFFRQ = 64 MHz and CDIV = 1:1)

// CONFIG1H
#pragma config CLKOUTEN = OFF   // Clock out Enable bit (CLKOUT function is disabled)
#pragma config PR1WAY = OFF     // PRLOCKED One-Way Set Enable bit (PRLOCK bit can be set and cleared repeatedly)
#pragma config CSWEN = OFF      // Clock Switch Enable bit (The NOSC and NDIV bits cannot be changed by user software)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)

// CONFIG2L
#pragma config MCLRE = INTMCLR  // MCLR Enable bit (If LVP = 0, MCLR pin function is port defined function; If LVP =1, RE3 pin fuction is MCLR)
#pragma config PWRTS = PWRT_64  // Power-up timer selection bits (PWRT set at 64ms)
#pragma config MVECEN = ON     // Multi-vector enable bit (Interrupt contoller does not use vector table to prioritze interrupts)
#pragma config IVT1WAY = OFF    // IVTLOCK bit One-way set enable bit (IVTLOCK bit can be cleared and set repeatedly)
#pragma config LPBOREN = OFF    // Low Power BOR Enable bit (ULPBOR disabled)
#pragma config BOREN = SBORDIS  // Brown-out Reset Enable bits (Brown-out Reset enabled , SBOREN bit is ignored)

// CONFIG2H
#pragma config BORV = VBOR_2P45 // Brown-out Reset Voltage Selection bits (Brown-out Reset Voltage (VBOR) set to 2.45V)
#pragma config ZCD = OFF        // ZCD Disable bit (ZCD disabled. ZCD can be enabled by setting the ZCDSEN bit of ZCDCON)
#pragma config PPS1WAY = ON     // PPSLOCK bit One-Way Set Enable bit (PPSLOCK bit can be cleared and set only once; PPS registers remain locked after one clear/set cycle)
#pragma config STVREN = ON      // Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)
#pragma config DEBUG = OFF      // Debugger Enable bit (Background debugger disabled)
#pragma config XINST = OFF      // Extended Instruction Set Enable bit (Extended Instruction Set and Indexed Addressing Mode disabled)

// CONFIG3L
#pragma config WDTCPS = WDTCPS_31// WDT Period selection bits (Divider ratio 1:65536; software control of WDTPS)
#pragma config WDTE = OFF       // WDT operating mode (WDT Disabled; SWDTEN is ignored)

// CONFIG3H
#pragma config WDTCWS = WDTCWS_7// WDT Window Select bits (window always open (100%); software control; keyed access not required)
#pragma config WDTCCS = SC      // WDT input clock selector (Software Control)

// CONFIG4L
#pragma config BBSIZE = BBSIZE_512// Boot Block Size selection bits (Boot Block size is 512 words)
#pragma config BBEN = OFF       // Boot Block enable bit (Boot block disabled)
#pragma config SAFEN = OFF      // Storage Area Flash enable bit (SAF disabled)
#pragma config WRTAPP = OFF     // Application Block write protection bit (Application Block not write protected)

// CONFIG4H
#pragma config WRTB = OFF       // Boot Block Write Protection bit (Boot Block not write-protected)
#pragma config WRTC = OFF       // Configuration Register Write Protection bit (Configuration registers not write-protected)
#pragma config WRTD = OFF       // Data EEPROM Write Protection bit (Data EEPROM not write-protected)
#pragma config WRTSAF = OFF     // SAF Write protection bit (SAF not Write Protected)
#pragma config LVP = ON         // Low Voltage Programming Enable bit (Low voltage programming enabled. MCLR/VPP pin function is MCLR. MCLRE configuration bit is ignored)

// CONFIG5L
#pragma config CP = OFF         // PFM and Data EEPROM Code Protection bit (PFM and Data EEPROM code protection disabled)

// CONFIG5H

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#include <xc.h>








#define _XTAL_FREQ 16000000 //16MHz

#define TMR1ON T1CONbits.ON 
#define MODE1 LATCbits.LATC3 
#define MODE2 LATAbits.LATA5
#define MODE3 LATAbits.LATA3
#define MODE4 LATAbits.LATA2
#define DIR LATAbits.LATA2
#define STEP LATAbits.LATA3
#define STBY LATAbits.LATA4

#define M_ON PORTBbits.RB5// MOTOR ON/OFF
#define M_DIR PORTBbits.RB3// CW/CCW
#define BLED LATCbits.LATC2

#define uchar unsigned char
#define uint unsigned int
#define ulint unsigned long int


unsigned char T1H = 0xD8;//TMR1初期値 50Hz B1 100Hz D8 200Hz EC
unsigned char T1L = 0xF0;//TMR1初期値 50Hz E0 100Hz F0 200Hz 78
unsigned int STEPNum,STEPNO,STEPing; 
unsigned char STEPingFlg;
unsigned char CHATA = 40;

uchar lastM_ON;





char getM_ONSw(){
 	char sw,last,cnt;
 	cnt=0;
 	last= M_ON; //Motor ON スイッチの接続ポート
	while(cnt < CHATA){
		__delay_us(500);
 		sw=M_ON;
 		if(last == sw){ // 前回の状態と比較
			cnt++; //安定状態
 			}else{
			cnt=0; //チャタリング発生中
 			}
 		last=sw; // 今の状態を前回の状態とする
 		}
	return sw;
 	}




void M_ONsw_check() {
	char sw;
	if (M_ON == 1) {lastM_ON = 1; return;}
	if (M_ON == lastM_ON) { return; }
	if (STEPingFlg == 1){return;}
	sw=getM_ONSw(); // チャタリング除去済のスイッチ状態
	if( (lastM_ON !=sw) && (M_ON == 0) ){ // スイッチが押されて、かつ現在ON
		TMR1H = T1H;TMR1L = T1L;
         TMR1ON = 1;
         STEPing = 0;
         STEPingFlg = 1;	
		}
	lastM_ON = 0;
	}





//*******************************************************************************
// *  InterruptFunction()   割り込みの処理                                            *
// *******************************************************************************/
	//timer 1 10msec 間隔で割り込み
void __interrupt(irq(IRQ_TMR1)) TMR1_ISR(void) {

		TMR1IF = 0;
		TMR1IE = 0;
        STEPing++;
		TMR1ON = 0;
		TMR1H = T1H;//45537;// 4MHz/2/200Hz=10000 5msec間隔	2^16-10000=55536
		TMR1L = T1L;//TMR1 = 55536+1 = 0xD8F0
		TMR1ON = 1;
		TMR1IE = 1;
	BLED = ~BLED;
    STEP = ~STEP;
}




void main() {

    OSCFRQ = 0b00000101;//16MHz
    OSCCON1 = 0b01100000;
    OSCCON2 = 0b01100010; //HFINTOSC 16MHz  CDIV =1/4 = 4MHz

    PORTA = 0b00000000; // 
    TRISA = 0b00000000; //RA0-7 出力設定
    ANSELA = 0b00000000; //ADコンバーターなし
    PORTB = 0b00000000; //
    TRISB = 0b11111111; // RB0-RB7入力
    ANSELB = 0b00000000; //ADコンバーター使用せず
    PORTC = 0b01000000; //ポートC　RC6=H UART TX
    TRISC = 0b10111000; //RCポート0-2出力 3-5.7 input
	ANSELC = 0b00000000; //ADコンバーター使用せず
    T1CON = 0b00010010; //CKPS=1/2 16bit Timer1 OFF
    T1CLK = 0b00000001; //FOSC/4:4MHz
	TMR1H = T1H;//
    TMR1L = T1L;//

	TMR1IE = 1;
    
    STBY = 0;
    __delay_ms(10);
    STBY = 0;
    MODE1 = 0;
    MODE2 = 1;
    MODE3 = 0;
    MODE4 = 1;
    __delay_ms(10);
    STBY = 1;
    __delay_ms(10);
    MODE4 = 0;

	GIE = 1;//全割込み許可
    

    while (1) {
        STEPNum = 800;STEPNO = STEPNum * 2;//800で1回転
        M_ONsw_check();
        if (STEPingFlg == 1){
           if (STEPNO <= STEPing) {
               if (STEP == 0) {TMR1ON = 0;}
               STEPingFlg = 0;
           } 
        }
        DIR = M_DIR;

    }
}
