PIC用共通ファイル(pic_init.c)

// --------------------------------------------------
// Global Versatile Controler http://www.gvc-on.net/
// --------------------------------------------------
// --------------------------------------------------
// Revision Memo (Y.M.D Editor/Memo)
// --------------------------------------------------
// 
// 2013.05.08 T.Kabu
// GVC Rev.2としてのもろもろを定義
// 

//---------------------------------------------------
// Include Header
//---------------------------------------------------
// ----------------------------------------
// Standard Header
// ----------------------------------------
#include <xc.h>
#include <plib.h>
#include <htc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// ----------------------------------------
// User Header
// ----------------------------------------
// PIC Parameter define and initialize
#include "pic_init.h"

// GVC Parameter define and initialize
#include "gvc_init.h"

// --------------------------------------------------
// Variable Param
// --------------------------------------------------
float	vdd_volt = 5.00;

// --------------------------------------------------
// Function prototype
// --------------------------------------------------

// --------------------------------------------------
// Sub Routine (pic_init.c)
// --------------------------------------------------
// ------------------------------
// Delay 10m sec
// ------------------------------
void Delay_10ms(unsigned char time)
{
	// _XTAL_FREQという定数を宣言すること。PICそのものの内部クロックOSCCONを変更したら_XTAL_FREQも変更すること
	// timeを1減らしつつ10ms待つ。例:time=100なら100x10ms=1000ms=1s待つ
	while(time--)
	{
		// wait 10ms
		__delay_ms(10);
	}
}

