JH7UBCブログ

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

PIC16F1827 8×7セグメントLED表示周波数カウンタのケーシング

2023-06-01 16:01:38 | PIC16F1827
 PIC16F1827 MAX7219使用8桁7セグメントLED周波数カウンタをケースに入れて完成させます。

 何か適当なケースはないかと考えました。100円ショップででも探そうと思ったのですが、ちょうど良い大きさのプラスチックケースを見つけました。MAX7219使用8桁7セグメントLEDを購入した時に入ってきたケースです。



 大きさは、外寸で90×66×30mmです。70×50mmのユニバーサル基板がすっぽり入り、LEDもちょうど収まります。

 電源は、microUSBで供給し、入力にはBNCコネクタを使います。加工を始めてみるとプラスチックケースは柔らかく加工しずらいものです。

 基板表面です。LEDの右端を少しカットしました。
 

 基板の裏面です。



 周波数をカウントしています。ゲートオープンを示すLEDは緑色にしました。


 LCD表示に比べ、8桁7セグメントLED表示は、文字が大きく明るく、非常に視認性が良いです。

 これで完成です。

PIC16F1827 8桁7セグメントLED表示周波数カウンタ

2023-05-29 19:24:37 | PIC16F1827
 PIC16F1827を使った周波数カウンタは2019年に試作し、JH7UBCホームページのここに掲載しています。周波数カウンタの仕組みも解説していますので、ご一読ください。

 この時は、LCD1602を周波数の表示器として使いました。今回は、MAX7219使用の8桁7セグメントLEDを表示器として使用した周波数カウンタを試作してみます。プログラムは、LCD版周波数カウンタのプログラムの表示部分を8×7セグメントLEDに差し替えました。

 回路図です。入力を増幅するため簡単なアンプをつけました。
 カウンタのゲートが開いている時LEDが点灯します。


プログラムです。
----------------------------------------------------------
/* 
 * PIC16F1827 Frequency Counter
 * Author: JH7UBC
 * Keiji Hata
 * 2023/05/29
 */

#include <stdio.h>
#include <stdlib.h>
#include <xc.h>

// CONFIG1
#pragma config FOSC = ECH //外部クロック
#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 = OFF
#pragma config STVREN = ON
#pragma config BORV = HI
#pragma config LVP = OFF

#define _XTAL_FREQ 20000000 //クロック20MHz
#define LED LATAbits.LATA4

// MAX7219 Register Address
#define MAX7219_DECODE_MODE 0x09
#define MAX7219_INTENSITY 0x0a
#define MAX7219_SCAN_LIMIT 0x0b
#define MAX7219_SHUTDOWN 0x0C
#define MAX7219_DISPLAY_TEST 0x0f

#define CS LATBbits.LATB3

void SPI_init(){
      SSP1CON1 = 0b00100000; //SSP1EN=1:SSP1 Enable,CKP=0:Idle Low,Clock=FOSC/4
      SSP1STAT = 0b01000000; //SMP=0:middle,CKE=1:Active to Idle
}

void maxTransfer(uint8_t address,uint8_t data){
      CS = 0;
      uint8_t dammy;
      //send address
      dammy = SSP1BUF;
      SSP1BUF = address;
      while(!SSP1STATbits.BF);
      //send data
      dammy = SSP1BUF;
      SSP1BUF = data;
      while(!SSP1STATbits.BF);
      CS =1;
}

void MAX7219_init(){
      maxTransfer(MAX7219_DECODE_MODE, 0xff);// Code B decode for digits 7-0
      maxTransfer(MAX7219_INTENSITY, 0x03); // Intensity
      maxTransfer(MAX7219_SCAN_LIMIT, 0x07);// Display digits 01234567
      maxTransfer(MAX7219_SHUTDOWN, 0x01);// Normal Operation
      maxTransfer(MAX7219_DISPLAY_TEST, 0x00);// Normal Operation
}

void Clear_Display(){
      for(uint8_t i=1;i<=8;i++){
         maxTransfer(i,0x0f);
    }
}

//数値を表示する
void Num_Display(uint32_t n){
      uint32_t josu = 10000000;
      uint8_t sho;
      uint32_t joyo;
      uint8_t i=8;
      uint8_t zflag = 1;
      while(i){
          sho = n / josu;
          joyo = n % josu;
         if(zflag==1 && sho==0 && i!=1){
              sho = 0x0f; //空白
          }
          else{
              zflag = 0;
          }
           maxTransfer(i,sho);
          n = joyo;
          josu = josu / 10;
          i--;
    }
}

