Last active
August 7, 2020 07:52
-
-
Save vintagechips/6cf5cd760748a988863629baaf53d5d3 to your computer and use it in GitHub Desktop.
SBC6800 SysClock, BaudRate, and Reset Generator 2MHz version by masa
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
SBC6800 cock/boud rate/reset generator | |
Device: PIC16F18313 | |
Compiler: XC8 | |
*/ | |
/* PIC16F18313 | |
* +--x--+ | |
* +5V VDD|1 8|VSS GND | |
* RST(O) RA5|2 7|RA0 RST(I) | |
* CLK2(O) RA4|3 6|RA1 ACIA(O) | |
* NC RA3|4 5|RA2 CLK1(O) | |
* +-----+ | |
*/ | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <xc.h> | |
// コンフィギュレーション1の設定 | |
#pragma config FEXTOSC = OFF // CLKINをRA5で使用する | |
#pragma config RSTOSC = HFINT32 // 初期発振器は内部発振器(HFFRQx2倍)を選択(32MHz) | |
#pragma config CLKOUTEN = OFF // CLKOUTをRA4で使用する | |
#pragma config CSWEN = OFF // NOSCとNDIVへの書き込みは許可しない | |
#pragma config FCMEN = OFF // 外部クロック監視しない | |
// コンフィギュレーション2の設定 | |
#pragma config MCLRE = ON // 外部リセット信号を使用する (RA3とするにはOFF) | |
#pragma config PWRTE = ON // 電源ONから64ms後にプログラムを開始する | |
#pragma config WDTE = OFF // ウオッチドッグタイマー無し | |
#pragma config LPBOREN = OFF // 低消費電力ブラウンアウトリセットは無効 | |
#pragma config BOREN = ON // 電源電圧降下常時監視機能ON | |
#pragma config PPS1WAY = OFF // ロック解除シーケンスを実行すれば何度でもPPSLOCKをセット/クリアできる | |
#pragma config STVREN = ON // スタックがオーバフローやアンダーフローしたらリセットをする(ON) | |
// コンフィギュレーション3の設定 | |
#pragma config WRT = OFF // Flashメモリーを保護しない | |
#pragma config LVP = OFF // 低電圧プログラミング機能使用しない | |
// コンフィギュレーション4の設定 | |
#pragma config CP = OFF // プログラムメモリーを保護しない | |
#pragma config CPD = OFF // EEPROMデータメモリーを保護しない | |
#define _XTAL_FREQ 32000000 // for delay function (32MHz) | |
void main() { | |
char count,high,low,max,dead; | |
high = 1; // リセット解除 | |
low = 0; // リセット実行 | |
max = 10; // チャタリング待ち回数 10ms x max | |
dead = 1; // dead band cycle clock x dead | |
// initialize | |
ANSELA = 0b00000000; // アナログは使用しない(すべてデジタルI/Oに割当てる) | |
TRISA = 0b00001001; // RA0,RA3:IN RA1,2,4,5:OUT | |
PORTA = 0b00000000; // 出力ピンの初期化(全てlowにする) | |
WPUA = 0b00000001; // RA0を内部プルアップする | |
/* CWG による System Clock((1MHz) の生成 | |
* デッドバンド制御でノンオーバーラップクロックを発生させる | |
* Dead band time: 31.25nsec (rising,falling) | |
* 入力クロックの立上がり(rising)で、CWG1A の立ち上がりを遅らせる | |
* 入力クロックの立下がり(falling)で、CWG1B の立ち上がりを遅らせる | |
* 実測値 1.007MHz (METEX P-16) | |
*/ | |
// CWGの設定 | |
RA2PPS = 0b00001000; // CWG1AはRA2ピンを使用する(CLK1) | |
RA4PPS = 0b00001001; // CWG1BはRA4ピンを使用する(CLK2) | |
CWG1CLKCON = 0b00000001; // クロックソースはFosc (32MHz) | |
CWG1DAT = 0b00000111; // PWM5をソースとする (1MHz) | |
CWG1CON1 = 0b00000000; // CWGはA,Bとも正転 | |
CWG1CON0 = 0b10000100; // CWGをONにしてハーフブリッジモードに設定 | |
CWG1CON0 = 0b11000100; // CWG Load Buffers bit をCWG ONの後に設定(重要) | |
CWG1DBR = dead; // 立ち上がりエッジデッドバンド (0 - 63 clock) | |
CWG1DBF = dead; // 立ち下がりエッジデッドバンド (0 - 63 clock) | |
/* クロック設定パラメータ Fosc/4 = 8MHz (125nsec) | |
* CLOCK PR2 PWM5DCH | |
* 1.0 MHz 7 4 | |
* 1.3 MHz 5 3 | |
* 2.0 MHz 3 2 | |
*/ | |
// PWM5の設定 1MHzで50% Duty | |
PWM5CON = 0b10010000; // PWM5機能を使用する(output is active-high) | |
PWM5DCH = 4; // デューティ値は50%で初期化 (上位) (PR2+1)/2 | |
PWM5DCL = 0; // (下位) | |
// TIMER2の設定 Fosc/4 = 8MHz (125ns) | |
T2CON = 0b00000000; // TMR2プリスケーラ値を1倍に設定 | |
TMR2 = 0; // タイマー2カウンターを初期化 | |
PR2 = 7; // PWMの周期を設定 | |
TMR2ON = 1; // TMR2(PWM)スタート | |
/* NCO による MC6850 Baud Rate Clock の生成 (source Clock: 32MHz) | |
* 153.6kHz = (9600 x 16) | |
* INC = (2 x 2^20 x 153.6kHz)/32MHz = 10066 [2 はDuty 50% の時] | |
* NCOINC = 10066 (0x02752) | |
* 実測値 154.6kHz (METEX P-16) | |
*/ | |
RA1PPS = 0b11101; // NCO1はRA1ピンを使用する(ACIA CLOCK) | |
NCO1CLK = 0b00000001; // HFINTOSC:0 (16MHz) , Fosc:1(32MHz) | |
NCO1CON = 0b10000000; // b7:N1EN, b0:N1PFM 0= Duty 50% | |
NCO1INCU = 0; // NCO1INCLへ書き込みがINCBUFにデータ転送するトリガとなる | |
NCO1INCH = 0x27; // Lowを最初にするとINCBUFへの転送が正常に行われない | |
NCO1INCL = 0x52; // | |
// Power on reset | |
LATA5 = 0; | |
__delay_ms(200); | |
LATA5 = 1; | |
// manual reset | |
while(1){ | |
count = 0; | |
/* チャタリング処理 H->L | |
* リセットSWが押されるのを待つ | |
* 10ms 間隔でSWをチェック | |
* 10回連続してlowを検出するとループを抜ける | |
* highを検出するとカウンタをリセットする | |
*/ | |
do{ | |
__delay_ms(10); | |
if (PORTAbits.RA0 == low) | |
count++; | |
else | |
count = 0; | |
}while (count <= max); | |
// CPU reset | |
LATA5 = low; | |
__delay_ms(200); | |
/* チャタリング処理 L->H | |
* 上記に同じ処理 | |
*/ | |
count = 0; | |
do{ | |
__delay_ms(10); | |
if (PORTAbits.RA0 == high) | |
count++; | |
else | |
count = 0; | |
}while (count <= max); | |
// CPU reset 解除 | |
LATA5 = high; | |
} | |
} | |
// end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment