16F18325 Numerically Controlled Oscillator (NCO1)があり、このモジュールを使うと周波数をきめ細かく調整できる発振器を構成することができます。
NCOは、20bit長の主レジスター(NCO1ACC)と20bitの加算器から成り立っており、NCO1_clk 入力のたびごとに、一定の値(NCO1INC)が主レジスターに加算されます。加算される値が小さければ、加算結果でOverFlow発生に時間がかかり、大きければすぐにOverFlowが発生します。OverFlow発生の繰り返し周波数は、以下の式で表されます。
| Freq. Overflow = | NCO1 Clock Freq. x Increment Value |
| 2^20 |
NCOに関連するレジスター一覧を下表に示します。
*注意*
NCO出力は、PPS機能でピンを指定します。
NCO1INCL に書き込みを行うことで、NCO1INC のデータが INCBUF に転送されるため、NCO1INCU 及び NCO1INCH に値を書き込んだ後に NCO1INCL に値を書き込みます。
| レジスタ | bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 |
|---|---|---|---|---|---|---|---|---|
| INTCON | GIE | PEIE | - | - | - | - | - | INTEDG |
| PIE2 | TMR6IE | C2IE | C1IE | NVMIE | SSP2IE | BLC2IE | TMR4IE | NCO1IE |
| PIR2 | TMR6IF | C2IF | C1IF | NVMIF | SSP2IF | BLC2IF | TMR4IF | NCO1IF |
| NCO1CON | N1EN | - | N1OUT | N1POL | - | - | - | N1PFM |
| NCO1CLK | N1PWS <2:0> | - | - | - | N1CKS <1:0> | |||
| NCO1ACCL | NCO1ACC <7:0> | |||||||
| NCO1ACCH | NCO1ACC <15:8> | |||||||
| NCO1ACCU | - | - | - | - | NCO1ACC <19:16> | |||
| NCO1INCL | NCO1INC <7:0> | |||||||
| NCO1INCH | NCO1INC <15:8> | |||||||
| NCO1INCU | - | - | - | - | NCO1INC <19:16> | |||
| RxyPPS | - | - | - | RxyTPPS <4:0> NCO1 は 29 : <11101> | ||||
| レジスタ | BIT | 名 | 説明 | 1 | 0 | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| INTCON | 7 | GIE | 全インタラプトの使用許可 | 許可 | 否 | ||||||||||||||||
| 6 | PEIE | 周辺機能インタラプトの使用許可 | 許可 | 否 | |||||||||||||||||
| PIE2 | 0 | NCO1IE | NCO1 インタラプトを使用許可 | 許可 | 否 | ||||||||||||||||
| PIR2 | 0 | NCO1IF | NCO1 フラグ | 発生 | 未発生 | ||||||||||||||||
| NCO1CON | 7 | N1EN | NCOモジュールのOn/Off | ON | OFF | ||||||||||||||||
| 5 | N1OUT | (Read Only)NCO1 出力 | 1 | 0 | |||||||||||||||||
| 4 | N1POL | NCO1 出力極性 | 不論理 | 正論理 | |||||||||||||||||
| 0 | N1PFM | NCO1 出力モード | Pulse | 反転 | |||||||||||||||||
| NCO1CLK | 7 | N1PWS2 | NCO1 Pulse Mode時の出力Pulse幅選択(x入力Clk)
|
||||||||||||||||||
| 6 | N1PWS1 | ||||||||||||||||||||
| 5 | N1PWS0 | ||||||||||||||||||||
| 1 | N1CKS1 | NCO1 Clock 選択
|
|||||||||||||||||||
| 0 | N1CKS0 | ||||||||||||||||||||
NCOを利用した発振器プログラムを作成しました。VRで 0−488Hzの方形波形をNCOから出力します。
<回路図>
*注意*
XC-8のマクロを使用して、 NOC1INC = 0xAABBCC; とすると、
コンパイラーは、NOC1INCLに0xCC --> NOC1INCHに0xBB --> NOC1INCUに0xAA の順でレジスターに書き込みます。この順では、正しくINCBUFFにデーターを転送することができません。XC-8のマクロを使用せず、プログラム例のようにデータをNCO1INCに書き込む必要があります。
<回路図>
<プログラム>
/*************************************
* File: NCO sample
* System ClockはConfigで内部1MHzに設定
* RA2 (ANA2) の電圧をAD変換、
* 変換された10ビットをNOCINCにセット
* VR値で、0−488HzのNCO出力反転を繰り返す
* PIC16F18346
* Created on Sep 22, 2020, 2:37 PM
**************************************/
#include <xc.h>
#define _XTAL_FREQ 1000000 // delay_ms(x) のための定義
#pragma config FEXTOSC = OFF,RSTOSC = HFINT1 // HFINTOSC (1MHz)
#pragma config CLKOUTEN = OFF,CSWEN = OFF,FCMEN = OFF
#pragma config MCLRE = OFF,PWRTE = OFF,WDTE = OFF,LPBOREN = OFF
#pragma config BOREN = OFF,BORV = LOW,PPS1WAY = OFF,STVREN = ON
#pragma config DEBUG = OFF
#pragma config WRT = OFF,LVP = OFF,CP = OFF,CPD = OFF
void main(void) {
LATC = 0;
TRISC = 0b111110; // RC0を出力に設定
TRISA = 0b111111; // PortAを入力に設定
ANSELA = 0; // 全てのpinをデジタルに設定
ANSELC = 0;
// ADC 設定 ************************************************
ANSA2 = 1; // ANA2(RA2)はアナログ入力に設定
ADACT = 0b00000000; // AD変換はプログラムの命令で開始
ADCON1 = 0b10000000; // 右詰め出力, AD変換クロックFosc/2
// 正基準電圧 VDD
ADCON0 = 0b00001001; // アナログ入力 AN2(RA2),ADC ON
// NCO 設定 ************************************************
NCO1CLK = 0b00000001; // Fosc (1 MHz)がクロック
NCO1CON = 0b10000000; // 正論理、反転モード
RC0PPS = 29; // RC0にNCO出力
while(1){
__delay_ms(5); // ADチャージ時間
GO = 1; // AD変換開始
while(GO); // AD変換終了待ち
NCO1INCU = 0; // NCO1INCに結果セット
NCO1INCH = 0; //
NCO1INCL = ADRES; //
}
}