/* * File: main.c * Author: mabo-2016 * * Created on 2019/01/31, 21:58 */ // PIC16F1827 Configuration Bit Settings // 'C' source line config statements // CONFIG1 #pragma config FOSC = INTOSC // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin) #pragma config WDTE = OFF // Watchdog Timer Enable (WDT disabled) #pragma config PWRTE = ON // Power-up Timer Enable (PWRT enabled) #pragma config MCLRE = OFF // MCLR Pin Function Select (MCLR/VPP pin function is MCLR) #pragma config CP = OFF // Flash Program Memory Code Protection (Program memory code protection is disabled) #pragma config CPD = OFF // Data Memory Code Protection (Data memory code protection is disabled) #pragma config BOREN = ON // Brown-out Reset Enable (Brown-out Reset enabled) #pragma config CLKOUTEN = OFF // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin) #pragma config IESO = OFF // Internal/External Switchover (Internal/External Switchover mode is enabled) #pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled) // CONFIG2 #pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off) #pragma config PLLEN = OFF // PLL Enable (4x PLL enabled) #pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset) #pragma config BORV = HI // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.) #pragma config LVP = OFF // Low-Voltage Programming Enable (Low-voltage programming enabled) // #pragma config statements should precede project file includes. // Use project enums instead of #define for ON and OFF. #include #include #include #include #include // delay用 #define _XTAL_FREQ 8000000 // delay用(クロック8MHzで動作時) //unsigned int color[3]; //LCDライブラリー // 異なるピンを使う場合はここを変更する /* #define LCD_RS RB1 #define LCD_EN RB3 #define LCD_D4 RB4 #define LCD_D5 RB5 #define LCD_D6 RB6 #define LCD_D7 RB7 #define LCD_STROBE() ((LCD_EN=1),(LCD_EN=0))*/ #define LCD_RS RB4 #define LCD_EN RB5 #define LCD_D4 RB6 #define LCD_D5 RB7 #define LCD_D6 RA6 #define LCD_D7 RA7 #define LCD_STROBE() ((LCD_EN=1),(LCD_EN=0)) //キー判定 #define SWTCH RA1//プルアップで接続 出力 #define ON 0 #define OFF 1 volatile unsigned short SWTCH_FLAG; int swCount = 0; int b_count=0; int g_count=0; int b_on=0; int g_on=0; //光センサーライブラリー /* #define DOUT RA7 //?ピン //?ピンVdd //?ピンGnd #define RANGE RA3 //? #define CK RA2 //? #define GATE RA1 //? */ #define DOUT RB0 //1ピンDout //2ピンVdd //3ピンGnd #define RANGE RB1 //4ピンRang #define CK RB2 //5ピンCK #define GATE RB3 //6ピンGate //外部スイッチ //#define RANGE_SW RA6//High→高感度 Low→低感度 void Wait(unsigned int num) { int i ; // numで指定した回数だけ繰り返す for (i=0 ; i> 4 ) & 0x01 ) ; LCD_D5 = ( ( c >> 5 ) & 0x01 ) ; LCD_D6 = ( ( c >> 6 ) & 0x01 ) ; LCD_D7 = ( ( c >> 7 ) & 0x01 ) ; LCD_STROBE() ; // 送信データのバイト列下位4ビットを処理 LCD_D4 =( ( c ) & 0x01 ) ; LCD_D5 =( ( c >> 1 ) & 0x01 ) ; LCD_D6 =( ( c >> 2 ) & 0x01 ) ; LCD_D7 =( ( c >> 3 ) & 0x01 ) ; LCD_STROBE() ; } // LCDにコマンドを発行する処理 void command(unsigned char c) { LCD_RS = 0 ; LCD_D4 = ( ( c ) & 0x01 ) ; LCD_D5 = ( ( c >> 1 ) & 0x01 ) ; LCD_D6 = ( ( c >> 2 ) & 0x01 ) ; LCD_D7 = ( ( c >> 3 ) & 0x01 ) ; LCD_STROBE() ; } /******************************************************************************* * lcd_clear - LCDモジュールの画面を消す処理 * *******************************************************************************/ void lcd_clear(void) { LCD_RS = 0 ; lcd_write(0x01) ; // Clear Display : 画面全体に20Hのスペースで表示、カーソルはcol=0,row=0に移動 __delay_ms(2) ; // LCDが処理(1.53ms)するのを待ちます } /******************************************************************************* * lcd_setCursor - LCDモジュール画面内のカーソル位置を移動する処理 * * col : 横(列)方向のカーソル位置(0-15) * * row : 縦(行)方向のカーソル位置(0-1) * ********************************************************************************/ void lcd_setCursor(int col, int row) { int row_offsets[] = { 0x00, 0x40 } ; LCD_RS = 0 ; lcd_write(0x80 | (col + row_offsets[row])) ; // Set DDRAM Adddress : 00H-0FH,40H-4FH } /******************************************************************************* * lcd_putc - LCDにデータを1バイト出力する処理 * * c : 出力する文字データ * *******************************************************************************/ void lcd_putc(char c) { LCD_RS = 1 ; // RSの制御信号線をセットします lcd_write( c ) ; // LCDにデータの送信 } /******************************************************************************* * lcd_puts - LCDに文字列データを出力する処理(文字列をNULL(0x00)まで繰返し出力)* * s : 出力する文字列のデータ * *******************************************************************************/ void lcd_puts(const char * ss) { LCD_RS = 1 ; // RSの制御信号線をセットします while(*ss) lcd_write(*ss++) ; } /******************************************************************************* * lcd_init - LCDの初期化処理 * *******************************************************************************/ void lcd_init() { LCD_RS = 0 ; LCD_EN = 0 ; __delay_ms(15) ; // 電源ON後15msまで待ってから初期化 // LCDの立上げ時のチェックデータ(イニシャライズ処理用)を設定 command(0x03) ; __delay_ms(5) ; command(0x02) ; // LCDにコマンドを発行します lcd_write(0x28) ; // function set : データ線は4本・表示は2行・フォントは5x8ドット lcd_write(0x0c) ; // display control: 画面表示はON・カーソル表示はOFF・カーソル点滅はOFF lcd_clear() ; // Clear Display : 画面をクリアし、カーソル位置はcol=0,row=0 lcd_write(0x06) ; // entry mode set : 文字を表示した次にカーソルを移動するを指示 } /******************************************************************************* * GetColor-カラーの読み取り *******************************************************************************/ void GetColor(short sensitivity, int addTime,int *pColor) { static unsigned int RED, GREEN, BLUE, tmp; static unsigned short cnt; //データ積算処理 GATE = 0; CK = 0; RANGE = sensitivity; GATE = 1;//積算開始 for (; addTime > 0; addTime--) { __delay_ms(1); } GATE = 0; __delay_ms(4); //赤色データの取り込み RED = 0; for (cnt = 0; cnt < 12; cnt++) { CK = 1;//ワンパルスの生成 CK = 0; tmp = DOUT << cnt; RED |= tmp; } *pColor = RED; //color[0]=RED pColor++;//color[1] __delay_ms(3); //緑色データの取り込み GREEN = 0; for (cnt = 0; cnt < 12; cnt++) { CK = 1; CK = 0; tmp = DOUT << cnt; GREEN |= tmp; } *pColor = GREEN; //color[1]=GREEN; pColor++; //color[2] __delay_ms(3); //青色データの取り込み BLUE = 0; for (cnt = 0; cnt < 12; cnt++) { CK = 1; CK = 0; tmp = DOUT << cnt; BLUE |= tmp; } *pColor = BLUE; //color[2]=BLUE; } /******************************************************************************* * moji_migizuzme-右詰表示 i=表示桁 *s1=表示文字 ******************************************************************************/ void moji_migizuzme(int i,char *s1){ static unsigned short cnt1; for(cnt1=0;cnt10 & b_on==1){//ブルーになったら,1回スイッチONで一秒待つ b_count=b_count-10; } if(b_count==0){ b_on=0; } if(g_count>0 & g_on==1){//グリーンになったら,1回スイッチONで一秒待つ g_count=g_count-10; } if(g_count==0){ g_on=0; } if(RA2== 0){//タクトスイッチ swCount++; ///RA0ポートをチェックして0ならカウント } else{ swCount = 0; //RA0が0でないならswCount } if(swCount == 8){//RA0が押されたと判断 SWTCH_FLAG=ON; } if(swCount >= 10){ //スイッチが押されつづけられた場合はなにもしない swCount = 9; } } /******************************************************************************* *main.c ******************************************************************************/ void main(void) { static unsigned char buff[12]; static unsigned int color[3]; static unsigned int sekisan; static unsigned int tmp; static unsigned int henkan; SWTCH_FLAG=OFF; henkan=OFF; OSCCON = 0b01110010; // 内部クロックは8MHzとする ADCON0=0b00000000; //bit0=0→AD変換不可 bit6-2=00000→RA0でAD変換 ADCON1bits.ADCS0 = 1; //AD変換クロック値設定 ADCON1bits.ADCS1 = 0; //001→8Mhzで1.0μs ADCON1bits.ADCS2 = 0; // ADCON1bits.ADFM = 1; // AD変換結果は右詰めで格納 ADCON1bits.ADNREF = 0; // 基準電圧はVddとVss ADCON1bits.ADPREF = 0; // ANSELA = 0b00000001; // RA0(AN0)はアナログ ANSELB = 0b00000000; // RBはデジタル PORTA = 0b00000000; // PORTAを初期化 PORTB = 0b00000000; // PORTBを初期化 TRISA = 0b00000101; // 1で入力 0で出力 RA1-RA7全て出力に設定(RA5は入力専用) RA7→Dout RA6→High,Low TRISB = 0b00000001; // RB0-入力 RB1-RB7 全部出力 //T1CON レジスタ(Timer1 Control Resister) TMR1CS1 = 0; //Timer1 clock source: Fosc/4 //Timer1 Clock Source Select bits TMR1CS0 = 0; //TMR1CS<1:0> = 00 → Fosc/4 // 01 → Fosc T1CKPS1 = 1; //プリスケーラ 1/8 //Prescale Select bits T1CKPS0 = 1; //T1CKPS<1:0> = 11 → 1/8 //10→1/4 01→1/2 00→1/1 T1OSCEN = 0; //LP Oscillator Enble Control bit nT1SYNC = 1; //Timer1 External Clock Input Synchronization Control bit TMR1ON = 1; //Enable Timer1 //Timer1 On bit //T1GCON レジスタ(Timer1 Gate Control Resister) // ゲート機能なし TMR1GE = 0; //Timer1 Gate Enable bit T1GPOL = 0; //Timer1 Gate Polarity bit T1GTM = 0; //Timer1 Gate Toggle Mode bit T1GSPM = 0; //Timer1 Gate Single Pulse Mode bit T1GGO = 0; //Timer1 Gate Single-Pulse Acquisition Status bit T1GVAL = 0; //Timer1 Gate current State bit T1GSS1 = 0; //Timer1 Gate Source Select bits T1GSS0 = 0; //Clock: 20MHz/4 → 5MHz 0.2μsec /* 8MHz: 8/4 2Mhz 0.5*μsec/ // 10msec毎の割り込みを行う1 //プリスケーラ 1/8 //Prescale Select bits // (65536 -N)*0.2*8 = 10000 /*(65536-N)*0.5*8=10000*/ // N = 65536 - 10000 /8/0.2 = 59286 /*N=65536-10000/8/0.5=63036*/ // 59268/256 = 231 /*63036/256=246*/ // 59286 -256*231 = 150 /*63036-256*246=60*/ // 59286 ÷ 256 = 231 余り150 /*63036÷256=246 あまり60*/ TMR1H = 246; // TMR1L = 60; TMR1IE = 1; // タイマ1割り込み許可 PEIE = 1; // 周辺割り込み許可許可 GIE = 1; // グローバル割り込み許可 /* LCDの初期化処理を行う */ lcd_init() ; /*sekisan時間をEEPROMから読み込む if(eep_read(0)==0){//デフォルトは10にする sekisan=10; } else{ sekisan=eep_read(0); tmp=sekisan; }*/ RA1=1; RA4=1; RA3=1; sekisan=(eep_read(0) | (eep_read(1)<<8)); tmp=sekisan; while (1) { //カラーデータの取得 GetColor(1, sekisan,(int *)color); //赤色データ表示 itoa((char *)buff,color[0],10) ; lcd_setCursor(0, 0); lcd_putc(0x52);//'R' lcd_putc(0x3a);//':' lcd_setCursor(2, 0); moji_migizuzme(4,(char *)buff);//右詰表示 //緑データ表示 itoa((char *)buff,color[1],10) ; lcd_setCursor(8, 0); lcd_putc(0x47);//'G' lcd_putc(0x3a);//':' lcd_setCursor(10, 0); moji_migizuzme(4,(char *)buff);//右詰表示 if((color[1]>200) & (color[1]>color[2])){ if(g_on==0 & g_count==0){ RA1=0;//フォットカプラー O __delay_ms(1); RA4=0; __delay_ms(100); RA1=1;//フォトプラ- OFF __delay_ms(1); RA4=1;; g_on=1; g_count=1000; } } //青データ表示 itoa((char *)buff,color[2],10) ; lcd_setCursor(0, 1); lcd_putc(0x42);//'B' lcd_putc(0x3a);//':' lcd_setCursor(2, 1); moji_migizuzme(4,(char *)buff);//右詰表示 if((color[2]>200) & (color[2]>color[1])){ if(b_on==0 & b_count==0){ RA1=0;//フォットカプラー ON __delay_ms(1); RA3=0; __delay_ms(100); RA1=1;//フォトプラ- OFF __delay_ms(1); RA3=1; b_on=1; b_count=1000; } } //積算タイム表示 //tmp=adconv(); itoa((char *)buff,tmp,10); lcd_setCursor(8, 1); lcd_putc(0x53);//'S' lcd_putc(0x3a);//':' lcd_setCursor(10, 1); moji_migizuzme(4,(char *)buff);//右詰表示 lcd_putc(0x6d);//'m' lcd_putc(0x73);//'s' /* RB0=0; __delay_ms(1000); RB0=1; __delay_ms(1000);*/ if(SWTCH_FLAG==ON){//スイッチが押されたら積算タイムの変更 tmp=adconv(); henkan=ON; RB0=0; //RA3=0; } if(henkan==ON & RA2==1){ eep_write(0,(tmp>>0) & 0xFF);//下位1バイトを取り出し書き込む eep_write(1,(tmp>>8) & 0xFF);//上位1バイトを取り出し書き込む __delay_ms(20); sekisan=tmp; RB0=1; henkan=OFF; SWTCH_FLAG=OFF; //asm("RESET");//リセットする } } }