nobcha23の日記

PICマイコンやArduinoを使う電子回路遊びを紹介します

PIC12F683 電圧電流表示器 Cソース

プログラムです。TC4040Bを経由してLCDを制御する回路
と関数プログラムは実績がありますのでGPIOの番号を見
直しただけで一発動作。


次に電圧変換部でバグリました。原因は掛け算割り算の
順番間違えたのと、データ型の取り方が悪かったと言う
ところです。表示関数が安定に動くので、デバッグ時に
ADC値そのままとか、計算後とかの値をLCDに表示して原
因推定できました。
ややっと自分なりの8ピンPICデバッグ環境が確立してき
た気がします。

/* 
 *   V0.1 02/11/2011
 *   PIC16F683を使う、電源モニター用の電圧値、電流値表示回路です。
 *   GP0(AN0)で入力電圧をセンス計ります。、
 *   GP1(AN1)は電流(0.1オームに流れる電流を電圧で見る)を計ります。
 *
 *   表示はTC4040B経由でSC1602互換LCD表示パネルを接続します。 
 *   SC1602とはバイト接続としてデータはGP5からTC4040Bへ、  
 *   パルス数で与え、ENABLEはGP2を使います。  
 *
 *	GP0 is connected to PS INPUT VOLTAGE AS AN0
 *	GP1 is connected to current sencing as AN3
 *	GP4 is connected to the LCD EN bit (enable)
 *      GP5 is connected to TC4040B clk input
 *
 *	TC4040B Q1-Q4 are connected to the LCD data bits 0-3 
 *	TC4040B Q5 is connected to the LCD RS input (register select)
 *
 *	SC1602 pin connection
 *		#1	Vdd=5V
 *		#2	Vss=GND
 *		#3	LCD contrust center of 5k VOL
 *		#4	RS	TC4040B #3 Q5
 *		#5	R/W	GND
 *		#6	E	675 #7	GP2
 *		#11	DB4	TC4040B	#9 Q1
 *		#12	DB5	TC4040B	#7 Q2
 *		#13	DB6	TC4040B	#6 Q3
 *		#14	DB7	TC4040B	#5 Q4
 *
 *   OSC internal RC 4MHz
 * 
 *   Development Circumstance
 *   MPLAB IDE V8.56   HiTECH C V9.71a
 *
 *
 *  ////////////////////////////////////////////////// */

#define pic_clk 4000000

#define MHz 000000
#define _XTAL_FREQ 4MHz

#include <htc.h>
#include "delay.h" 
#include <pic.h>
#include "lcd.h"

__CONFIG(BORDIS & UNPROTECT & PWRTEN & WDTDIS & MCLREN & INTIO );

/* /////////////////////////////////////////////////  */

void init_a2d(void){
   	ANS0=1;  	    	// AN0 set
	ANS1=1;			// AN1 set
	ANS3=1;			// AN3 set
   	ADCS0=1;		// Select Fosc/8
	ADCS1=0;
	ADCS2=0;
	ADFM=1;  	    	// Select right justify result AD port config0
	ADON=1;
	PEIE=0;			// Inhibit Interrupt
}

short long read_a2d(unsigned char ch){
	ADON=1;			// ADC start
	if(ch){			// ch==1 voltage
	   	CHS0=0; 	// Select AN0 A2D module
		CHS1=0;
		VCFG=0;		// refer Vdd
	}
	else{
	   	CHS0=1; 	// Select AN1 A2D module
		CHS1=0;
		VCFG=0;		// refer Vdd
	}		
	__delay_us(20);		// Wait 20uS
	GODONE=1;
        while (GODONE) ;

        return((short long)(( ADRESH *256 + ADRESL ) );  //
				// Return with 10 bits
}


void main(void){
	unsigned char  i, disp_data, zero_sup;
	short long decimal;
	short long volt_data,amp_data;


	GPIO=0x00;		// GPIO initialize
	TRISIO=0x0f;		// GP0,GP1,GP3,GP4 input
 	ANSEL=0x1b;       	// Fosc/8 GP0,1,3 is assigned as ADC port

 	init_a2d();        	// ADC initialize

	lcd_init();
	lcd_goto(0);		// select first line

	lcd_putch(0xc3); lcd_putch(0xde); lcd_putch(0xdd); lcd_putch(0xb1); lcd_putch(0xc2);  // デンアツ
	lcd_puts("   ");
	lcd_putch(0xc3); lcd_putch(0xde); lcd_putch(0xdd); lcd_putch(0xd8); lcd_putch(0xad); lcd_putch(0xb3);  // デンリュウ

while(1){

	lcd_goto(0x42);					// select second line

	i=0;
	decimal = 1000;

	volt_data=( 244 * read_a2d(1) )/ 100; 
							// Calculate adc to volt 
							// 5/1024=4.88mv/bit  real V is 5 times
							// adc_data * 24.4mV  = (adc_data *244) / 100mV
        while(i<2){
		disp_data = (char)(( volt_data / decimal )%10) ;	// Get digit data
		if ( disp_data == 0 & i==0 ){		// zero suppress
			lcd_puts(" ");			// insert space
		}
		else {					// other wise display decimal ascii
			lcd_putch(disp_data | 0x30 );	// Display digit
		}
		decimal = decimal / 10; 		// 10->1  
 		i=i++;      				// next column
       	}	
	lcd_puts(".");
	disp_data =( char) (( volt_data/10  )%10) ;	// Get digit data
	lcd_putch( disp_data | 0x30 );			// Display digit
	lcd_puts("V  ");

	amp_data=(( 488*read_a2d(0) ))/10; 
							// Calculate adc to mili ampere


    	decimal=10000;                       		// 4 digit  xxxx mA                
	i=0;
	zero_sup=0;
    	while(i<4){
		disp_data = (char)(( amp_data / decimal )%10) ;	// Get digit data
			if ( disp_data == 0 & i!=3 & zero_sup ==0 ){	// zero suppress condition
				lcd_puts(" "); 			// saoce inserted
	}
	else {						// not zero
		lcd_putch(disp_data | 0x30 );		// Display digit
		zero_sup=1;				// zero sup flag off
	}
	decimal = decimal / 10; 			// 10->1  
 	i=i++;      					// next digit
       	}

	lcd_puts("mA"); 
	for (i=0;i<10;i++){				// Measure and display every 0.5 second.
		__delay_ms(50);
		}
	}
}


PIC12F629,PIC12F675を使用してHI-TECHのCでプログラム書く時、この本をいつも横に置いて参考にしております。PIC12F683でもOSCALなど一部異なる部分に注意するだけで使えます。