JH7UBCブログ

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

PIC16F18326 MCC NCOテスト その2

2024-01-28 19:06:01 | MPLAB X MCC
 引き続き、PIC16F18326のNOCのテストをします。

 今回は、任意の周波数を発生させ、NOC出力(RC3に設定しました)にスピーカーを接続して音として聞くことにより、様々な効果音やメロディーを奏でてみることにします。

 回路図です。ICSPでプログラムを書き込みます。PICは、けっこう力持ちでこのままだとかなり大きな音が出ます。音が大きすぎるときには直列に100Ω程度の抵抗を入れると聞きやすくなります。


 まず、救急車のピーポー音を出してみます。
 MCCの設定は、前の記事と同じです。
 systemモジュールです。


 NCO1モジュールです。


 ピーポー音は、ピーの音(960Hz)0.65秒、ポーの音(770Hz)0.62秒の繰り返しです。予めNCOモジュールで、周波数に対するレジスタの設定値を調べておきます。
 NCOの出力周波数を決定するのは、NCO1INCU,NCO1INCH,NCO1INCLレジスタ(各8bit)の値で、NCO1INCU = 0x0で、周波数ごとの各レジスタの値は
周波数  NCO1INCH    NCO1INCL
960Hz    0x1    0xF7
770Hz    0x1    0x94
です。
プログラムです。NCO1INCUは設定していませんが、デフォルトで0x0です。
-----------------------------------------
#include "mcc_generated_files/mcc.h"

void main(void)
{
     // initialize the device
     SYSTEM_Initialize();

     NCO1CONbits.N1EN = 1;//NCO1スタート
     NCO1INCH = 0x1;
     while (1)
    {
         NCO1INCL = 0xF7;//ピーの音 960Hz
         __delay_ms(650);
         NCO1INCL = 0x94;//ポーの音 770Hz
         __delay_ms(650);
   }
}
-----------------------------------------
 レジスタへの設定は、NCO1INCH,NCO1INCLの順に行います。

 はい、ピーポーピーポーと聞こえました。

 では、次にドレミソラシドの音階を出してみましょう。各音階(周波数)とレジスタの設定値は次のとおりです。(NCOINCUは0x0です)
 音階(周波数) NCO1INCH NCO1INCL
 ド(262Hz)   0x00    0x89
 レ(294Hz)   0x00    0x9A
 ミ(330Hz)   0x00    0xAC
ファ(349Hz)   0x00    0xB7
 ソ(392Hz)   0x00    0xCE
 ラ(440Hz)   0x00    0xE7
 シ(494Hz)   0x01    0x03
 ド(523Hz)   0x01    0x12
 
ドレミファソラシドを繰り返すプログラムです。
--------------------------------------------------------------------
/*
 * PIC16F18326 MCC NCO test
 * 2024.1.28
 * JH7UBC Keiji Hata
*/
#include "mcc_generated_files/mcc.h"

void main(void)
{
     // initialize the device
     SYSTEM_Initialize();

     NCO1CONbits.N1EN = 0;//NCO1ストップ
     NCO1INCH = 0x1;
     while (1)
    {
         NCO1CONbits.N1EN = 1;//NCO1スタート
         NCO1INCH = 0x0;
         NCO1INCL = 0x89;//ドの音 262Hz
         __delay_ms(1000);
         NCO1INCL = 0x9A;//レの音 294Hz
         __delay_ms(1000);
         NCO1INCL = 0xAC;//ミの音 330Hz
         __delay_ms(1000);
         NCO1INCL = 0xB7;//ファの音 349Hz
         __delay_ms(1000);
         NCO1INCL = 0xCE;//ソの音 392Hz
         __delay_ms(1000);
          NCO1INCL = 0xE7;//ラの音 440Hz
         __delay_ms(1000);
         NCO1INCH = 0x1;//シの音 494Hz
         NCO1INCL = 0x03;
         __delay_ms(1000);
          NCO1INCL = 0x12;//ドの音 523Hz
         __delay_ms(1000);
         NCO1CONbits.N1EN = 0;//NCO1ストップ
         __delay_ms(1000);
    }
}
--------------------------------------------------------------------
 この音階を利用すれば、メロディーを奏でることができますね。


PIC16F18326 MCC NCOテスト その1