static uint16_t MeassuremmentCnt;

/*TMR2のオーバーフロー割り込み*/
void __interrupt(high_priority) isr(){
     TMR2IF = 0;//TMR2割り込みフラッグクリア
     MeassuremmentCnt--;
     if (MeassuremmentCnt == 0){
         TMR1ON = 0;//ゲートを閉める。
         TMR2ON = 0;//TMR2を停止する。
    }
}

/*周波数測定*/
uint32_t FreqMeassurement(){
     static uint32_t freq;
     /*TIMERの初期化*/
     TMR1IF = 0; //TMR1割り込みフラッグクリア
     TMR1L = 0; //TMR1クリア
     TMR1H = 0;
     /*TMR2の初期化*/
     TMR2IF = 0; //TMR2割り込みフラッグクリア
     MeassuremmentCnt = 1221;
     TMR2 = 0x4C;
     /*counter 初期化*/
     freq = 0;
     /*割り込み許可*/
     PEIE = 1;
     GIE = 1;
     //count start
     TMR2ON = 1;
     /* gate time調整 NOP 25 */
     NOP();
     NOP();
     NOP();
     NOP();
     NOP();
     NOP();
     NOP();
     NOP();
     NOP();
     NOP();
     NOP();
     NOP();
     NOP();
     NOP();
     NOP();
     NOP();
     NOP();
     NOP();
     NOP();
     NOP();
     NOP();
     NOP();
     NOP();
     NOP();
     NOP();
     /*ゲートを開ける*/
     TMR1ON = 1;
     while(TMR2ON){
         if(TMR1IF == 1){
             TMR1IF = 0;
             freq ++;
         }
    }
     if(TMR1IF == 1){
         TMR1IF = 0;
         freq ++;
    }
     /*換算*/
     freq = freq * 65536;
     freq = freq + ((unsigned)TMR1H * 256) + (unsigned)TMR1L;

     return(freq);
}


int main() {
     ANSELA = 0b00000000 ; // AN0-AN4は使用しない
     ANSELB = 0b00000000 ; // AN5-AN11は使用しない
     TRISA = 0b10000000 ; // RA7は入力 他は出力(RA5は入力)
     TRISB = 0b01000000 ; // RB6は入力他は出力
     PORTA = 0b00000000 ; // PORTA初期化
     PORTB = 0b00000000 ; // PORTB初期化
     CS = 1; //CS初期値
     SPI_init();      //SPI初期化
     MAX7219_init();  //MAX7219初期化
     Clear_Display(); //ディスプレイクリア
     LED = 0;
     /*TMR2の設定*/
     TMR2IE = 1; //TMR2割り込み許可
     TMR2IF = 0; //TMR2割り込みフラッグクリア
     T2OUTPS0 = 0; //TMR2 output poststscaler 1:1
     T2OUTPS1 = 0;
     T2OUTPS2 = 0;
     T2OUTPS3 = 0;
     TMR2ON = 0; //TMR2 off
     T2CKPS0 = 0; //TMR2 prescaler 1:16
     T2CKPS1 = 1;
     TMR2 = 0; //TMR2 clear

     /*TMR1の設定*/
     TMR1IE = 0; //TMR1割り込み禁止
     TMR1IF = 0; //TMR1割り込みフラッグクリア
    T1CKPS0 = 0; //TMR1 prescaler 1:1
     T1CKPS1 = 0;
     T1OSCEN = 0; //TMR1 Clock source = T1CKI
     TMR1CS1 = 1;
     TMR1CS0 = 0;
     nT1SYNC = 1;
     TMR1ON = 0; //TMR1 stop
     TMR1L = 0; //TMR1 clear
     TMR1H = 0;

     while(1){
         /*周波数の測定*/
         LED = 1;//RA4 LED ON
         uint32_t frequency = FreqMeassurement();
         LED = 0;//RA4 LED OFF
         Num_Display(frequency);
         __delay_ms(500); 
    }
}
----------------------------------------------------------
 MPLAB X IDEは、v6.00をXC8はv2.40を使っています。
 ゲートタイム(1秒)は、プログラム中のNOP();の数で調整します。
 今のところ、NOP 25個でちょうど良いようです。
 MAX7219使用8X7セグメントLEDテストのままの表示プログラムですと、入力がない時に何も表示されませんので、ちょっと不安になります。そこでカウントが0の時は、0が表示されるように変更しました。

 1MHzを入力した時の表示の様子です。


 10MHzの時です。


 周波数の測定範囲は10Hz~約50MHzです。
 誤差は、数ppm程度だと思います。
 自作SGからの信号ですから、どちらがずれているかの判断は難しいです。

 この後、簡単な筐体に入れて、周波数カウンタとして仕上げてみたいと思います。