// ----------------------------------------
// Setup 18F26K22
// ----------------------------------------
void init_pic_18F26K22(void)
{
	// ------------------------------
	// PICの動作クロック定義。
	// ------------------------------
	// ちなみに動作クロックを変更したら_XTAL_FREQも変更すること
	// bit7   : 0 = 完全OFF、1 = SCS次第。(SLEEP命令時)
	// bit6-4 : (以下は内部OSC使用時)
	//        : 111 = HFINTOSC    (16 MHz)
	//        : 110 = HFINTOSC/2  (8 MHz)
	//        : 101 = HFINTOSC/4  (4 MHz)
	//        : 100 = HFINTOSC/8  (2 MHz)
	//        : 011 = HFINTOSC/16 (1 MHz)
	// bit3   : OSC起動タイムアウト ステータス
	//        : 1 = デバイスはCONFIG1HレジスタのFOSC<3:0>が定義するクロックによって動作中
	//        : 0 = デバイスは内部OSC(HFINTOSC, MFINTOSC or LFINTOSC)により動作中
	// bit2   : HFINTOSC 周波数安定状態ビット
	//        : 1 = HFINTOSC の周波数が安定している
	//        : 0 = HFINTOSC の周波数が安定していない
	// bit1-0 : 1x = Internal OSC
	//        : 01 = Secondary (SOSC) oscillator
	//        : 00 = Primary clock (determined by FOSC<3:0> in CONFIG1H)
	OSCCON  = 0b01110010; 		// アイドルモード、16MHz(HFINTOSC)、、INTOSC使用
	
	// ------------------------------
	// ポートAのI/Oモードの設定。
	// ------------------------------
	// bit7-6 : Unimplemented: Read as ‘0’
	// bit5   : ANSA5: RA5 Analog Select bit
	//        : 1 = Digital input buffer disabled
	//        : 0 = Digital input buffer enabled
	// bit4   : Unimplemented: Read as ‘0’
	// bit3-0 : ANSA<3:0>: RA<3:0> Analog Select bit
	//        : 1 = Digital input buffer disabled
	//        : 0 = Digital input buffer enabled
	ANSELA = 0b00000000;		// ALL digital
	
	// ------------------------------
	// ポートBのI/Oモードの設定。
	// ------------------------------
	// bit7-6 : Unimplemented: Read as ‘0’
	// bit5-0 : ANSB<5:0> RB<5:0> Analog Select bit
	//        : 1 = Digital input buffer disabled
	//        : 0 = Digital input buffer enabled
	ANSELB = 0b00000000;		// ALL digital
	
	// ------------------------------
	// ポートCのI/Oモードの設定。
	// ------------------------------
	// bit7-2 : ANSC<5:0> RC<5:0> Analog Select bit
	//        : 1 = Digital input buffer disabled
	//        : 0 = Digital input buffer enabled
	// bit1-0 : Unimplemented: Read as ‘0’
	ANSELC = 0b00000000;		// ALL digital
	
	// ------------------------------
	// ポートA設定
	// ------------------------------
	// bit7   : RA7 1 = input, 0 = output
	// bit6   : RA6 1 = input, 0 = output
	// bit5   : RA5 1 = input, 0 = output
	// bit4   : RA4 1 = input, 0 = output
	// bit3   : RA3 1 = input, 0 = output
	// bit2   : RA2 1 = input, 0 = output
	// bit1   : RA1 1 = input, 0 = output
	// bit0   : RA0 1 = input, 0 = output
	TRISA = 0b00000000;
	
	// ------------------------------
	// ポートB設定
	// ------------------------------
	// bit7   : RB7 1 = input, 0 = output
	// bit6   : RB6 1 = input, 0 = output
	// bit5   : RB5 1 = input, 0 = output
	// bit4   : RB4 1 = input, 0 = output
	// bit3   : RB3 1 = input, 0 = output
	// bit2   : RB2 1 = input, 0 = output
	// bit1   : RB1 1 = input, 0 = output
	// bit0   : RB0 1 = input, 0 = output
	TRISB = 0b00000000;
	
	// ------------------------------
	// ポートC設定
	// ------------------------------
	// bit7   : RC7 1 = input, 0 = output
	// bit6   : RC6 1 = input, 0 = output
	// bit5   : RC5 1 = input, 0 = output
	// bit4   : RC4 1 = input, 0 = output
	// bit3   : RC3 1 = input, 0 = output
	// bit2   : RC2 1 = input, 0 = output
	// bit1   : RC1 1 = input, 0 = output
	// bit0   : RC0 1 = input, 0 = output
	TRISC = 0b10011001;			// RC7をシリアルRX用に、RC4,RC3をI2C用に、RC0をリモコン受信用にinputモード
	
	// ------------------------------
	// ポートAラッチデータ設定
	// ------------------------------
	// bit7   : RA7 ポートI/O 出力ラッチレジスタ ビット
	// bit6   : RA6 ポートI/O 出力ラッチレジスタ ビット
	// bit5   : RA5 ポートI/O 出力ラッチレジスタ ビット
	// bit4   : RA4 ポートI/O 出力ラッチレジスタ ビット
	// bit3   : RA3 ポートI/O 出力ラッチレジスタ ビット
	// bit2   : RA2 ポートI/O 出力ラッチレジスタ ビット
	// bit1   : RA1 ポートI/O 出力ラッチレジスタ ビット
	// bit0   : RA0 ポートI/O 出力ラッチレジスタ ビット
	LATA = 0b00000000;
	
	// ------------------------------
	// ポートBラッチデータ設定
	// ------------------------------
	// bit7   : RB7 ポートI/O 出力ラッチレジスタ ビット
	// bit6   : RB6 ポートI/O 出力ラッチレジスタ ビット
	// bit5   : RB5 ポートI/O 出力ラッチレジスタ ビット
	// bit4   : RB4 ポートI/O 出力ラッチレジスタ ビット
	// bit3   : RB3 ポートI/O 出力ラッチレジスタ ビット
	// bit2   : RB2 ポートI/O 出力ラッチレジスタ ビット
	// bit1   : RB1 ポートI/O 出力ラッチレジスタ ビット
	// bit0   : RB0 ポートI/O 出力ラッチレジスタ ビット
	LATB = 0b00000000;
	
	// ------------------------------
	// ポートCラッチデータ設定
	// ------------------------------
	// bit7   : RC7 ポートI/O 出力ラッチレジスタ ビット
	// bit6   : RC6 ポートI/O 出力ラッチレジスタ ビット
	// bit5   : RC5 ポートI/O 出力ラッチレジスタ ビット
	// bit4   : RC4 ポートI/O 出力ラッチレジスタ ビット
	// bit3   : RC3 ポートI/O 出力ラッチレジスタ ビット
	// bit2   : RC2 ポートI/O 出力ラッチレジスタ ビット
	// bit1   : RC1 ポートI/O 出力ラッチレジスタ ビット
	// bit0   : RC0 ポートI/O 出力ラッチレジスタ ビット
	LATC = 0b00000000;
	
	// ------------------------------
	// タイマー0設定
	// ------------------------------
	// bit 7   : TMR0ON: Timer0 On/Off Control bit
	//     1 = Enables Timer0
	//     0 = Stops Timer0
	// bit 6   : T08BIT: Timer0 8-bit/16-bit Control bit
	//     1 = Timer0 is configured as an 8-bit timer/counter
	//     0 = Timer0 is configured as a 16-bit timer/counter
	// bit 5   : T0CS: Timer0 Clock Source Select bit
	//     1 = Transition on T0CKI pin
	//     0 = Internal instruction cycle clock (CLKOUT) タイマーとして使うなら0にすること
	// bit 4   : T0SE: Timer0 Source Edge Select bit
	//     1 = Increment on high-to-low transition on T0CKI pin
	//     0 = Increment on low-to-high transition on T0CKI pin
	// bit 3   : PSA: Timer0 Prescaler Assignment bit
	//     1 = TImer0 prescaler is NOT assigned. Timer0 clock input bypasses prescaler.
	//     0 = Timer0 prescaler is assigned. Timer0 clock input comes from prescaler output.
	// bit 2-0 : T0PS<2:0>: Timer0 Prescaler Select bits
	//     111 = 1:256 prescale value
	//     110 = 1:128 prescale value
	//     101 = 1:64 prescale value
	//     100 = 1:32 prescale value
	//     011 = 1:16 prescale value
	//     010 = 1:8 prescale value
	//     001 = 1:4 prescale value
	//     000 = 1:2 prescale value
	T0CON = 0b00000010;			// Stops Timer0, 16bit, Internal, NONE, Prescaler assign, 1:8
	
	// ------------------------------
	// タイマー1設定
	// ------------------------------
	// bit 7-6 : TMRxCS<1:0>: Timer1/3/5 Clock Source Select bits
	//     11 =Reserved. Do not use.
	//     10 =Timer1/3/5 clock source is pin or oscillator:
	//         If TxSOSCEN = 0:
	//             External clock from TxCKI pin (on the rising edge)
	//         If TxSOSCEN = 1:
	//             Crystal oscillator on SOSCI/SOSCO pins
	//     01 =Timer1/3/5 clock source is system clock (FOSC)
	//     00 =Timer1/3/5 clock source is instruction clock (FOSC/4)
	// bit 5-4 : TxCKPS<1:0>: Timer1/3/5 Input Clock Prescale Select bits
	//     11 = 1:8 Prescale value
	//     10 = 1:4 Prescale value
	//     01 = 1:2 Prescale value
	//     00 = 1:1 Prescale value
	// bit 3   : TxSOSCEN: Secondary Oscillator Enable Control bit
	//     1 = Dedicated Secondary oscillator circuit enabled
	//     0 = Dedicated Secondary oscillator circuit disabled
	// bit 2   : TxSYNC: Timer1/3/5 External Clock Input Synchronization Control bit
	//     TMRxCS<1:0> = 1X
	//         1 = Do not synchronize external clock input
	//         0 = Synchronize external clock input with system clock (FOSC)
	//     TMRxCS<1:0> = 0X
	//         This bit is ignored. Timer1/3/5 uses the internal clock when TMRxCS<1:0> = 1X.
	// bit 1   : TxRD16: 16-Bit Read/Write Mode Enable bit
	//     1 = Enables register read/write of Timer1/3/5 in one 16-bit operation
	//     0 = Enables register read/write of Timer1/3/5 in two 8-bit operation
	// bit 0   : TMRxON: Timer1/3/5 On bit
	//     1 = Enables Timer1/3/5
	//     0 = Stops Timer1/3/5
	//     Clears Timer1/3/5 Gate flip-flop
	T1CON = 0b00110010;			// FOSC/4, 1:8, disabled, ignored, 16bit, Timer1 Stop
	
	// ------------------------------
	// タイマー1ゲート制御レジスタ設定
	// ------------------------------
	// bit 7 TMRxGE: Timer1 Gate Enable bit
	//     If TMRxON = 0:
	//         This bit is ignored
	//     If TMRxON = 1:
	//         1 = Timer1 counting is controlled by the Timer1 gate function
	//         0 = Timer1 counts regardless of Timer1 gate function
	// bit 6 T1GPOL: Timer1 Gate Polarity bit
	//     1 = Timer1 gate is active-high (Timer1 counts when gate is high)
	//     0 = Timer1 gate is active-low (Timer1 counts when gate is low)
	// bit 5 T1GTM: Timer1 Gate Toggle Mode bit
	//     1 = Timer1 Gate Toggle mode is enabled
	//     0 = Timer1 Gate Toggle mode is disabled and toggle flip-flop is cleared
	//     Timer1 gate flip-flop toggles on every rising edge.
	// bit 4 T1GSPM: Timer1 Gate Single-Pulse Mode bit
	//     1 = Timer1 gate Single-Pulse mode is enabled and is controlling Timer1 gate
	//     0 = Timer1 gate Single-Pulse mode is disabled
	// bit 3 T1GGO/DONE: Timer1 Gate Single-Pulse Acquisition Status bit
	//     1 = Timer1 gate single-pulse acquisition is ready, waiting for an edge
	//     0 = Timer1 gate single-pulse acquisition has completed or has not been started
	//     This bit is automatically cleared when T1GSPM is cleared.
	// bit 2 T1GVAL: Timer1 Gate Current State bit
	//     Indicates the current state of the Timer1 gate that could be provided to TMRxH:TMRxL.
	//     Unaffected by Timer1 Gate Enable (TMRxGE).
	// bit 1-0 T1GSS<1:0>: Timer1 Gate Source Select bits
	//     00 = Timer1 Gate pin
	//     01 = Timer0 overflow output
	//     10 = Comparator 1 optionally synchronized output (SYNCC1OUT)
	//     11 = Comparator 2 optionally synchronized output (SYNCC2OUT)(1)
	T1GCON = 0b00000000;		// ignored, active-low, disabled, disabled ...
	
	Delay_10ms(10);	// 100ms待つ
}