2024-01-27 18:49:43 | MPLAB X MCC
 PIC16F18326のNOCのテストをします。
 環境は、MPLAB X(v6.15) XC8(v2.45) MCC(v5.3.7)です。 

 NCO(Numerically Controlled Oscillator 数値制御発振器)とは、数値で周期を設定できるパルス発生器で、2つのモードがあります。
 下の図のように、デューティ比が一定で周波数を変化させられる固定デューティモード(FDC)とパルス幅一定で周波数を変化させられるパルス周波数モード(PFM)モードです。


 それぞれのモードの信号を発生させてみることにします。
 NCOの詳しい説明は省略します。詳細は、こちらのサイトをご覧ください。

 MPLAB Xでprojectを作成し、MCCを立ち上げます。
 まず、systemモジュールでクロック周波数を設定します。
 今回はデフォルトの状態で、1MHzとしました。


 NCOモジュールを導入し、出力先を設定します。出力は、RA3を除くすべてのI/Oポートに設定できます。今回は、RC3に設定しました。

 NCOモジュールで、モードと周波数を設定します。
 まず、FDCモードで周波数を1KHzに設定します。(デフォルトの状態です)


 この状態でGenerateします。
 main.cは次のように生成されます。(プログラム上にはNCOについては何も書かれていません)
-----------------------------------------------------
#include "mcc_generated_files/mcc.h"