PIC16F1827 MAX7219 8×7セグメントLED表示テスト その2

2023-05-24 11:24:22 | PIC16F1827
 前の記事の続きです。
 PIC16F1827でMAX7219使用の8×7セグメントLEDに数値を表示するテストをします。

 一般に良く利用されるLCD表示器LCD1602などの場合、キャラクタコードを送るだけでよいのですが、MAX7219の場合は、Digit番号と数値を送る必要があります。そこで、PIC内の数値(バイナリ)を10進数に変換しなければなりません。

 以前、ArduinoでMAX7219のテストをしたときには、数値を文字列に変換し、LEDに表示するために、アスキーコードを数値に変換しました。その記事はこちら

  今回は、簡単なアルゴリズムで数値(バイナリ)から表示用のデータを取り出すことにしました。10のn乗で割って、商と剰余を計算し、その都度、商を表示する方法です。
 例えば数値 n=12345678とした場合、表示器の桁数が8桁ですので、除数josu=10000000で割ります。商は sho=12345678 / 10000000 = 1 です。このshoの値をDigit8にセットすればいいわけです。この時、余り(剰余)は、joyo=12345678 % 10000000 = 2345678となります。
 このjoyoをnとして、次は除数を1/10にして、josu=1000000として、同じ計算をして、Digit7にセットします。以下この繰り返しになります。
 このままだと小さい数値の場合に上位に「0」が表示されてしまいますので、ゼロ消しをします。最初にゼロフラッグzflagを立てておいて、最初の数値がゼロでなくなったときにゼロフラッグを下ろします。ゼロフラッグが立っている時には「0」ではなく、「空白」を表示するようにします。

 これをプログラムにすると次のようになります。
-------------------------------------------------------
//数値を表示する
void Num_Display(uint32_t n){
     uint32_t josu = 10000000;
     uint8_t sho;
     uint32_t joyo;
     uint8_t i=8;
     uint8_t zflag = 1;
     while(i){
         sho = n / josu;
         joyo = n % josu;
         if(zflag==1 && sho==0){
             sho = 0x0f; //空白
         }
         else{
             zflag = 0;
         }
          maxTransfer(i,sho);
         n = joyo;
         josu = josu / 10;
         i--;
    }
}
-------------------------------------------------------

 mainルーチンに
uint32_t k = 0;
     while(1){
         Num_Display(k);
         k++;
         __delay_ms(100);
    }
を書き込んで、0.1秒ごとに数値をカウントアップさせてみました。
その時の様子です。ゼロ消しがされた数値が表示され、カウントアップされました。


 もっとうまい方法があると思うのですが、とりあえず表示されました。

PIC16F1827 MAX7219 8×7セグメントLED表示テスト その1