// ------------------------------
// Setup EUSART 18F26K22
// ------------------------------
void init_eusart_18F26K22(void)
{
	// EUSART機能の設定を行う
	// ANSELCの設定に注意、初期設定はALL Digitalになっているからいいけど
	TXSTA1 = 0b00100100;		// 送信設定 TXEN=1, SYNC=0, BRGH(高速ボーレート)=1
	RCSTA1 = 0b10010000;		// 受信設定 SPEN=1, CREN=1
	SPBRG1 = 103;				// 9600bpsに設定、FOSCの変更により値が変わるので注意
}

// ----------------------------------------
// Get temperature port voltage
// ----------------------------------------
int get_port_voltage(char port_num)
{
	int  voltage = 0;// 温度データ、上位8ビットにintのlowが、下位8ビットにintのhiが入る
	
	// FVRが安定するまで待つ
	while ( 1 )
	{
		// FVRが安定したなら
		if (VREFCON0bits.FVRST == 1)
		{
			// ループを抜ける
			break;
		}
		// FVRが安定していないなら
		else
		{
			// 何もしない
		}
	}
	
	// AD変換制御レジスタ0設定 A/D CONTROL REGISTER 0
	// bit 7 Unimplemented: Read as ‘0’
	// bit 6-2 CHS<4:0>: Analog Channel Select bits
	//     00000 = AN0
	//     00001 = AN1
	//     00010 = AN2
	//     00011 = AN3
	//     00100 = AN4
	//     01000 = AN8
	//     01001 = AN9
	//     01010 = AN10
	//     01011 = AN11
	//     01100 = AN12
	//     01101 = AN13
	//     01110 = AN14
	//     01111 = AN15
	//     10000 = AN16
	//     10001 = AN17
	//     10010 = AN18
	//     10011 = AN19
	//     11100 = Reserved
	//     11101 = CTMU
	//     11110 = DAC
	//     11111 = FVR BUF2 (1.024V/2.048V/2.096V Volt Fixed Voltage Reference)(2)
	// bit 1 GO/DONE: A/D Conversion Status bit
	//     1 = A/D conversion cycle in progress. Setting this bit starts an A/D conversion cycle.
	//         This bit is automatically cleared by hardware when the A/D conversion has completed.
	//     0 = A/D conversion completed/not in progress
	// bit 0 ADON: ADC Enable bit
	//     1 = ADC is enabled
	//     0 = ADC is disabled and consumes no operating current
//	ADCON0 = 0b00001000;	// AN2 でAD変換有効に設定
	ADCON0 = (port_num << 2);
	
	// 初期設定(ADCON0,ADCON1)の設定が終わってから、AD変換を有効にする
	ADCON0bits.ADON = 1;
	// 電圧測定のため、10us秒待ち
	__delay_us(10);    // wait 10us
	
	// 初期設定(ADCON0,ADCON1)の設定が終わってから、AD変換を有効にする
	ADCON0bits.GODONE = 1;
	
	// ADGOが1の間は待ち
	while(ADCON0bits.GODONE)
	{
		// 電圧測定のため、10us秒待ち
		__delay_us(10);    // wait 10us
	};
	// 電圧データを読み出して温度データに設定
	voltage = ADRESH << 8;
	voltage += ADRESL;
	
	// 温度データを返す
	return voltage;
}

// ----------------------------------------
// Get Vdd Voltage
// ----------------------------------------
float get_vdd(void)
{
	// float をスタックにいっぱい用意しようとすると、オーバーフローになるよ!! "fixup overflow referencing psect..." といわれて
	// リンクできなかったら、変数はstatic宣言でちゃんと固定メモリ領域を使おう 2013.06.10 T.Kabu

	int		an_data = 0;
	float	an_volt = 0;
	
	// PICのポート(AN3)から現在の電圧データを取得する
	an_data = get_port_voltage(3);
	
	// 電圧データを電圧に変換(抵抗で1/2に分圧しているので二倍するのを忘れずに)
	an_volt = (FVR_VOLT / 1024) * an_data * 2;
	
	return an_volt;
}