void main(void)
{
     // initialize the device
     SYSTEM_Initialize();

     while (1)
    {
    }
}
-----------------------------------------------------
 buildして書き込んでみます。
 RC3に自作の周波数カウンタを接続して周波数を測定してみました。(この周波数カウンタの製作記事はこちら
  1002Hzでした。(プログラム上の計算値は999Hzです)誤差5%以内とけっこう優秀です。



 波形を見てみましょう。


 確かにデューティ比50%の波形です。

 では、次にPFMモードで1KHzの信号を発生させてみます。
 NCOモジュールで、モードをPFMに、パルス幅を64クロックとしてみました。


 出力波形を見てみます。



 周波数1KHzでパルス幅が一定の波形が観測できました。

 では、NCOの周波数を変えるのにはどうしたらよいでしょうか。
 簡単に行うには、NCOモジュールのNCO Output Frequencyに周波数を記入すればよく、必要な計算とレジスタへのセッティングは自動的に行われます。

 NCOモジュールでRegistersの値を見ると
 NCO1INCH = 0x2
 NCO1INCL = 0xC
 NCO1INCU = 0x0
 と計算されています。


 この値を検証してみます。


 今回、NCOのクロックには、HFINTOSC=4MHzを使っています。
 確かに、NCOの計算のとおりになりました。

 この計算式を利用すれば、任意の周波数を発生させることができます。
 次回はこれを利用して音楽の演奏をやってみます。

PIC16F18326 MCC DACテスト

2024-01-26 07:31:36 | MPLAB X MCC
 PIC16F18326のDACのテストをします。
 環境は、MPLAB X(v6.15) XC8(v2.45) MCC(v5.3.7)です。 

 回路図です。RA0がDACの出力ですので、ICSPが使えません。


 MPLAB Xでprojectを作り、MCCを立ち上げます。
 まず、systemモジュールでクロックを設定します。4MHzとしました。


 DACモジュールを導入します。デフォルトのままで特に設定はしません。
 Positive Reference はVDD、Negative ReferenceはVSSです。



 Pinモジュールです。DAC1OUTはRA0にだけ設定できます。



 DAC1OUTのDirectionがinputとなっているのですが、これでAnalog出力になります。

 Generateして、main.cを編集します。
 鋸歯状波を出力してみます。
 プログラムです。
--------------------------------------------------------
/*
 * PIC16F18326 MCC DAC test
 * 2024.1.24
 * JH7UBC Keiji Hata
*/

#include "mcc_generated_files/mcc.h"

void main(void)
{
     // initialize the device
     SYSTEM_Initialize();
     while (1)
    {
         for(uint8_t i = 0;i<32;i++){
              DAC1_SetOutput(i);
         }
    }
}
--------------------------------------------------------

 DAC1_SetOutput(uint8_t data);関数でDACの出力が決まります。
 PIC16F18326のDACは、5bitですので、dataは0から31の間の値を入れます。Positive Referenceは、VDDのほかFVR(Fixed Voltage Reference)や外部からの電圧も使えます。

 DAC1OUTの出力波形です。ギザギザのある鋸歯状波が出力されました。



 DAC1OUTの出力は、電流が取れませんので、実際に利用する場合は、オペアンプなどのバッファが必要です。


PIC16F18326 MCC IOC割り込みテスト

2024-01-24 07:43:49 | MPLAB X MCC
 PIC16F18326のIOC(ピン状態変化)割り込みのテストをします。

 テストする回路です。
 RC3の電圧変化を検知し、RC2に接続したLEDを点滅させてみます。
 RC3は内部でウィークプルアップ(WPU)しますので、プルアップ抵抗はつけていません。
 

 MPLAB X でprojectを作成し、MCCを立ち上げて各種設定をします。

 systemモジュールです。クロックは4MHzにしました。

 RC3をinputに、RC2をoutputに設定します。

 Interruptモジュールです。
 IOC割り込みを使いますので、IOCI Enabledにチェックを入れます。


 
 pinモジュールを設定します。
 RC3をウィークプルアップするため、WPUにチェックを入れます。
 割り込みのタイミングをIOC欄で立下り(negative)に設定しました。


 設定が終わったら、Generateし、main.cにプログラムを記入します。

プログラムです。ピンに状態変化が起きると割り込みが発生し、
 IOCCF3_SetInterruptHandler(LED_toggle);で指定されたルーチンを実行します。今回は、RC3の電圧の立下りで割り込みが発生し、LED_toggle()が実行されます。
----------------------------------------------------
/*
 * PIC16F18326 MCC IOC Interrupt test
 * 2024.01.23
 * JH7UBC Keiji Hata
*/

#include "mcc_generated_files/mcc.h"
#define LED LATC2

void LED_toggle(){
     __delay_ms(10);//チャタリング待ち
     if(RC3 == 0){
         LED = !LED;
    }
}

void main(void)
{
     // initialize the device
     SYSTEM_Initialize();

     // Enable the Global Interrupts
     INTERRUPT_GlobalInterruptEnable();

     // Enable the Peripheral Interrupts
     INTERRUPT_PeripheralInterruptEnable();
     IOCCF3_SetInterruptHandler(LED_toggle);
     LED = 0;

     while (1)
    {
    }
}
----------------------------------------------------

 機械的なスイッチには、接点が閉じたり開いたりするときにチャタリングという現象が生じます。RC3のタクトスイッチを押したときの電圧波形です。
 スイッチをチョンと押したときで、接点が閉じている時間は約100ms(0.1s)です。この波形ではチャタリングは見られませんが、押し方によっては、立下りと立ち上がりにギザギザのチャタリングが発生します。
 ということで、、チャタリング待ちの時間は10msとしました。


 ブレッドボードです。SWを押すたびにLEDが点灯したり消灯したりします。チャタリングの影響は、ほとんどありません。



PIC16F18326 MCC Timer割り込み & オープンドレイン テスト

2024-01-22 21:53:16 | MPLAB X MCC
 PIC16F18326のタイマー割り込みとオープンドレイン出力のテストをします。
 Timer0の割り込みを使ってLED点滅(Lチカ)をやってみます。PIC16F18326では、すべてのGPIOに対してオープンドレイン出力を設定することができます。そこで、RC3をオープンドレイン出力に設定して、LEDに接続します。

 回路図です。ICSPでテストします。


 MPLAB Xでprojectを作成し、MCCを立ち上げ、必要な設定をします。
 まず、systemモジュールの設定です。クロックは、4MHzとしました。


 Timer0もジュールを導入し、Timer0の周期を設定します。
 Clock SourceをFOSC/4、Timer modeを16bitにして、prescalerを1:8しました。Timer Periodを500msとしました。タイマー割り込みを使いますので、Enable Timer interruptにチェックを入れます。



 Interruptモジュールです。TMR0にチェックが入っています。



 LEDを接続するポートをオープンドレインにするため、pinモジュールでODにチェックを入れます。


プログラムです。
-------------------------------------------------------------------
/*
 * PIC16F18326 MCC Timer Interrupt and Open Drain test
 * 2024.01.21
 * JH7UBC Keiji Hata
*/

#include "mcc_generated_files/mcc.h"

#define LED LATC3

void ISR(void){
     LED = !LED;
}

void main(void)
{
     // initialize the device
     SYSTEM_Initialize();

     // Enable the Global Interrupts
     INTERRUPT_GlobalInterruptEnable();

     // Enable the Peripheral Interrupts
     INTERRUPT_PeripheralInterruptEnable();
     TMR0_SetInterruptHandler(ISR);
     LED = 0;
     while (1)
    {

    }
}
-------------------------------------------------------------------
 割り込み時に処理する関数は、TMR0_SetInterruptHandler();に記入します。

 ブレッドボードです。LEDが0.5秒ごとに点滅しました。