2023-05-23 14:12:59 | PIC16F1827
 昨年の秋、MPLAB X + XC8 + MCC環境下で、PIC16F1827を使って、MAX7219使用8桁7セグメントLEDの表示テストをしました。しかし、うまくいきませんでした。

 MCCを使うとCONFIGの設定や各設定が格段に楽になるのですが、その分ブラックボックス化され、いざ不具合を見つけようとすると難しくなります。

 そこで、今回はMCCを使わないで、XC8だけでテストをしてみます。MAX7219使用8桁7セグメントLEDの表示テストについては、Arduinoで既に行っており(当ブログでの記事はこちら)、今回はそのスケッチをMPLAB Xに移植する形で行いました。

 テストした回路図です。PIC16F1827のクロックは、今後周波数カウンタへの発展を考えて、外部クロック(クリスタルオシレータ20MHz)を使っています。

 MAX7219のコントロールは、SPIで行います。その時のタイミングチャートです。(MAX7219の説明書より)
 CSを1から0にしてデータ転送を開始します。CLKの立ち上がりでDINの値が読み込まれます。8bitデータを送ったらCSを1に戻します。

 PIC16G1827でSPIのタイミングを決めるのは、SSPXCON1レジスタとSSPXSTATレジスタです。今回はSSP1を使いますのでX=1とします。
 まず、SSP1CON1レジスタの設定です。(必要な部分だけ設定します)



 SSP1を有効にするため、SSP1EN=1とします。
 クロックの極性は常時Lowでアクティブ時にHighですので、CKP=0とします。
 次に、SSP1STATレジスタの設定をします。


 クロックエッジCKEは、CKP=0のとき立ち上がりを指定のCKE=1とします。サンプル位置は中央でSMP=0とします。
 以上の条件で、PIC16F1827のSPI出力をpico scopeで確認してみました。
 SSP1BUF=0x55(0b01010101)として出力しました。
 
 MAX7219のタイミングに合っています。OKです。
 テストしたプログラムです。
--------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <xc.h>

// CONFIG1
#pragma config FOSC = ECH       //外部クロック
#pragma config WDTE = OFF       //ウオッチドックタイマーを使わない
#pragma config PWRTE = ON       //パワーアップタイマーON
#pragma config MCLRE = OFF      //外部リセット信号は使用しない、
#pragma config CP = OFF         //プログラムメモリーを保護しない
#pragma config CPD = OFF        //データメモリーを保護しない
#pragma config BOREN = ON       //ブラウンアウト リセット 有効
#pragma config CLKOUTEN = OFF   //Clock Out OFF
#pragma config IESO = OFF       //外部・内部クロックの切替えでの起動はなし
#pragma config FCMEN = OFF      //外部クロック監視しない

// CONFIG2
#pragma config WRT = OFF        //Flashメモリーを保護しない
#pragma config PLLEN = OFF      //PLLを使わない
#pragma config STVREN = ON      //スタックがオーバフローやアンダーフローしたらリセットをする
#pragma config BORV = HI        //電源電圧降下常時監視電圧(2.5V)設定(HI)
#pragma config LVP = OFF        //低電圧プログラミング機能使用しない

#define _XTAL_FREQ 20000000 //クロック20MHz
#define CS LATBbits.LATB3

// MAX7219 Register Address
#define MAX7219_DECODE_MODE 0x09
#define MAX7219_INTENSITY 0x0a
#define MAX7219_SCAN_LIMIT 0x0b
#define MAX7219_SHUTDOWN 0x0C
#define MAX7219_DISPLAY_TEST 0x0f

void SPI_init(){
     SSP1CON1 = 0b00100000; //SSP1EN=1:SSP1 Enable,CKP=0:Idle Low,Clock=FOSC/4
     SSP1STAT = 0b01000000; //SMP=0:middle,CKE=1:Active to Idle
}

void maxTransfer(uint8_t address,uint8_t data){
     CS = 0;
     uint8_t dammy;
     //send address
     dammy = SSP1BUF;
     SSP1BUF = address;
     while(!SSP1STATbits.BF);
     //send data
     dammy = SSP1BUF;
     SSP1BUF = data;
     while(!SSP1STATbits.BF);
     CS =1;
}

void MAX7219_init(){
     maxTransfer(MAX7219_DECODE_MODE, 0xff);// Code B decode for digits 7-0
     maxTransfer(MAX7219_INTENSITY, 0x03); // Intensity
     maxTransfer(MAX7219_SCAN_LIMIT, 0x07);// Display digits 01234567
     maxTransfer(MAX7219_SHUTDOWN, 0x01);// Normal Operation
     maxTransfer(MAX7219_DISPLAY_TEST, 0x00);// Normal Operation
}

void Clear_Display(){
     for(uint8_t i=1;i<=8;i++){
         maxTransfer(i,0x0f);
    }
}

void main(){
     ANSELA = 0b00000000 ; // AN0-AN4は使用しない
     ANSELB = 0b00000000 ; // AN5-AN11は使用しない
     TRISA = 0b00000000 ; // PORTAは全て出力(RA5は入力)
     TRISB = 0b00000000 ; // PORTBは全て出力
     PORTA = 0b00000000 ; // PORTA初期化
     PORTB = 0b00000000 ; // PORTB初期化
     CS = 1; //CS初期値
     SPI_init();      //SPI初期化
     MAX7219_init();  //MAX7219初期化
     Clear_Display(); //ディスプレイクリア

for(uint8_t i=1;i<=8;i++){    
     maxTransfer(i,i);
     __delay_ms(1000);
}

     while(1){
         maxTransfer(MAX7219_DISPLAY_TEST, 0x01);// 全点灯
         __delay_ms(500);
         maxTransfer(MAX7219_DISPLAY_TEST, 0x00);// normal mode
         __delay_ms(500);        
    }
}
--------------------------------------------------------------------
 ディスプレイをクリアした後、Digit0からDigit7に1から8を表示し、その後、全点灯とノーマル表示を0.5秒ごとに表示します。

 ノーマル表示の様子です。数10mA程度の電流が流れます。

 全点灯の様子です。200mA程度電流が流れます。


PIC16F1827 AD9834DDS SG

2021-02-01 20:42:19 | PIC16F1827
 昨年試作したPIC16F1827 AD9834DDS 7MHz VFOを汎用化して、SG(Signal Generator)を作ってみました。

 回路図です。AD9834DDSの出力に簡単なバッファアンプをつけました。
また、ICSPでプログラムの変更ができるように、ロータリーエンコーダーの接続を変更しました。


 ケースは、以前周波数カウンタに使っていたものを流用しました。


 内部の様子です。


 出力は、最大で約12.5dBm(17.8mW)です。周波数設定範囲は、10Hz~約24MHzで、周波数STEPは、1MHz→100KHz→10KHz→1KHz→100Hz→10Hzを循環で変更できます。

 1MHzの出力波形です。


 参考までにXC8のソースリストを掲載します。
-----------------------------------------------------------------------------------------------------
/*
* File: main.c
* Author: JH7UBC Keiji Hata
* PIC16F1827_AD9834_SG
* Created on 2021/02/01
*/


#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 //クロック32MHz


//LCD関係定義
#define LCD_EN 0b00000100 //Enable
#define LCD_BL 0b00001000 //Back Light
#define LCD_CMD 0x00
#define LCD_CHR 0x01
#define LCD_LINE1 0x80
#define LCD_LINE2 0xC0
#define LCD_addr 0x4E //0x27<<1


/* ロータリーエンコーダ関係定義*/
#define ECA RB2 //エンコーダA
#define ECB RB3 //エンコーダB
unsigned char EA;
unsigned char EB;
volatile unsigned char curDat;
volatile unsigned char befDat;
volatile signed char count= 0;


/* STEP関係設定 */
unsigned long Step = 1000000; //STEP初期値 1MHz
#define STEP_SW RB5


/* AD9834DDS関係定義 */
#define FSYNC RA0
#define SCLK RA1
#define SDATA RA2
unsigned long Freq = 1000000; //周波数初期値 1MHz
unsigned long Freq_old; //周波数の前の値

/* I2C 初期化*/
void I2C_init(){
SSP1CON1 = 0x28; //SSPEN = 1,I2C Master Mode
SSP1STATbits.SMP = 1; //標準速度モード(100KHz)
SSP1ADD = 0x4F; //Fosc/(4*Clock)-1 Clock=100kHz,Fosc=32MHz
}


/* スタートコンディション */
void I2C_start(){
SSP1CON2bits.SEN = 1;
while(SSP1CON2bits.SEN);
}


/* ストップコンディション */
void I2C_stop(){
SSP1IF = 0;
SSP1CON2bits.PEN = 1;
while(SSP1CON2bits.PEN);
SSP1IF = 0;
}


/* I2Cに1byte送信 */
void I2C_write(unsigned char dat){
SSP1IF = 0;
SSP1BUF = dat;
while(!SSP1IF);
}


void Write_data(unsigned char data){
I2C_start();
I2C_write(LCD_addr);
I2C_write(data | LCD_EN | LCD_BL);
I2C_write(data | LCD_BL);
I2C_stop();
__delay_us(100);
}


void LCD_write(unsigned char bits,unsigned char mode){
//send High 4bits
Write_data((bits & 0xF0) | mode);
//send Low 4bits
Write_data(((bits << 4) & 0xF0) | mode);
}
void LCD_init(){
LCD_write(0x33,LCD_CMD);
LCD_write(0x32,LCD_CMD);
LCD_write(0x06,LCD_CMD);
LCD_write(0x0C,LCD_CMD);
LCD_write(0x28,LCD_CMD);
LCD_write(0x01,LCD_CMD);
__delay_ms(1);
}


void LCD_clear(){
LCD_write(0x01,LCD_CMD);
__delay_ms(1);
}


void LCD_home(){
LCD_write(0x02,LCD_CMD);
__delay_ms(1);
}


void LCD_cursor(unsigned char x,unsigned char y){
if (y == 0){
LCD_write(LCD_LINE1+x,LCD_CMD);
}
if (y == 1){
LCD_write(LCD_LINE2+x,LCD_CMD);
}
}


void putch(unsigned char ch){
LCD_write(ch,LCD_CHR);
}


void Freq_disp(unsigned long frequency){
LCD_cursor(4,0);
printf("%8ld",frequency);
}


void Step_disp(unsigned long stp){
LCD_cursor(5,1);
printf("%7ld",stp);
}


void Step_change(){
__delay_ms(5);
if(Step == 10){
Step = 1000000;
}else{
Step = Step/10;
}
Step_disp(Step);
while(!STEP_SW){
__delay_ms(5);
}
}


/* AD9834DDSに16ビット送信 */
void Data_send(unsigned long data){
for(unsigned char i = 0;i<16;i++){
if(data & 0x8000){
SDATA = 1;
}else{
SDATA = 0;
}
__delay_us(1);
SCLK = 0;
__delay_us(1);
SCLK = 1;
data <<= 1;
}
}


/* AD9834DDSに周波数データを送る */
void Fnc_DDS(unsigned long frequency){
unsigned long wrk = frequency << 2;
unsigned int wrk1,wrk2,wrk3;

wrk1 = 0x2000; //コントロールワード
wrk2 = wrk & 0x3fff; //周波数データ下位
wrk2 = wrk2 | 0x4000;
wrk3 = wrk >> 14;
wrk3 = wrk3 & 0x3fff; //周波数データ上位
wrk3 = wrk3 | 0x4000;
SCLK = 1;
FSYNC = 0;
Data_send(wrk1);
Data_send(wrk2);
Data_send(wrk3);
FSYNC = 1;
}

void interrupt isr(){
IOCIF = 0; //割り込みフラッグクリア
IOCBF2 = 0;
IOCBF3 = 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){
Freq += Step;
count = 0;
}else if(count <= -4){
Freq -= Step;
count = 0;
}
}

void main(){
OSCCON = 0b01110000 ; // 内部クロック8MHz
ANSELA = 0b00000000 ; // AN0-AN4は使用しない
ANSELB = 0b00000000 ; // AN5-AN11は使用しない
TRISA = 0b00000000 ; // PORTAは全て出力(RA5は入力)
TRISB = 0b00111110 ; // RB1(SDA),RB2(REA),RB3(REB),RB4(SDA),RB5は入力他は出力
PORTA = 0b00000000 ; // PORTA初期化
PORTB = 0b00000000 ; // PORTB初期化
OPTION_REGbits.nWPUEN=0; // ウィークプルアップ許可
WPUB = 0b00101100; // RB2,RB3,RB5をプルアップ

/* IOC割り込み設定 */
IOCBN = 0b00001100; //RB2,RB3立下り割り込み設定
IOCBP = 0b00001100; //RB2,RB3立ち上がり割り込み設定
IOCIE = 1; //IOC割り込み許可
GIE = 1; //全割り込み許可

I2C_init(); //I2C初期化
LCD_init(); //LCD初期化

/* Roatry Encoder 初期値 */
EA = ECA;
EB = ECB;
befDat = EA + (EB<<1);

/* 初期表示と初期周波数設定 */
LCD_cursor(13,0);
printf("Hz");
Freq_disp(Freq);
Fnc_DDS(Freq);
LCD_cursor(0,1);
printf("STEP");
Step_disp(Step);

while(1){
if(STEP_SW == 0){
Step_change();
}
if(Freq != Freq_old){
Fnc_DDS(Freq);
Freq_disp(Freq);
Freq_old = Freq;
}
}
}